diff --git a/.editorconfig b/.editorconfig
index 9bc03af..9528f12 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,6 +1,7 @@
-[*.*]
+root = true
+[*]
 tab_width = 2
-indent_size = 1
+indent_size = 2
 indent_style = tab
 charset = utf-8
 max_line_length = 160
\ No newline at end of file
diff --git a/components/layouts/footer.vue b/components/layouts/footer.vue
index 88d4590..83be34e 100644
--- a/components/layouts/footer.vue
+++ b/components/layouts/footer.vue
@@ -2,25 +2,17 @@
 <template>
 	<div>
 		<p>
-			© Rockfic.com, since 2004. Rockfic.com is in no way associated with any
-			band listed on this website. Rockfic.com is entertainment. All stories
-			contained on this site are fictional, which means that while the
-			characters may be loosely based on the public personas of real people, the
-			stories themselves are completely ungrounded from reality and are in no
-			way meant to reflect the private lives, actual practices, or activities of
-			any persons named. Rockfic.com will remove a work of fiction if an
-			individual named within requests its removal.<br />
+			© Rockfic.com, since 2004. Rockfic.com is in no way associated with any band listed on this website. Rockfic.com is entertainment. All stories contained
+			on this site are fictional, which means that while the characters may be loosely based on the public personas of real people, the stories themselves are
+			completely ungrounded from reality and are in no way meant to reflect the private lives, actual practices, or activities of any persons named. Rockfic.com
+			will remove a work of fiction if an individual named within requests its removal.<br />
 			For site problems and/or bugs, contact
-			<a style="font-weight: bold" href="mailto:bugs@rockfic.com"
-				>bugs@rockfic.com</a
-			>.<br />
+			<a style="font-weight: bold" href="mailto:bugs@rockfic.com">bugs@rockfic.com</a>.<br />
 			For everything else, contact
 			<a href="mailto:admin@rockfic.com">admin@rockfic.com</a>.
 		</p>
 		<b>Copyright Notice</b><br />
-		All content on this site is copyright of its respective author. You may not,
-		except with our express written permission, distribute or commercially
-		exploit the content. Nor may you transmit it or store it in any other
-		website or other form of electronic retrieval system.
+		All content on this site is copyright of its respective author. You may not, except with our express written permission, distribute or commercially exploit
+		the content. Nor may you transmit it or store it in any other website or other form of electronic retrieval system.
 	</div>
 </template>
diff --git a/components/profile/adminPanel.vue b/components/profile/adminPanel.vue
index d6aca42..fe9345b 100644
--- a/components/profile/adminPanel.vue
+++ b/components/profile/adminPanel.vue
@@ -30,11 +30,7 @@
 				promote: !short,
 			},
 		});
-		messageApi.success(
-			`User ${props.user?.username} is now ${
-				short ? "an admin" : "a regular user"
-			}.`,
-		);
+		messageApi.success(`User ${props.user?.username} is now ${short ? "an admin" : "a regular user"}.`);
 		setTimeout(() => {
 			showDemote.value = false;
 		}, 1000);
@@ -44,26 +40,15 @@
 <template>
 	<a-space :size="10" direction="vertical">
 		<div>
-			<a-descriptions
-				:colon="false"
-				:label-style="{ fontWeight: 'bold' }"
-				:column="1"
-			>
+			<a-descriptions :colon="false" :label-style="{ fontWeight: 'bold' }" :column="1">
 				<a-descriptions-item label="IP addresses">
 					<a-list :data-source="user?.ipLog">
 						<template #renderItem="{ item }">
 							{{ item.ip }}<br />
-							<a-typography-title :level="5"
-								>Other users with this IP:</a-typography-title
-							>
+							<a-typography-title :level="5">Other users with this IP:</a-typography-title>
 							<div v-if="commonIps != null">
-								<i v-if="!commonIps[item.ip]?.length">
-									No other users share this IP.
-								</i>
-								<a-list
-									v-else
-									:data-source="!!commonIps ? commonIps[item.ip] : []"
-								>
+								<i v-if="!commonIps[item.ip]?.length"> No other users share this IP. </i>
+								<a-list v-else :data-source="!!commonIps ? commonIps[item.ip] : []">
 									<template #renderItem="{ item: otherItem }">
 										<nuxt-link :to="`/user/${otherItem._id}`">
 											{{ otherItem.username }}
@@ -83,16 +68,10 @@
 					<b>{{ user?.profile.isAdmin ? "an admin" : "a regular user" }}</b
 					>.
 				</span>
-				<a-button
-					danger
-					v-if="!user?.profile.isAdmin"
-					@click="() => (showDemote = true)"
-				>
+				<a-button danger v-if="!user?.profile.isAdmin" @click="() => (showDemote = true)">
 					<b>Promote to Admin</b>
 				</a-button>
-				<a-button v-else @click="() => (showDemote = true)">
-					Demote to regular user
-				</a-button>
+				<a-button v-else @click="() => (showDemote = true)"> Demote to regular user </a-button>
 			</a-space>
 			<a-divider />
 			<div style="display: flex">
@@ -110,8 +89,7 @@
 		v-model:open="showBanUnban"
 		:title="`${user?.banned ? 'Unban' : 'Ban'} ${user?.username}`"
 	>
-		Are you sure you want to {{ `${user?.banned ? "unban" : "ban"}` }}
-		{{ user?.username }}?
+		Are you sure you want to {{ `${user?.banned ? "unban" : "ban"}` }} {{ user?.username }}?
 	</a-modal>
 	<a-modal
 		cancel-text="No"
@@ -119,20 +97,13 @@
 		@ok="prodem"
 		@cancel="() => (showDemote = false)"
 		v-model:open="showDemote"
-		:title="`${short ? 'Demoting' : 'Promoting'} ${user?.username} ${
-			!short ? 'to an administrator' : 'to a regular user'
-		}`"
+		:title="`${short ? 'Demoting' : 'Promoting'} ${user?.username} ${!short ? 'to an administrator' : 'to a regular user'}`"
 	>
 		<div v-if="!short">
-			Are you <b><u>absolutely sure</u></b> you want to
-			<b>promote this user to an admin</b>?
+			Are you <b><u>absolutely sure</u></b> you want to <b>promote this user to an admin</b>?
 			<br />
-			<a-typography-title :level="5">
-				This is a VERY dangerous permission to grant.
-			</a-typography-title>
-		</div>
-		<div v-else>
-			Are you sure you want to remove this user as an administrator?
+			<a-typography-title :level="5"> This is a VERY dangerous permission to grant. </a-typography-title>
 		</div>
+		<div v-else>Are you sure you want to remove this user as an administrator?</div>
 	</a-modal>
 </template>
diff --git a/components/reviews/forChapter.vue b/components/reviews/forChapter.vue
index b7f40be..389b109 100644
--- a/components/reviews/forChapter.vue
+++ b/components/reviews/forChapter.vue
@@ -4,9 +4,7 @@
 	import { SingleChapterResult } from "@client/types/slightlyDifferentStory";
 	const props = defineProps<{ endpoint: string }>();
 	const story = inject<SingleChapterResult>("story");
-	const { data: reviews } = (await useApiFetch<IReview[]>(
-		`${props.endpoint}/reviews`,
-	)) as unknown as {
+	const { data: reviews } = (await useApiFetch<IReview[]>(`${props.endpoint}/reviews`)) as unknown as {
 		data: IReview[];
 	};
 </script>
diff --git a/components/story/atoms/characters.vue b/components/story/atoms/characters.vue
index 95e1fb0..84ec96b 100644
--- a/components/story/atoms/characters.vue
+++ b/components/story/atoms/characters.vue
@@ -12,20 +12,12 @@
 		});
 		return unflattened.flat(Infinity).map((a) => ({ value: a, label: a }));
 	});
-	const charField = useField<string[]>(
-		fname + "characters",
-		cs.fields.characters as unknown as MaybeRef<RuleExpression<string[]>>,
-	);
+	const charField = useField<string[]>(fname + "characters", cs.fields.characters as unknown as MaybeRef<RuleExpression<string[]>>);
 	const { value, errorMessage, name: bandName, setValue } = charField;
 	// setValue([]);
 </script>
 <template>
-	<a-form-item
-		:help="errorMessage"
-		label="Characters"
-		:name="bandName as string"
-		:validate-status="!!errorMessage ? 'error' : undefined"
-	>
+	<a-form-item :help="errorMessage" label="Characters" :name="bandName as string" :validate-status="!!errorMessage ? 'error' : undefined">
 		<a-select mode="multiple" :options="opts" v-model:value="value">
 			<template #removeIcon>
 				<i class="far fa-circle-x" />
diff --git a/components/story/atoms/genre.vue b/components/story/atoms/genre.vue
index f18f689..c66487b 100644
--- a/components/story/atoms/genre.vue
+++ b/components/story/atoms/genre.vue
@@ -6,22 +6,11 @@
 		value: a,
 		label: a,
 	}));
-	const { value, errorMessage, name, setValue } = useField<string[]>(
-		fname + "genre",
-	);
+	const { value, errorMessage, name, setValue } = useField<string[]>(fname + "genre");
 </script>
 <template>
-	<a-form-item
-		:help="errorMessage"
-		label="Genre(s)"
-		:validate-status="!!errorMessage ? 'error' : undefined"
-	>
-		<a-select
-			:allow-clear="true"
-			:options="opts"
-			v-model:value="value"
-			mode="multiple"
-		>
+	<a-form-item :help="errorMessage" label="Genre(s)" :validate-status="!!errorMessage ? 'error' : undefined">
+		<a-select :allow-clear="true" :options="opts" v-model:value="value" mode="multiple">
 			<template #removeIcon>
 				<i class="far fa-circle-x" />
 			</template>
diff --git a/components/story/atoms/pairings.vue b/components/story/atoms/pairings.vue
index 72e1c68..03095b9 100644
--- a/components/story/atoms/pairings.vue
+++ b/components/story/atoms/pairings.vue
@@ -12,26 +12,14 @@
 		});
 		return uf.flat(Infinity).map((a) => ({ value: a, label: a }));
 	});
-	const { fields, push, remove, replace, update } = useFieldArray<string[]>(
-		fname + "relationships",
-	);
+	const { fields, push, remove, replace, update } = useFieldArray<string[]>(fname + "relationships");
 	// replace([]);
 </script>
 <template>
 	<a-form-item label="Pairings">
-		<a-row
-			:gutter="5"
-			:wrap="true"
-			v-for="(field, idx) in fields"
-			:key="field.key"
-		>
+		<a-row :gutter="5" :wrap="true" v-for="(field, idx) in fields" :key="field.key">
 			<Field :name="fname + 'relationships' + `[${idx}]`">
-				<a-select
-					mode="multiple"
-					:options="opts"
-					v-model:value="field.value as string[]"
-					@change="(val) => update(idx, val as string[])"
-				>
+				<a-select mode="multiple" :options="opts" v-model:value="field.value as string[]" @change="(val) => update(idx, val as string[])">
 					<template #removeIcon>
 						<i class="far fa-circle-x" />
 					</template>
diff --git a/components/story/atoms/test1.vue b/components/story/atoms/test1.vue
index 587f15d..0283e07 100644
--- a/components/story/atoms/test1.vue
+++ b/components/story/atoms/test1.vue
@@ -3,9 +3,7 @@
 		mode="multiple"
 		style="width: 100%"
 		placeholder="Please select"
-		:options="
-			[...Array(25)].map((_, i) => ({ value: (i + 10).toString(36) + (i + 1) }))
-		"
+		:options="[...Array(25)].map((_, i) => ({ value: (i + 10).toString(36) + (i + 1) }))"
 		@change="handleChange"
 	></a-select>
 </template>
diff --git a/components/story/view/storyInfo.vue b/components/story/view/storyInfo.vue
index 402a3c0..f7ac37b 100644
--- a/components/story/view/storyInfo.vue
+++ b/components/story/view/storyInfo.vue
@@ -8,77 +8,45 @@
 </script>
 <template>
 	<a-card style="width: 45%; float: left; margin-right: 1.2em" v-if="!!story">
-		<a-descriptions
-			:label-style="{ fontWeight: 'bold' }"
-			:colon="false"
-			:column="1"
-		>
+		<a-descriptions :label-style="{ fontWeight: 'bold' }" :colon="false" :column="1">
 			<a-descriptions-item label="Author">
-				<nuxt-link :to="`/user/${story?.author._id}`">{{
-					story?.author.username
-				}}</nuxt-link>
+				<nuxt-link :to="`/user/${story?.author._id}`">{{ story?.author.username }}</nuxt-link>
 			</a-descriptions-item>
 			<a-descriptions-item label="Bands">
-				<div
-					class="wrapLong"
-					v-for="(item, index) in story?.currentChapter.bands"
-				>
+				<div class="wrapLong" v-for="(item, index) in story?.currentChapter.bands">
 					<span>
 						<nuxt-link :to="`/band/${item._id}`">
 							{{ item.name }}
 						</nuxt-link>
-						{{
-							(index < story!.currentChapter?.bands.length - 1 && ",&nbsp;") ||
-							""
-						}}
+						{{ (index < story!.currentChapter?.bands.length - 1 && ",&nbsp;") || "" }}
 					</span>
 				</div>
 			</a-descriptions-item>
 			<a-descriptions-item label="Genre(s)">
-				<div
-					class="wrapLong"
-					v-for="(item, index) in story?.currentChapter.genre"
-				>
+				<div class="wrapLong" v-for="(item, index) in story?.currentChapter.genre">
 					<span>
 						{{ item }}
-						{{
-							(index < story!.currentChapter?.genre.length - 1 && ",&nbsp;") ||
-							""
-						}}
+						{{ (index < story!.currentChapter?.genre.length - 1 && ",&nbsp;") || "" }}
 					</span>
 				</div>
 			</a-descriptions-item>
 			<a-descriptions-item label="Relationship(s)">
-				<div
-					class="wrapLong"
-					v-for="(item, index) in story?.currentChapter.relationships"
-				>
+				<div class="wrapLong" v-for="(item, index) in story?.currentChapter.relationships">
 					<span>
 						{{ item.join("/") }}
-						{{
-							(index < story!.currentChapter?.relationships.length - 1 &&
-								",&nbsp;") ||
-							""
-						}}
+						{{ (index < story!.currentChapter?.relationships.length - 1 && ",&nbsp;") || "" }}
 					</span>
 				</div>
 			</a-descriptions-item>
 			<a-descriptions-item label="Character(s)">
 				<div class="wrapLong">
 					<span v-for="(item, index) in story?.currentChapter.characters">
-						{{ item
-						}}{{
-							(index < story!.currentChapter?.characters.length - 1 &&
-								",&nbsp;") ||
-							""
-						}}
+						{{ item }}{{ (index < story!.currentChapter?.characters.length - 1 && ",&nbsp;") || "" }}
 					</span>
 				</div>
 			</a-descriptions-item>
 			<a-descriptions-item label="Rating">
-				{{
-					story?.currentChapter.nsfw ? "Adult" : "Suitable for most audiences"
-				}}
+				{{ story?.currentChapter.nsfw ? "Adult" : "Suitable for most audiences" }}
 			</a-descriptions-item>
 			<a-descriptions-item label="Summary">
 				<div v-html="story?.currentChapter.summary"></div>
@@ -86,19 +54,9 @@
 			<a-descriptions-item label="Date posted">
 				<a-tooltip>
 					<template #title>
-						{{
-							format(
-								Date.parse(story?.currentChapter.posted as unknown as string),
-								"EEEE, LLL dd yyyy @ hh:mm:ss.SSS aa",
-							)
-						}}
+						{{ format(Date.parse(story?.currentChapter.posted as unknown as string), "EEEE, LLL dd yyyy @ hh:mm:ss.SSS aa") }}
 					</template>
-					{{
-						format(
-							Date.parse(story?.currentChapter.posted as unknown as string),
-							"yyyy-MM-dd",
-						)
-					}}
+					{{ format(Date.parse(story?.currentChapter.posted as unknown as string), "yyyy-MM-dd") }}
 				</a-tooltip>
 			</a-descriptions-item>
 		</a-descriptions>
@@ -106,12 +64,7 @@
 		<div class="stats">
 			<span>
 				<span class="staticon">
-					<icon
-						:istyle="!dark ? 'solid' : 'regular'"
-						icolor="#ff2883"
-						:size="12"
-						name="heart"
-					/>
+					<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#ff2883" :size="12" name="heart" />
 				</span>
 				<span>
 					{{ story.favs }}
@@ -119,12 +72,7 @@
 			</span>
 			<span>
 				<span class="staticon">
-					<icon
-						:istyle="!dark ? 'solid' : 'regular'"
-						icolor="#1787d7"
-						:size="12"
-						name="book-open"
-					/>
+					<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#1787d7" :size="12" name="book-open" />
 				</span>
 				<span>
 					{{ story.views }}
@@ -132,12 +80,7 @@
 			</span>
 			<span>
 				<span class="staticon">
-					<icon
-						:istyle="!dark ? 'solid' : 'regular'"
-						icolor="#51e07c"
-						:size="12"
-						name="thumbs-up"
-					/>
+					<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#51e07c" :size="12" name="thumbs-up" />
 				</span>
 				<span>
 					{{ story.recs }}
@@ -145,12 +88,7 @@
 			</span>
 			<span>
 				<span class="staticon">
-					<icon
-						:istyle="!dark ? 'solid' : 'regular'"
-						icolor="#c2d420"
-						:size="12"
-						name="download"
-					/>
+					<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#c2d420" :size="12" name="download" />
 				</span>
 				<span>
 					{{ story.downloads }}
diff --git a/components/tos.vue b/components/tos.vue
index 1f5462b..643fa1c 100644
--- a/components/tos.vue
+++ b/components/tos.vue
@@ -2,95 +2,59 @@
 <template>
 	<div>
 		<h3>Age Policy</h3>
-		You must be 18 years of age or older to have an account. If you are found to
-		be underage, your account will be suspended without notice.
+		You must be 18 years of age or older to have an account. If you are found to be underage, your account will be suspended without notice.
 		<h3>General</h3>
 		<ol>
 			<li>Rockfic.com is not affiliated with any band listed on the site;</li>
 			<li>
-				All stories are fictional and for entertainment purposes only, which
-				means that while the characters may be loosely based on the public
-				personas of real people, the stories are completely ungrounded from
-				reality and are in no way meant to reflect the private lives, actual
-				practices, or activities of any persons named;
+				All stories are fictional and for entertainment purposes only, which means that while the characters may be loosely based on the public personas of real
+				people, the stories are completely ungrounded from reality and are in no way meant to reflect the private lives, actual practices, or activities of any
+				persons named;
 			</li>
+			<li>Rockfic.com will remove a work of fiction if an individual named within requests its removal;</li>
+			<li>We do not sell, trade or otherwise disclose personal user information to any third party;</li>
 			<li>
-				Rockfic.com will remove a work of fiction if an individual named within
-				requests its removal;
-			</li>
-			<li>
-				We do not sell, trade or otherwise disclose personal user information to
-				any third party;
-			</li>
-			<li>
-				We reserve the right to access and disclose individually identifiable
-				information to comply with any legal obligation or governmental request
-				to enforce or apply our Terms of Use, or to ensure the constitutional
-				rights and safety of Rockfic.com users.
+				We reserve the right to access and disclose individually identifiable information to comply with any legal obligation or governmental request to enforce
+				or apply our Terms of Use, or to ensure the constitutional rights and safety of Rockfic.com users.
 			</li>
 		</ol>
 
 		<h3>Content</h3>
 		<ol>
-			<li>
-				Rockfic.com does not own any of the stories published on the site, nor
-				are its administrators legally accountable for its content;
-			</li>
+			<li>Rockfic.com does not own any of the stories published on the site, nor are its administrators legally accountable for its content;</li>
 			<li>Authors are the sole copyright owners of their stories;</li>
+			<li>Authors are responsible for managing any content they create; this includes managing the privacy settings facilitated by the site;</li>
 			<li>
-				Authors are responsible for managing any content they create; this
-				includes managing the privacy settings facilitated by the site;
+				Rockfic.com reserves the right to remove content, including anything we consider offensive, inappropriate or defamatory, at our discretion; any content
+				we decide to remove will be done in accordance with our Submission Rules;
+			</li>
+			<li>Rockfic.com reserves the right to edit content, in line with our Submission Rules.</li>
+			<li>
+				If you believe that you own the copyright in any of the content on Rockfic.com, and you have not been recognized as the copyright owner, please contact
+				us and your case will be investigated;
 			</li>
 			<li>
-				Rockfic.com reserves the right to remove content, including anything we
-				consider offensive, inappropriate or defamatory, at our discretion; any
-				content we decide to remove will be done in accordance with our
-				Submission Rules;
-			</li>
-			<li>
-				Rockfic.com reserves the right to edit content, in line with our
-				Submission Rules.
-			</li>
-			<li>
-				If you believe that you own the copyright in any of the content on
-				Rockfic.com, and you have not been recognized as the copyright owner,
-				please contact us and your case will be investigated;
-			</li>
-			<li>
-				While we investigate reports of inappropriate content or copyright
-				issues, we may temporarily remove the content in question; if we agree
-				that you are the copyright owner or that the content is inappropriate,
-				we will remove the relevant content permanently.
+				While we investigate reports of inappropriate content or copyright issues, we may temporarily remove the content in question; if we agree that you are
+				the copyright owner or that the content is inappropriate, we will remove the relevant content permanently.
 			</li>
 		</ol>
 
 		<h3>Conduct</h3>
 		<ol>
-			<li>
-				Rockfic.com operates a strict anti-bullying and anti-harassment policy;
-				if you have an issue to report, contact us;
-			</li>
+			<li>Rockfic.com operates a strict anti-bullying and anti-harassment policy; if you have an issue to report, contact us;</li>
 			<li>
 				Rockfic.com will permanently ban users who:
 				<ol style="list-style-type: lower-alpha">
-					<li>
-						break the law, for example by saying something libellous, or by
-						posting something which results in a criminal offence;
-					</li>
+					<li>break the law, for example by saying something libellous, or by posting something which results in a criminal offence;</li>
 					<li>share the personal details of users without their permission;</li>
 					<li>impersonate another user;</li>
-					<li>
-						collect or use any information from Rockfic.com with the intent to
-						harm, discredit or harass any other user; or
-					</li>
+					<li>collect or use any information from Rockfic.com with the intent to harm, discredit or harass any other user; or</li>
 					<li>do anything which impacts the performance of the site.</li>
 				</ol>
 			</li>
 		</ol>
 		<h3>Copyright</h3>
-		All content on this site is copyright of its respective author. You may not,
-		except with our express written permission, distribute or commercially
-		exploit the content. Nor may you transmit it or store it in any other
-		website or other form of electronic retrieval system.
+		All content on this site is copyright of its respective author. You may not, except with our express written permission, distribute or commercially exploit
+		the content. Nor may you transmit it or store it in any other website or other form of electronic retrieval system.
 	</div>
 </template>
diff --git a/lib/client/editorConfig.ts b/lib/client/editorConfig.ts
index c83ddfe..7af8f88 100644
--- a/lib/client/editorConfig.ts
+++ b/lib/client/editorConfig.ts
@@ -60,8 +60,7 @@ export const fancy = {
 			items: "h1 h2 h3 h4 h5 h6",
 		},
 	},
-	toolbar:
-		"undo redo | paste | bold italic underline | hr image link | forecolor styles | heading alignment | code",
+	toolbar: "undo redo | paste | bold italic underline | hr image link | forecolor styles | heading alignment | code",
 	contextmenu: "bold italic underline | hr | link | image | paste",
 	external_plugins: {
 		mentions: "/plugins/mentions/plugin.min.js",
@@ -122,11 +121,7 @@ export const story = {
 		`advlist autolink lists link image charmap preview anchor searchreplace visualblocks code fullscreen insertdatetime media table advcode help wordcount save`.split(
 			" ",
 		),
-	toolbar:
-		"undo redo | paste |" +
-		"bold italic underline | hr | alignleft aligncenter " +
-		"alignright alignjustify | " +
-		"| code",
+	toolbar: "undo redo | paste |" + "bold italic underline | hr | alignleft aligncenter " + "alignright alignjustify | " + "| code",
 	contextmenu: "bold italic underline | hr | paste | link",
 };
 export const bare = {
diff --git a/lib/client/listActions.ts b/lib/client/listActions.ts
index 80add2b..8c9bee0 100644
--- a/lib/client/listActions.ts
+++ b/lib/client/listActions.ts
@@ -3,12 +3,7 @@ import { FavPayload, HidePayload, SubPayload } from "./types/form/favSub";
 
 const base = `/user/me`;
 
-export const favourites = (
-	values: (any & { _id: number })[],
-	id: number,
-	remove: boolean,
-	type: "story" | "author",
-) => {
+export const favourites = (values: (any & { _id: number })[], id: number, remove: boolean, type: "story" | "author") => {
 	values?.splice(
 		values!.findIndex((a) => a._id == id),
 		1,
@@ -26,12 +21,7 @@ export const favourites = (
 	});
 };
 
-export const subscriptions = (
-	values: (any & { _id: number })[],
-	id: number,
-	action: "hide" | "subscribe" | "unsubscribe",
-	type: "bands" | "authors",
-) => {
+export const subscriptions = (values: (any & { _id: number })[], id: number, action: "hide" | "subscribe" | "unsubscribe", type: "bands" | "authors") => {
 	values?.splice(
 		values!.findIndex((a) => a._id == id),
 		1,
diff --git a/lib/client/middleware.ts b/lib/client/middleware.ts
index d27ed97..5cc6dae 100644
--- a/lib/client/middleware.ts
+++ b/lib/client/middleware.ts
@@ -3,15 +3,16 @@ import { IChapter } from "@models/stories/chapter";
 import { IStory } from "@models/stories";
 import { messages } from "@server/constants";
 import { IUser } from "@models/user";
+import { IDraft } from "@models/stories/draft";
+
+const show404 = () => showError({ statusCode: 404, message: messages[404] });
 
 export const storyMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
 	const { getSession } = useAuth();
 	await getSession({ force: true });
 	const { data } = useAuth();
 	console.log("to n from", to, from, data);
-	const { data: story, error } = await useApiFetch<SingleChapterResult>(
-		to.path,
-	);
+	const { data: story, error } = await useApiFetch<SingleChapterResult>(to.path);
 	if (error.value) {
 		return showError(error.value);
 	} else if (!story.value) {
@@ -23,24 +24,27 @@ export const storyMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
 	}
 });
 
-export const storyEditMiddleware = defineNuxtRouteMiddleware(
-	async (to, from) => {
-		const { data: curU } = useAuth();
-		const rtr = useRoute();
-		const { data: storyInfo } = await useApiFetch<
-			({ chapters: (IChapter & { text: string })[] } & IStory) | null
-		>(`/story/${rtr.params.id}/full`);
-		if (!storyInfo.value) {
-			return showError({ statusCode: 404, message: messages[404] });
-		}
-		if (
-			curU.value?.user?._id !== (storyInfo.value?.author as IUser)._id &&
-			curU.value?.user?._id !== (storyInfo.value?.coAuthor as IUser)?._id
-		) {
-			return showError({
-				statusCode: 403,
-				message: messages[403],
-			});
-		}
-	},
-);
+export const storyEditMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
+	const { data: curU } = useAuth();
+	const rtr = useRoute();
+	const { data: storyInfo } = await useApiFetch<({ chapters: (IChapter & { text: string })[] } & IStory) | null>(`/story/${rtr.params.id}/full`);
+	if (!storyInfo.value) show404();
+	if (curU.value?.user?._id !== (storyInfo.value?.author as IUser)._id && curU.value?.user?._id !== (storyInfo.value?.coAuthor as IUser)?._id) {
+		return showError({
+			statusCode: 403,
+			message: messages[403],
+		});
+	}
+});
+export const draftEditMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
+	const { data: curU } = useAuth();
+	const rtr = useRoute();
+	const { data: storyInfo } = await useApiFetch<IDraft | null>(`/draft/${rtr.params.id}`);
+	if (!storyInfo.value) show404();
+	if (curU.value?.user?._id !== (storyInfo.value?.author as IUser)._id && curU.value?.user?._id !== (storyInfo.value?.coAuthor as IUser)?._id) {
+		return showError({
+			statusCode: 403,
+			message: messages[403],
+		});
+	}
+});
diff --git a/lib/client/types/form/draftInfo.ts b/lib/client/types/form/draftInfo.ts
new file mode 100644
index 0000000..eb38219
--- /dev/null
+++ b/lib/client/types/form/draftInfo.ts
@@ -0,0 +1,3 @@
+export interface DraftInfo {
+	id: number;
+}
diff --git a/lib/client/types/form/story.ts b/lib/client/types/form/story.ts
index fa45acd..80a7ecb 100644
--- a/lib/client/types/form/story.ts
+++ b/lib/client/types/form/story.ts
@@ -1,4 +1,6 @@
-import { V4Options, v4 } from "uuid";
+import { v4 } from "uuid";
+import { IChapter } from "@models/stories/chapter";
+import { IBand } from "@models/band";
 
 export interface FormChapter {
 	id?: number;
@@ -51,3 +53,21 @@ export const defaultStory: FormStory = {
 	challenge: null,
 	completed: false,
 };
+
+export function toFormChapter(chap: IChapter & { text: string }): FormChapter {
+	return {
+		chapterTitle: chap.title,
+		index: 1,
+		summary: chap.summary,
+		notes: chap.notes,
+		genre: chap.genre,
+		bands: (chap.bands as IBand[]).map((a) => a._id),
+		characters: chap.characters,
+		relationships: chap.relationships,
+		nsfw: chap.nsfw,
+		loggedInOnly: chap.loggedInOnly,
+		hidden: chap.hidden,
+		content: chap.text,
+		uuidKey: v4(),
+	};
+}
diff --git a/lib/client/utils.ts b/lib/client/utils.ts
index 8c71bf4..80b55f3 100644
--- a/lib/client/utils.ts
+++ b/lib/client/utils.ts
@@ -27,11 +27,7 @@ export const autoSave = async (values: any) => {
 	}
 };
 
-export const autoEdit = (
-	values: any,
-	endpoint: string,
-	method: "put" | "post",
-) => {
+export const autoEdit = (values: any, endpoint: string, method: "put" | "post") => {
 	const [messageApi, contextHolder] = message.useMessage();
 	useApiFetch<{ success: boolean; data: IStory }>(endpoint, {
 		method,
diff --git a/lib/server/constants.ts b/lib/server/constants.ts
index f5a22e1..27bcb67 100644
--- a/lib/server/constants.ts
+++ b/lib/server/constants.ts
@@ -1,10 +1,8 @@
 import turndown from "turndown";
 export const ContentFilenameRegex = /\.(doc|docx|md|markdown)$/i;
 
-export const emailRegex: RegExp =
-	/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
-export const usernameRegex: (uname: string) => RegExp = (uname: string) =>
-	new RegExp("^" + uname.trim().replace(/\*/g, "\\*") + "$", "i");
+export const emailRegex: RegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
+export const usernameRegex: (uname: string) => RegExp = (uname: string) => new RegExp("^" + uname.trim().replace(/\*/g, "\\*") + "$", "i");
 export const mammothTemplate = (doc, defaults, content) => {
 	return content.replace(/\n|\r\n|\r/gm, "");
 };
@@ -90,17 +88,7 @@ export const sanitizeConf = {
 		img: ["src"],
 	},
 	// Lots of these won't come up by default because we don't allow them
-	selfClosing: [
-		"img",
-		"br",
-		"hr",
-		"area",
-		"base",
-		"basefont",
-		"input",
-		"link",
-		"meta",
-	],
+	selfClosing: ["img", "br", "hr", "area", "base", "basefont", "input", "link", "meta"],
 	// URL schemes we permit
 	allowedSchemes: ["http", "https", "ftp", "mailto", "tel"],
 	allowedSchemesAppliedToAttributes: ["href", "src", "cite"],
diff --git a/lib/server/dbHelpers/draftHydrator.ts b/lib/server/dbHelpers/draftHydrator.ts
new file mode 100644
index 0000000..017b9b6
--- /dev/null
+++ b/lib/server/dbHelpers/draftHydrator.ts
@@ -0,0 +1,20 @@
+import { Document } from "mongoose";
+import { IDraft } from "@models/stories/draft";
+import { EventHandlerRequest, H3Event } from "h3";
+import { IChapter } from "@models/stories/chapter";
+import getDraftBucket from "@server/storyHelpers/getDraftBucket";
+import { norm, stringifyStream } from "@functions";
+
+export interface HydratedDraft extends Omit<IDraft, "chapters"> {
+	chapters: (IChapter & { text: string })[];
+}
+
+export default async function (draft: Document<number, {}, IDraft> & IDraft, event: H3Event<EventHandlerRequest>): Promise<HydratedDraft> {
+	const finObj = draft.toObject() as HydratedDraft;
+	const bucket = getDraftBucket();
+	for (let chap of finObj.chapters) {
+		let dstream = bucket.openDownloadStreamByName(`/drafts/${chap.id}.txt`);
+		chap.text = norm(await stringifyStream(dstream));
+	}
+	return finObj;
+}
diff --git a/lib/server/dbHelpers/storyQuerier.ts b/lib/server/dbHelpers/storyQuerier.ts
index 023d19c..9c4504b 100644
--- a/lib/server/dbHelpers/storyQuerier.ts
+++ b/lib/server/dbHelpers/storyQuerier.ts
@@ -20,7 +20,6 @@ export default async function (ev: H3Event<EventHandlerRequest>) {
 		})
 		.populate({ path: "challenge", model: Challenge })
 		.exec();
-	if (story == null)
-		throw createError({ statusCode: 404, message: "Not found." });
+	if (story == null) throw createError({ statusCode: 404, message: "Not found." });
 	return story;
 }
diff --git a/lib/server/ficmas.ts b/lib/server/ficmas.ts
index f59446b..6e74fb7 100644
--- a/lib/server/ficmas.ts
+++ b/lib/server/ficmas.ts
@@ -1,8 +1,4 @@
 export const submissionsOpen = () =>
-	new Date() < new Date(Date.parse(`Dec 24 ${new Date().getFullYear()}`)) &&
-	Date.now() > Date.parse(`Nov 1 ${new Date().getFullYear()}`);
-export const ficsHidden = (d: number) =>
-	d < Date.parse(`Dec 25 ${new Date().getFullYear()}`);
-export const status = () =>
-	Date.now() > Date.parse(`Oct 1 ${new Date().getFullYear()}`) &&
-	Date.now() < Date.parse(`Nov 30 ${new Date().getFullYear()}`);
+	new Date() < new Date(Date.parse(`Dec 24 ${new Date().getFullYear()}`)) && Date.now() > Date.parse(`Nov 1 ${new Date().getFullYear()}`);
+export const ficsHidden = (d: number) => d < Date.parse(`Dec 25 ${new Date().getFullYear()}`);
+export const status = () => Date.now() > Date.parse(`Oct 1 ${new Date().getFullYear()}`) && Date.now() < Date.parse(`Nov 30 ${new Date().getFullYear()}`);
diff --git a/lib/server/middlewareButNotReally/storyPrivileges.ts b/lib/server/middlewareButNotReally/storyPrivileges.ts
index bc5aafc..78eca5c 100644
--- a/lib/server/middlewareButNotReally/storyPrivileges.ts
+++ b/lib/server/middlewareButNotReally/storyPrivileges.ts
@@ -5,25 +5,13 @@ import { IDraft } from "@models/stories/draft";
 import { IUser } from "@models/user";
 export function canDelete(event: H3Event<EventHandlerRequest>, story: IStory) {
 	isLoggedIn(event);
-	return (
-		event.context.currentUser?.profile.isAdmin ||
-		(story.author as IUser)._id === event.context.currentUser?._id
-	);
+	return event.context.currentUser?.profile.isAdmin || (story.author as IUser)._id === event.context.currentUser?._id;
 }
-export function canDeleteDraft(
-	event: H3Event<EventHandlerRequest>,
-	story: IDraft,
-) {
+export function canDeleteDraft(event: H3Event<EventHandlerRequest>, story: IDraft) {
 	isLoggedIn(event);
 	return story.author === event.context.currentUser?._id;
 }
-export function canModify(
-	event: H3Event<EventHandlerRequest>,
-	story: IStory | IDraft,
-) {
+export function canModify(event: H3Event<EventHandlerRequest>, story: IStory | IDraft) {
 	isLoggedIn(event);
-	return (
-		event.context.currentUser?._id === (story.author as IUser)._id ||
-		(story.coAuthor as IUser)?._id === event.context.currentUser?._id
-	);
+	return event.context.currentUser?._id === (story.author as IUser)._id || (story.coAuthor as IUser)?._id === event.context.currentUser?._id;
 }
diff --git a/lib/server/storyHelpers/bodyHandler.ts b/lib/server/storyHelpers/bodyHandler.ts
index de9558b..0e27f36 100644
--- a/lib/server/storyHelpers/bodyHandler.ts
+++ b/lib/server/storyHelpers/bodyHandler.ts
@@ -14,17 +14,9 @@ export default async function (bodyObj: FormChapter): Promise<string> {
 		str = bodyObj.content;
 	} else if (bodyObj.file) {
 		let ext = extname(bodyObj.file).toLowerCase();
-		if (ext === ".md" || ext === ".markdown")
-			str = marked.parse(
-				readFileSync(resolve(`tmp/${bodyObj.file}`)).toString(),
-			);
+		if (ext === ".md" || ext === ".markdown") str = marked.parse(readFileSync(resolve(`tmp/${bodyObj.file}`)).toString());
 		else if (ext === ".doc" || ext === ".docx")
-			str = (
-				await mammoth.convertToHtml(
-					{ path: resolve(`tmp/${bodyObj.file}`) },
-					{ styleMap: ["b => b", "i => i", "u => u"] },
-				)
-			).value;
+			str = (await mammoth.convertToHtml({ path: resolve(`tmp/${bodyObj.file}`) }, { styleMap: ["b => b", "i => i", "u => u"] })).value;
 		else
 			throw createError({
 				statusCode: 400,
diff --git a/lib/server/storyHelpers/replaceGridFS.ts b/lib/server/storyHelpers/replaceGridFS.ts
index 9fd179f..09f31e9 100644
--- a/lib/server/storyHelpers/replaceGridFS.ts
+++ b/lib/server/storyHelpers/replaceGridFS.ts
@@ -1,9 +1,6 @@
 import getBucket from "./getBucket";
 import { Readable } from "stream";
-export default async function replaceGridFS(
-	chapterID: number | undefined,
-	content: string,
-) {
+export default async function replaceGridFS(chapterID: number | undefined, content: string) {
 	let filename = `/stories/${chapterID}.txt`;
 	const bucket = getBucket();
 	if (chapterID) {
diff --git a/pages/bands.vue b/pages/bands.vue
index 3561009..098f65e 100644
--- a/pages/bands.vue
+++ b/pages/bands.vue
@@ -4,9 +4,7 @@
 	import { subscriptions, bp } from "@client/listActions";
 	import { IUser } from "@models/user";
 
-	const { data: bands } = (await useApiFetch<NonNullable<IBand[]>>(
-		"/band/all",
-	)) as unknown as { data: Ref<IBand[]> };
+	const { data: bands } = (await useApiFetch<NonNullable<IBand[]>>("/band/all")) as unknown as { data: Ref<IBand[]> };
 
 	const { data: rd }: { data: any } = useAuth();
 	const data = rd as { user: IUser };
@@ -29,16 +27,10 @@
 					</a-col>
 					<!-- subscribe... -->
 					<a-col v-if="data && data.user?._id" style="margin-left: auto">
-						<a
-							v-if="!data?.user.subscriptions.bands.includes(item._id)"
-							@click="(e) => hider(bands, item._id, 'subscribe', 'bands')"
-						>
+						<a v-if="!data?.user.subscriptions.bands.includes(item._id)" @click="(e) => hider(bands, item._id, 'subscribe', 'bands')">
 							<icon :istyle="'regular'" name="paper-plane" :size="12" />
 						</a>
-						<a
-							v-else
-							@click="(e) => hider(bands, item._id, 'unsubscribe', 'bands')"
-						>
+						<a v-else @click="(e) => hider(bands, item._id, 'unsubscribe', 'bands')">
 							<icon :istyle="'regular'" name="x" :size="12" />
 						</a>
 					</a-col>
diff --git a/pages/forum.vue b/pages/forum.vue
index 80bf9b6..ebbb8e8 100644
--- a/pages/forum.vue
+++ b/pages/forum.vue
@@ -1,8 +1,5 @@
 <template>
 	<div style="width: 100%; height: 90vh">
-		<iframe
-			style="width: 100%; height: 100%"
-			src="https://www.rockfic.com/forum/"
-		/>
+		<iframe style="width: 100%; height: 100%" src="https://www.rockfic.com/forum/" />
 	</div>
 </template>
diff --git a/pages/new-story.vue b/pages/new-story.vue
index 22f0087..a140059 100644
--- a/pages/new-story.vue
+++ b/pages/new-story.vue
@@ -10,10 +10,5 @@
 </script>
 <template>
 	<a-typography-title> Post a new Story </a-typography-title>
-	<story-form
-		endpoint-method="post"
-		:can-draft="true"
-		:data="defaultStory"
-		endpoint="/story/new"
-	/>
+	<story-form endpoint-method="post" :can-draft="true" :data="defaultStory" endpoint="/story/new" />
 </template>
diff --git a/pages/story/[id]/[cidx]/index.vue b/pages/story/[id]/[cidx]/index.vue
index 65e8897..8e8a499 100644
--- a/pages/story/[id]/[cidx]/index.vue
+++ b/pages/story/[id]/[cidx]/index.vue
@@ -12,9 +12,7 @@
 		middleware: [storyMiddleware],
 	});
 	const rtr = useRoute();
-	const { data: story, error } = await useApiFetch<SingleChapterResult>(
-		`/story/${rtr.params.id}/${rtr.params.cidx}`,
-	);
+	const { data: story, error } = await useApiFetch<SingleChapterResult>(`/story/${rtr.params.id}/${rtr.params.cidx}`);
 	provide<SingleChapterResult | null>("story", story.value);
 	console.log("storyyy", story.value?.currentChapter);
 	console.log(rtr);
@@ -52,55 +50,24 @@
 		<div v-html="story?.currentChapter.text"></div>
 		<a-divider style="background-color: #fff" />
 		<a-button-group size="large" v-if="story.totalChapters > 1">
-			<a-button
-				v-if="parseInt(rtr.params.cidx as string) > 1"
-				@click="() => navigateTo(`/story/${rtr.params.id}/1`)"
-			>
-				First
-			</a-button>
-			<a-button
-				v-if="parseInt(rtr.params.cidx as string) > 1"
-				@click="
-					() =>
-						navigateTo(
-							`/story/${rtr.params.id}/${
-								parseInt(rtr.params.cidx as string) - 1
-							}`,
-						)
-				"
-			>
+			<a-button v-if="parseInt(rtr.params.cidx as string) > 1" @click="() => navigateTo(`/story/${rtr.params.id}/1`)"> First </a-button>
+			<a-button v-if="parseInt(rtr.params.cidx as string) > 1" @click="() => navigateTo(`/story/${rtr.params.id}/${parseInt(rtr.params.cidx as string) - 1}`)">
 				Previous
 			</a-button>
 			<a-button
-				v-if="
-					parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1
-				"
-				@click="
-					() =>
-						navigateTo(
-							`/story/${rtr.params.id}/${
-								parseInt(rtr.params.cidx as string) + 1
-							}`,
-						)
-				"
+				v-if="parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1"
+				@click="() => navigateTo(`/story/${rtr.params.id}/${parseInt(rtr.params.cidx as string) + 1}`)"
 			>
 				Next
 			</a-button>
 			<a-button
-				@click="
-					() =>
-						navigateTo(`/story/${rtr.params.id}/${story.chapterNames.length}`)
-				"
-				v-if="
-					parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1
-				"
+				@click="() => navigateTo(`/story/${rtr.params.id}/${story.chapterNames.length}`)"
+				v-if="parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1"
 			>
 				Last
 			</a-button>
 		</a-button-group>
-		<a-typography-title style="text-align: center" :level="2">
-			Reviews
-		</a-typography-title>
+		<a-typography-title style="text-align: center" :level="2"> Reviews </a-typography-title>
 		<for-chapter :endpoint="`/story/${rtr.params.id}/${rtr.params.cidx}`" />
 	</div>
 </template>
diff --git a/pages/story/[id]/chapters.vue b/pages/story/[id]/chapters.vue
index 541899a..29d0b10 100644
--- a/pages/story/[id]/chapters.vue
+++ b/pages/story/[id]/chapters.vue
@@ -6,9 +6,7 @@
 		middleware: [storyMiddleware],
 	});
 	const rtr = useRoute();
-	const { data: story, error } = await useApiFetch<IStory>(
-		`/story/${rtr.params.id}`,
-	);
+	const { data: story, error } = await useApiFetch<IStory>(`/story/${rtr.params.id}`);
 </script>
 
 <template>
diff --git a/server/api/auth/register.post.ts b/server/api/auth/register.post.ts
index ab7b00a..6f50fa8 100644
--- a/server/api/auth/register.post.ts
+++ b/server/api/auth/register.post.ts
@@ -15,10 +15,7 @@ export default eventHandler(async (event) => {
 	await captcha(event);
 	console.log("fields exist");
 	const user = await User.findOne({
-		$or: [
-			{ username: usernameRegex(body.username) },
-			{ email: (body.email as string).toLowerCase() },
-		],
+		$or: [{ username: usernameRegex(body.username) }, { email: (body.email as string).toLowerCase() }],
 	});
 	console.log("after f0", user);
 	if (user)
@@ -27,7 +24,7 @@ export default eventHandler(async (event) => {
 			message: "A user with that username or email already exists.",
 		});
 	let nuser = new User({
-		email: body.email.toLowerCase(),
+		email: body.email.toLowerCase().trim(),
 		username: w2nc(body.username.trim()),
 		password: User.generateHash(body.password),
 		auth: {
diff --git a/server/api/authors.get.ts b/server/api/authors.get.ts
index c0b7c72..0072272 100644
--- a/server/api/authors.get.ts
+++ b/server/api/authors.get.ts
@@ -14,10 +14,7 @@ let authorSingleton: {
 const threshold = 60 * 60 * 1000;
 export default cachedEventHandler(
 	async (ev) => {
-		if (
-			Date.now() - authorSingleton.lastRefreshed >= threshold ||
-			authorSingleton.data.length < 1
-		)
+		if (Date.now() - authorSingleton.lastRefreshed >= threshold || authorSingleton.data.length < 1)
 			authorSingleton.data = await User.aggregate([
 				{ $project: { username: true, _id: true } },
 				{
@@ -38,10 +35,8 @@ export default cachedEventHandler(
 				},
 			]);
 		authorSingleton.data.sort((a, b) => {
-			if (a.username.toLocaleUpperCase() > b.username.toLocaleUpperCase())
-				return 1;
-			else if (a.username.toLocaleUpperCase() < b.username.toLocaleUpperCase())
-				return -1;
+			if (a.username.toLocaleUpperCase() > b.username.toLocaleUpperCase()) return 1;
+			else if (a.username.toLocaleUpperCase() < b.username.toLocaleUpperCase()) return -1;
 			return 0;
 		});
 		return authorSingleton.data;
diff --git a/server/api/review/[id]/index.delete.ts b/server/api/review/[id]/index.delete.ts
index 6cddf2c..844ef28 100644
--- a/server/api/review/[id]/index.delete.ts
+++ b/server/api/review/[id]/index.delete.ts
@@ -19,10 +19,7 @@ export default eventHandler(async (ev) => {
 			statusCode: 400,
 			message: "bad parameter",
 		});
-	if (
-		ev.context.currentUser!._id != s2v?.author &&
-		ev.context.currentUser!._id != c2d._id
-	)
+	if (ev.context.currentUser!._id != s2v?.author && ev.context.currentUser!._id != c2d._id)
 		throw createError({
 			statusCode: 403,
 			message: messages[403],
diff --git a/server/api/review/[id]/index.get.ts b/server/api/review/[id]/index.get.ts
index de8d70e..24d5711 100644
--- a/server/api/review/[id]/index.get.ts
+++ b/server/api/review/[id]/index.get.ts
@@ -4,9 +4,7 @@ import { isIdNan } from "@server/middlewareButNotReally";
 
 export default eventHandler(async (ev) => {
 	const revid = isIdNan(ev);
-	const r = await Review.findById(revid)
-		.populate("author", "username _id")
-		.exec();
+	const r = await Review.findById(revid).populate("author", "username _id").exec();
 	if (!r) {
 		throw createError({
 			statusCode: 404,
diff --git a/server/api/review/[id]/index.put.ts b/server/api/review/[id]/index.put.ts
index f3d3905..0e79b91 100644
--- a/server/api/review/[id]/index.put.ts
+++ b/server/api/review/[id]/index.put.ts
@@ -32,8 +32,6 @@ export default eventHandler(async (ev) => {
 	});
 	return {
 		success: true,
-		data: await Review.findById(revid)
-			.populate("author", "username profile _id")
-			.exec(),
+		data: await Review.findById(revid).populate("author", "username profile _id").exec(),
 	};
 });
diff --git a/server/api/review/[id]/reply.post.ts b/server/api/review/[id]/reply.post.ts
index 3a3babf..a320636 100644
--- a/server/api/review/[id]/reply.post.ts
+++ b/server/api/review/[id]/reply.post.ts
@@ -20,9 +20,7 @@ export default eventHandler(async (ev) => {
 		});
 	}
 	if (
-		(replyingTo?.author as IUser).blocked.includes(
-			ev.context.currentUser!._id,
-		) ||
+		(replyingTo?.author as IUser).blocked.includes(ev.context.currentUser!._id) ||
 		ev.context.currentUser!.blocked.includes((replyingTo?.author as IUser)._id)
 	) {
 		throw createError({
@@ -40,9 +38,7 @@ export default eventHandler(async (ev) => {
 		datePosted: new Date(),
 	});
 	const { _id } = await newReply.save();
-	const nrs = (await Review.findOne({ _id })
-		.populate("author", "username _id blocked")
-		.exec())!;
+	const nrs = (await Review.findOne({ _id }).populate("author", "username _id blocked").exec())!;
 	replyingTo.replies.push(nrs._id);
 	await replyingTo.save();
 	const story = await Story.findById(replyingTo.leftOn);
@@ -52,9 +48,7 @@ export default eventHandler(async (ev) => {
 		});
 	}
 	return {
-		back: `/story/${replyingTo.leftOn}/${
-			story!.chapters.findIndex((x) => x.id === nrs.whichChapter) + 1
-		}`,
+		back: `/story/${replyingTo.leftOn}/${story!.chapters.findIndex((x) => x.id === nrs.whichChapter) + 1}`,
 		data: nrs.toObject(),
 		success: true,
 	};
diff --git a/server/api/story/[id]/full.get.ts b/server/api/story/[id]/full.get.ts
index a13d499..452f051 100644
--- a/server/api/story/[id]/full.get.ts
+++ b/server/api/story/[id]/full.get.ts
@@ -8,11 +8,7 @@ export default eventHandler(async (ev) => {
 	isLoggedIn(ev);
 	const s = await storyQuerier(ev);
 	const hidden = s.chapters.some((a) => a.hidden);
-	if (
-		hidden &&
-		ev.context.currentUser?._id !== (s.author as IUser)._id &&
-		!ev.context.currentUser?.profile.isAdmin
-	) {
+	if (hidden && ev.context.currentUser?._id !== (s.author as IUser)._id && !ev.context.currentUser?.profile.isAdmin) {
 		throw createError({
 			statusCode: 403,
 			message: messages[403],
diff --git a/server/api/totals.get.ts b/server/api/totals.get.ts
index a4e6a02..c33bda3 100644
--- a/server/api/totals.get.ts
+++ b/server/api/totals.get.ts
@@ -20,10 +20,7 @@ export default cachedEventHandler(
 	async (event) => {
 		let aa = mongoose.connection.db.collection("z_index_totAuthors");
 		let totalStories = await Story.countDocuments({ "chapters.hidden": false });
-		if (
-			!authorSingleton.data.length ||
-			Date.now() - authorSingleton.lastRefreshed >= threshold
-		) {
+		if (!authorSingleton.data.length || Date.now() - authorSingleton.lastRefreshed >= threshold) {
 			authorSingleton.data = await User.aggregate([
 				{ $project: { username: true, _id: true } },
 				{
diff --git a/server/api/user/me/reviews.get.ts b/server/api/user/me/reviews.get.ts
index 1f184db..cf6663e 100644
--- a/server/api/user/me/reviews.get.ts
+++ b/server/api/user/me/reviews.get.ts
@@ -16,9 +16,5 @@ export default eventHandler(async (ev) => {
 	})
 		.populate("story")
 		.exec();
-	return ar
-		.map((a) => a.toObject())
-		.sort(
-			(a, b) => b.datePosted.getMilliseconds() - a.datePosted.getMilliseconds(),
-		);
+	return ar.map((a) => a.toObject()).sort((a, b) => b.datePosted.getMilliseconds() - a.datePosted.getMilliseconds());
 });
diff --git a/server/middleware/06.ip.ts b/server/middleware/06.ip.ts
index 04441e3..13ce771 100644
--- a/server/middleware/06.ip.ts
+++ b/server/middleware/06.ip.ts
@@ -1,10 +1,7 @@
 export default eventHandler(async (ev) => {
 	if (ev.context.currentUser) {
 		let log = ev.context.currentUser.ipLog;
-		if (
-			ev.context.clientAddress !== undefined &&
-			!/127\.0\.0\.1|localhost|::1/.test(ev.context.clientAddress)
-		) {
+		if (ev.context.clientAddress !== undefined && !/127\.0\.0\.1|localhost|::1/.test(ev.context.clientAddress)) {
 			let found = log.findIndex((a) => a.ip === ev.context.clientAddress);
 			if (found !== -1) {
 				ev.context.currentUser.ipLog[found].lastAccess = new Date();
diff --git a/server/middleware/10.ficmasData.ts b/server/middleware/10.ficmasData.ts
index 71b7767..abff170 100644
--- a/server/middleware/10.ficmasData.ts
+++ b/server/middleware/10.ficmasData.ts
@@ -4,10 +4,7 @@ export default eventHandler(async (event) => {
 	let y = new Date().getFullYear();
 	let fmfilt: any = {};
 
-	if (
-		!!process.env.JulyFicmas &&
-		new Date() < new Date(Date.parse("Aug 1 " + y))
-	) {
+	if (!!process.env.JulyFicmas && new Date() < new Date(Date.parse("Aug 1 " + y))) {
 		fmfilt.isAnniversary = true;
 		fmfilt.year = y;
 	} else if (new Date() < new Date(Date.parse("Dec 25 " + y))) {
diff --git a/server/middleware/90.log.ts b/server/middleware/90.log.ts
index dec5665..5af56f7 100644
--- a/server/middleware/90.log.ts
+++ b/server/middleware/90.log.ts
@@ -5,9 +5,7 @@ export default eventHandler(async (ev) => {
 	ev.node.res.on("close", () => {
 		p.done({
 			label: "http/request",
-			message: `{${
-				ev.context.currentUser?.username || "guest"
-			}} | ${ev.method.toLocaleUpperCase()} @ ${ev._path}`,
+			message: `{${ev.context.currentUser?.username || "guest"}} | ${ev.method.toLocaleUpperCase()} @ ${ev._path}`,
 		});
 	});
 });
diff --git a/typings/auth.d.ts b/typings/auth.d.ts
index a722c23..8e0f61e 100644
--- a/typings/auth.d.ts
+++ b/typings/auth.d.ts
@@ -1,12 +1,5 @@
 import { IUser } from "@models/user";
-import {
-	GetSessionFunc,
-	SecondarySignInOptions,
-	SessionLastRefreshedAt,
-	SessionStatus,
-	SignInFunc,
-	SignOutFunc,
-} from "@sidebase/nuxt-auth/dist/runtime/types";
+import { GetSessionFunc, SecondarySignInOptions, SessionLastRefreshedAt, SessionStatus, SignInFunc, SignOutFunc } from "@sidebase/nuxt-auth/dist/runtime/types";
 import { ComputedRef, Ref } from "vue";
 
 declare module "#auth" {
@@ -24,18 +17,10 @@ declare module "@sidebase/nuxt-auth/dist/runtime/types" {
 	declare const signIn: SignInFunc<Credentials, any>;
 	declare const signOut: SignOutFunc;
 	declare const getSession: GetSessionFunc<SessionData | null | void>;
-	declare const signUp: (
-		credentials: Credentials,
-		signInOptions?: SecondarySignInOptions,
-	) => Promise<any>;
+	declare const signUp: (credentials: Credentials, signInOptions?: SecondarySignInOptions) => Promise<any>;
 
 	type WrappedSessionData<SessionData> = Ref<SessionData | null | undefined>;
-	export interface CommonUseAuthReturn<
-		SignIn,
-		SignOut,
-		GetSession,
-		SessionData,
-	> {
+	export interface CommonUseAuthReturn<SignIn, SignOut, GetSession, SessionData> {
 		data: Readonly<WrappedSessionData<SessionData>>;
 		lastRefreshedAt: Readonly<Ref<SessionLastRefreshedAt>>;
 		status: ComputedRef<SessionStatus>;
@@ -43,13 +28,7 @@ declare module "@sidebase/nuxt-auth/dist/runtime/types" {
 		signOut: SignOut;
 		getSession: GetSession;
 	}
-	interface UseAuthReturn
-		extends CommonUseAuthReturn<
-			typeof signIn,
-			typeof signOut,
-			typeof getSession,
-			SessionData
-		> {
+	interface UseAuthReturn extends CommonUseAuthReturn<typeof signIn, typeof signOut, typeof getSession, SessionData> {
 		signUp: typeof signUp;
 		token: Readonly<Ref<string | null>>;
 	}