From 41592eafb363e3c62ab2d3e5f41b38d7d083d3fb Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Fri, 9 Jan 2026 22:06:40 +0900
Subject: refactor: make noImplicitAny true (#17083)

* wip

* Update emojis.emoji.vue

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update manager.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update analytics.ts
---
 packages/frontend/src/components/MkReactionsViewer.vue | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'packages/frontend/src/components/MkReactionsViewer.vue')

diff --git a/packages/frontend/src/components/MkReactionsViewer.vue b/packages/frontend/src/components/MkReactionsViewer.vue
index bd9ef50157..ab7f86842c 100644
--- a/packages/frontend/src/components/MkReactionsViewer.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.vue
@@ -32,11 +32,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 import * as Misskey from 'misskey-js';
 import { inject, watch, ref } from 'vue';
 import { TransitionGroup } from 'vue';
+import { isSupportedEmoji } from '@@/js/emojilist.js';
 import XReaction from '@/components/MkReactionsViewer.reaction.vue';
 import { $i } from '@/i.js';
 import { prefer } from '@/preferences.js';
 import { customEmojisMap } from '@/custom-emojis.js';
-import { isSupportedEmoji } from '@@/js/emojilist.js';
 import { DI } from '@/di.js';
 
 const props = withDefaults(defineProps<{
@@ -60,8 +60,8 @@ const initialReactions = new Set(Object.keys(props.reactions));
 const _reactions = ref<[string, number][]>([]);
 const hasMoreReactions = ref(false);
 
-if (props.myReaction && !Object.keys(_reactions.value).includes(props.myReaction)) {
-	_reactions.value[props.myReaction] = props.reactions[props.myReaction];
+if (props.myReaction != null && !(props.myReaction in props.reactions)) {
+	_reactions.value.push([props.myReaction, props.reactions[props.myReaction]]);
 }
 
 function onMockToggleReaction(emoji: string, count: number) {
-- 
cgit v1.2.3-freya


From 389861f1da42e66fe52fe5d33ba4ade35aa16f23 Mon Sep 17 00:00:00 2001
From: かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>
Date: Fri, 16 Jan 2026 22:42:08 +0900
Subject: refactor(frontend): fix invalid self-closing tags (#17103)

* fix(frontend): fix invalid self-closing tags

* apply eslint rules

* fix

* fix
---
 packages/frontend-embed/eslint.config.js                     | 10 +++++++++-
 packages/frontend-embed/src/components/EmAvatar.vue          | 12 ++++++------
 packages/frontend-embed/src/components/EmImgWithBlurhash.vue |  2 +-
 packages/frontend/eslint.config.js                           | 10 +++++++++-
 packages/frontend/src/components/MkDialog.vue                |  4 ++--
 packages/frontend/src/components/MkDivider.vue               |  2 +-
 packages/frontend/src/components/MkImgWithBlurhash.vue       |  2 +-
 packages/frontend/src/components/MkInput.vue                 |  2 +-
 packages/frontend/src/components/MkNotification.vue          |  4 ++--
 packages/frontend/src/components/MkPagingButtons.vue         |  4 ++--
 packages/frontend/src/components/MkPolkadots.vue             |  2 +-
 packages/frontend/src/components/MkPostForm.vue              |  4 ++--
 packages/frontend/src/components/MkPullToRefresh.vue         |  2 +-
 packages/frontend/src/components/MkReactionsViewer.vue       |  2 +-
 packages/frontend/src/components/global/MkAvatar.vue         | 12 ++++++------
 .../admin/abuse-report/notification-recipient.editor.vue     |  4 ++--
 .../pages/admin/abuse-report/notification-recipient.item.vue |  6 +++---
 .../src/pages/admin/abuse-report/notification-recipient.vue  |  2 +-
 packages/frontend/src/pages/admin/server-rules.vue           |  4 ++--
 packages/frontend/src/pages/admin/system-webhook.item.vue    |  8 ++++----
 packages/frontend/src/pages/drop-and-fusion.game.vue         |  4 ++--
 packages/frontend/src/pages/follow-requests.vue              |  6 +++---
 packages/frontend/src/pages/settings/2fa.vue                 |  2 +-
 packages/frontend/src/pages/user/home.vue                    |  6 +++---
 packages/frontend/src/ui/deck/tl-column.vue                  |  2 +-
 25 files changed, 67 insertions(+), 51 deletions(-)

(limited to 'packages/frontend/src/components/MkReactionsViewer.vue')

diff --git a/packages/frontend-embed/eslint.config.js b/packages/frontend-embed/eslint.config.js
index 63767cfb3c..d1ca70617b 100644
--- a/packages/frontend-embed/eslint.config.js
+++ b/packages/frontend-embed/eslint.config.js
@@ -144,7 +144,15 @@ export default [
 			'vue/return-in-computed-property': 'warn',
 			'vue/no-setup-props-reactivity-loss': 'warn',
 			'vue/max-attributes-per-line': 'off',
-			'vue/html-self-closing': 'off',
+			'vue/html-self-closing': ['error', {
+				html: {
+					void: 'any',
+					normal: 'never',
+					component: 'any',
+				},
+				svg: 'any',
+				math: 'any',
+			}],
 			'vue/singleline-html-element-content-newline': 'off',
 			'vue/v-on-event-hyphenation': ['error', 'never', {
 				autofix: true,
diff --git a/packages/frontend-embed/src/components/EmAvatar.vue b/packages/frontend-embed/src/components/EmAvatar.vue
index 58c35c8ef0..3f91e14403 100644
--- a/packages/frontend-embed/src/components/EmAvatar.vue
+++ b/packages/frontend-embed/src/components/EmAvatar.vue
@@ -9,16 +9,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div v-if="user.isCat" :class="[$style.ears]">
 		<div :class="$style.earLeft">
 			<div v-if="false" :class="$style.layer">
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
 			</div>
 		</div>
 		<div :class="$style.earRight">
 			<div v-if="false" :class="$style.layer">
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
 			</div>
 		</div>
 	</div>
diff --git a/packages/frontend-embed/src/components/EmImgWithBlurhash.vue b/packages/frontend-embed/src/components/EmImgWithBlurhash.vue
index 71f0ee9294..be18ce79d5 100644
--- a/packages/frontend-embed/src/components/EmImgWithBlurhash.vue
+++ b/packages/frontend-embed/src/components/EmImgWithBlurhash.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div ref="root" :class="['chromatic-ignore', $style.root, { [$style.cover]: cover }]" :title="title ?? ''">
-	<canvas v-show="hide" key="canvas" ref="canvas" :class="$style.canvas" :width="canvasWidth" :height="canvasHeight" :title="title ?? undefined" tabindex="-1"/>
+	<canvas v-show="hide" key="canvas" ref="canvas" :class="$style.canvas" :width="canvasWidth" :height="canvasHeight" :title="title ?? undefined" tabindex="-1"></canvas>
 	<img v-show="!hide" key="img" ref="img" :height="imgHeight ?? undefined" :width="imgWidth ?? undefined" :class="$style.img" :src="src ?? undefined" :title="title ?? undefined" :alt="alt ?? undefined" loading="eager" decoding="async" tabindex="-1"/>
 </div>
 </template>
diff --git a/packages/frontend/eslint.config.js b/packages/frontend/eslint.config.js
index 15baf449fe..adae471c0a 100644
--- a/packages/frontend/eslint.config.js
+++ b/packages/frontend/eslint.config.js
@@ -147,7 +147,15 @@ export default [
 			'vue/return-in-computed-property': 'warn',
 			'vue/no-setup-props-reactivity-loss': 'warn',
 			'vue/max-attributes-per-line': 'off',
-			'vue/html-self-closing': 'off',
+			'vue/html-self-closing': ['error', {
+				html: {
+					void: 'any',
+					normal: 'never',
+					component: 'any',
+				},
+				svg: 'any',
+				math: 'any',
+			}],
 			'vue/singleline-html-element-content-newline': 'off',
 			'vue/v-on-event-hyphenation': ['error', 'never', {
 				autofix: true,
diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue
index 4801b412f8..fb8b38de6d 100644
--- a/packages/frontend/src/components/MkDialog.vue
+++ b/packages/frontend/src/components/MkDialog.vue
@@ -25,8 +25,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<MkInput v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder || undefined" :autocomplete="input.autocomplete" @keydown="onInputKeydown">
 			<template v-if="input.type === 'password'" #prefix><i class="ti ti-lock"></i></template>
 			<template #caption>
-				<span v-if="okButtonDisabledReason === 'charactersExceeded'" v-text="i18n.tsx._dialog.charactersExceeded({ current: (inputValue as string)?.length ?? 0, max: input.maxLength ?? 'NaN' })"/>
-				<span v-else-if="okButtonDisabledReason === 'charactersBelow'" v-text="i18n.tsx._dialog.charactersBelow({ current: (inputValue as string)?.length ?? 0, min: input.minLength ?? 'NaN' })"/>
+				<span v-if="okButtonDisabledReason === 'charactersExceeded'" v-text="i18n.tsx._dialog.charactersExceeded({ current: (inputValue as string)?.length ?? 0, max: input.maxLength ?? 'NaN' })"></span>
+				<span v-else-if="okButtonDisabledReason === 'charactersBelow'" v-text="i18n.tsx._dialog.charactersBelow({ current: (inputValue as string)?.length ?? 0, min: input.minLength ?? 'NaN' })"></span>
 			</template>
 		</MkInput>
 		<MkSelect v-if="select" v-model="selectedValue" :items="selectDef" autofocus></MkSelect>
diff --git a/packages/frontend/src/components/MkDivider.vue b/packages/frontend/src/components/MkDivider.vue
index f72f091383..808a9ae2f8 100644
--- a/packages/frontend/src/components/MkDivider.vue
+++ b/packages/frontend/src/components/MkDivider.vue
@@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		borderWidth ? { borderWidth: borderWidth } : {},
 		borderColor ? { borderColor: borderColor } : {},
 	]"
-/>
+></div>
 </template>
 
 <script setup lang="ts">
diff --git a/packages/frontend/src/components/MkImgWithBlurhash.vue b/packages/frontend/src/components/MkImgWithBlurhash.vue
index 983a0932c3..a61836e101 100644
--- a/packages/frontend/src/components/MkImgWithBlurhash.vue
+++ b/packages/frontend/src/components/MkImgWithBlurhash.vue
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			draggable="false"
 			tabindex="-1"
 			style="-webkit-user-drag: none;"
-		/>
+		></canvas>
 		<img
 			v-show="!hide"
 			key="img"
diff --git a/packages/frontend/src/components/MkInput.vue b/packages/frontend/src/components/MkInput.vue
index 8a49fd231d..aebeefe165 100644
--- a/packages/frontend/src/components/MkInput.vue
+++ b/packages/frontend/src/components/MkInput.vue
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			@input="onInput"
 		>
 		<datalist v-if="datalist" :id="id">
-			<option v-for="data in datalist" :key="data" :value="data"/>
+			<option v-for="data in datalist" :key="data" :value="data"></option>
 		</datalist>
 		<div ref="suffixEl" :class="$style.suffix"><slot name="suffix"></slot></div>
 	</div>
diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue
index a22fb7db01..30494d5362 100644
--- a/packages/frontend/src/components/MkNotification.vue
+++ b/packages/frontend/src/components/MkNotification.vue
@@ -143,8 +143,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<template v-else-if="notification.type === 'receiveFollowRequest'">
 				<span :class="$style.text" style="opacity: 0.6;">{{ i18n.ts.receiveFollowRequest }}</span>
 				<div v-if="full && !followRequestDone" :class="$style.followRequestCommands">
-					<MkButton :class="$style.followRequestCommandButton" rounded primary @click="acceptFollowRequest()"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
-					<MkButton :class="$style.followRequestCommandButton" rounded danger @click="rejectFollowRequest()"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
+					<MkButton :class="$style.followRequestCommandButton" rounded primary @click="acceptFollowRequest()"><i class="ti ti-check"></i> {{ i18n.ts.accept }}</MkButton>
+					<MkButton :class="$style.followRequestCommandButton" rounded danger @click="rejectFollowRequest()"><i class="ti ti-x"></i> {{ i18n.ts.reject }}</MkButton>
 				</div>
 			</template>
 			<span v-else-if="notification.type === 'test'" :class="$style.text">{{ i18n.ts._notification.notificationWillBeDisplayedLikeThis }}</span>
diff --git a/packages/frontend/src/components/MkPagingButtons.vue b/packages/frontend/src/components/MkPagingButtons.vue
index fe59efd83a..10f432e50d 100644
--- a/packages/frontend/src/components/MkPagingButtons.vue
+++ b/packages/frontend/src/components/MkPagingButtons.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div :class="$style.buttons">
 		<div v-if="prevDotVisible" :class="$style.headTailButtons">
 			<MkButton @click="onToHeadButtonClicked">{{ min }}</MkButton>
-			<span class="ti ti-dots"/>
+			<span class="ti ti-dots"></span>
 		</div>
 
 		<MkButton
@@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</MkButton>
 
 		<div v-if="nextDotVisible" :class="$style.headTailButtons">
-			<span class="ti ti-dots"/>
+			<span class="ti ti-dots"></span>
 			<MkButton @click="onToTailButtonClicked">{{ max }}</MkButton>
 		</div>
 	</div>
diff --git a/packages/frontend/src/components/MkPolkadots.vue b/packages/frontend/src/components/MkPolkadots.vue
index 4f1346b685..ca7bfd3a93 100644
--- a/packages/frontend/src/components/MkPolkadots.vue
+++ b/packages/frontend/src/components/MkPolkadots.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<div :class="[$style.root, accented ? $style.accented : null, revered ? $style.revered : null]"/>
+<div :class="[$style.root, accented ? $style.accented : null, revered ? $style.revered : null]"></div>
 </template>
 
 <script lang="ts" setup>
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index 9d5d2392d0..72a7f4a01c 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -77,7 +77,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="[$style.textOuter, { [$style.withCw]: useCw }]">
 		<div v-if="targetChannel" :class="$style.colorBar" :style="{ background: targetChannel.color }"></div>
-		<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :readonly="textAreaReadOnly" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @keyup="onKeyup" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/>
+		<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :readonly="textAreaReadOnly" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @keyup="onKeyup" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"></textarea>
 		<div v-if="maxTextLength - textLength < 100" :class="['_acrylic', $style.textCount, { [$style.textOver]: textLength > maxTextLength }]">{{ maxTextLength - textLength }}</div>
 	</div>
 	<input v-show="withHashtags" ref="hashtagsInputEl" v-model="hashtags" :class="$style.hashtags" :placeholder="i18n.ts.hashtags" list="hashtags">
@@ -108,7 +108,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 	</footer>
 	<datalist id="hashtags">
-		<option v-for="hashtag in recentHashtags" :key="hashtag" :value="hashtag"/>
+		<option v-for="hashtag in recentHashtags" :key="hashtag" :value="hashtag"></option>
 	</datalist>
 </div>
 </template>
diff --git a/packages/frontend/src/components/MkPullToRefresh.vue b/packages/frontend/src/components/MkPullToRefresh.vue
index 89aca5d29b..4d936758c5 100644
--- a/packages/frontend/src/components/MkPullToRefresh.vue
+++ b/packages/frontend/src/components/MkPullToRefresh.vue
@@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 	</div>
 
-	<slot/>
+	<slot></slot>
 </div>
 </template>
 
diff --git a/packages/frontend/src/components/MkReactionsViewer.vue b/packages/frontend/src/components/MkReactionsViewer.vue
index ab7f86842c..67fd570b41 100644
--- a/packages/frontend/src/components/MkReactionsViewer.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.vue
@@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		:myReaction="props.myReaction"
 		@reactionToggled="onMockToggleReaction"
 	/>
-	<slot v-if="hasMoreReactions" name="more"/>
+	<slot v-if="hasMoreReactions" name="more"></slot>
 </component>
 </template>
 
diff --git a/packages/frontend/src/components/global/MkAvatar.vue b/packages/frontend/src/components/global/MkAvatar.vue
index fd1d0c2b63..b413fef3b8 100644
--- a/packages/frontend/src/components/global/MkAvatar.vue
+++ b/packages/frontend/src/components/global/MkAvatar.vue
@@ -11,16 +11,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div v-if="user.isCat" :class="[$style.ears]">
 		<div :class="$style.earLeft">
 			<div v-if="false" :class="$style.layer">
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
 			</div>
 		</div>
 		<div :class="$style.earRight">
 			<div v-if="false" :class="$style.layer">
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
-				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"/>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
+				<div :class="$style.plot" :style="{ backgroundImage: `url(${JSON.stringify(url)})` }"></div>
 			</div>
 		</div>
 	</div>
diff --git a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue
index 7c3f736506..591d8fa736 100644
--- a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue
+++ b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue
@@ -37,8 +37,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<template #label>{{ i18n.ts._abuseReport._notificationRecipient.notifiedWebhook }}</template>
 						</MkSelect>
 						<MkButton rounded :class="$style.systemWebhookEditButton" @click="onEditSystemWebhookClicked">
-							<span v-if="systemWebhookId === null" class="ti ti-plus" style="line-height: normal"/>
-							<span v-else class="ti ti-settings" style="line-height: normal"/>
+							<span v-if="systemWebhookId === null" class="ti ti-plus" style="line-height: normal"></span>
+							<span v-else class="ti ti-settings" style="line-height: normal"></span>
 						</MkButton>
 					</div>
 				</div>
diff --git a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue
index 36d586bd23..ba5830c2e8 100644
--- a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue
+++ b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div :class="$style.root" class="_panel _gaps_s">
-	<div :class="$style.rightDivider" style="width: 80px;"><span :class="`ti ${methodIcon}`"/> {{ methodName }}</div>
+	<div :class="$style.rightDivider" style="width: 80px;"><span :class="`ti ${methodIcon}`"></span> {{ methodName }}</div>
 	<div :class="$style.rightDivider" style="flex: 0.5">{{ entity.name }}</div>
 	<div :class="$style.rightDivider" style="flex: 1">
 		<div v-if="method === 'email' && user">
@@ -19,10 +19,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="$style.recipientButtons" style="margin-left: auto">
 		<button :class="$style.recipientButton" @click="onEditButtonClicked()">
-			<span class="ti ti-settings"/>
+			<span class="ti ti-settings"></span>
 		</button>
 		<button :class="$style.recipientButton" @click="onDeleteButtonClicked()">
-			<span class="ti ti-trash"/>
+			<span class="ti ti-trash"></span>
 		</button>
 	</div>
 </div>
diff --git a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue
index 893bd8d6d3..a9cf372c0e 100644
--- a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue
+++ b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.root" class="_gaps_m">
 			<div :class="$style.addButton">
 				<MkButton primary @click="onAddButtonClicked">
-					<span class="ti ti-plus"/> {{ i18n.ts._abuseReport._notificationRecipient.createRecipient }}
+					<span class="ti ti-plus"></span> {{ i18n.ts._abuseReport._notificationRecipient.createRecipient }}
 				</MkButton>
 			</div>
 			<div :class="$style.subMenus" class="_gaps_s">
diff --git a/packages/frontend/src/pages/admin/server-rules.vue b/packages/frontend/src/pages/admin/server-rules.vue
index b192129548..02aad732f6 100644
--- a/packages/frontend/src/pages/admin/server-rules.vue
+++ b/packages/frontend/src/pages/admin/server-rules.vue
@@ -21,8 +21,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<template #default="{ item, index, dragStart }">
 					<div :class="$style.item">
 						<div :class="$style.itemHeader">
-							<div :class="$style.itemNumber" v-text="String(index + 1)"/>
-							<span :class="$style.itemHandle" :draggable="true" @dragstart.stop="dragStart"><i class="ti ti-menu"/></span>
+							<div :class="$style.itemNumber">{{ index + 1 }}</div>
+							<span :class="$style.itemHandle" :draggable="true" @dragstart.stop="dragStart"><i class="ti ti-menu"></i></span>
 							<button class="_button" :class="$style.itemRemove" @click="remove(item.id)"><i class="ti ti-x"></i></button>
 						</div>
 						<MkInput :modelValue="item.text" @update:modelValue="serverRules[index].text = $event"/>
diff --git a/packages/frontend/src/pages/admin/system-webhook.item.vue b/packages/frontend/src/pages/admin/system-webhook.item.vue
index b53667e98c..9807cbb313 100644
--- a/packages/frontend/src/pages/admin/system-webhook.item.vue
+++ b/packages/frontend/src/pages/admin/system-webhook.item.vue
@@ -8,14 +8,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template #label>{{ entity.name || entity.url }}</template>
 	<template v-if="entity.name != null && entity.name != ''" #caption>{{ entity.url }}</template>
 	<template #icon>
-		<i v-if="!entity.isActive" class="ti ti-player-pause"/>
-		<i v-else-if="entity.latestStatus === null" class="ti ti-circle"/>
+		<i v-if="!entity.isActive" class="ti ti-player-pause"></i>
+		<i v-else-if="entity.latestStatus === null" class="ti ti-circle"></i>
 		<i
 			v-else-if="[200, 201, 204].includes(entity.latestStatus)"
 			class="ti ti-check"
 			:style="{ color: 'var(--MI_THEME-success)' }"
-		/>
-		<i v-else class="ti ti-alert-triangle" :style="{ color: 'var(--MI_THEME-error)' }"/>
+		></i>
+		<i v-else class="ti ti-alert-triangle" :style="{ color: 'var(--MI_THEME-error)' }"></i>
 	</template>
 	<template #suffix>
 		<MkTime v-if="entity.latestSentAt" :time="entity.latestSentAt" style="margin-right: 8px"/>
diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue
index 4c677a8d09..21e4657b2c 100644
--- a/packages/frontend/src/pages/drop-and-fusion.game.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.game.vue
@@ -58,7 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div ref="containerEl" :class="[$style.gameContainer, { [$style.gameOver]: isGameOver && !replaying }]" @contextmenu.stop.prevent @click.stop.prevent="onClick" @touchmove.stop.prevent="onTouchmove" @touchend="onTouchend" @mousemove="onMousemove">
 				<img v-if="store.s.darkMode" src="/client-assets/drop-and-fusion/frame-dark.svg" :class="$style.mainFrameImg"/>
 				<img v-else src="/client-assets/drop-and-fusion/frame-light.svg" :class="$style.mainFrameImg"/>
-				<canvas ref="canvasEl" :class="$style.canvas"/>
+				<canvas ref="canvasEl" :class="$style.canvas"></canvas>
 				<Transition
 					:enterActiveClass="$style.transition_combo_enterActive"
 					:leaveActiveClass="$style.transition_combo_leaveActive"
@@ -82,7 +82,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</Transition>
 					<template v-if="dropReady && currentPick">
 						<img src="/client-assets/drop-and-fusion/drop-arrow.svg" :class="$style.currentMonoArrow"/>
-						<div :class="$style.dropGuide"/>
+						<div :class="$style.dropGuide"></div>
 					</template>
 				</div>
 				<div v-if="isGameOver && !replaying" :class="$style.gameOverLabel">
diff --git a/packages/frontend/src/pages/follow-requests.vue b/packages/frontend/src/pages/follow-requests.vue
index 1b729837a7..2404fd9744 100644
--- a/packages/frontend/src/pages/follow-requests.vue
+++ b/packages/frontend/src/pages/follow-requests.vue
@@ -18,11 +18,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 								<p class="acct">@{{ acct(displayUser(req)) }}</p>
 							</div>
 							<div v-if="tab === 'list'" class="commands">
-								<MkButton class="command" rounded primary @click="accept(displayUser(req))"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
-								<MkButton class="command" rounded danger @click="reject(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
+								<MkButton class="command" rounded primary @click="accept(displayUser(req))"><i class="ti ti-check"></i> {{ i18n.ts.accept }}</MkButton>
+								<MkButton class="command" rounded danger @click="reject(displayUser(req))"><i class="ti ti-x"></i> {{ i18n.ts.reject }}</MkButton>
 							</div>
 							<div v-else class="commands">
-								<MkButton class="command" rounded danger @click="cancel(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.cancel }}</MkButton>
+								<MkButton class="command" rounded danger @click="cancel(displayUser(req))"><i class="ti ti-x"></i> {{ i18n.ts.cancel }}</MkButton>
 							</div>
 						</div>
 					</div>
diff --git a/packages/frontend/src/pages/settings/2fa.vue b/packages/frontend/src/pages/settings/2fa.vue
index fcd598fe76..bf71845a38 100644
--- a/packages/frontend/src/pages/settings/2fa.vue
+++ b/packages/frontend/src/pages/settings/2fa.vue
@@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<template #suffix><i v-if="$i.twoFactorEnabled" class="ti ti-check" style="color: var(--MI_THEME-success)"></i></template>
 
 					<div v-if="$i.twoFactorEnabled" class="_gaps_s">
-						<div v-text="i18n.ts._2fa.alreadyRegistered"/>
+						<div>{{ i18n.ts._2fa.alreadyRegistered }}</div>
 						<template v-if="$i.securityKeysList!.length > 0">
 							<MkButton @click="renewTOTP">{{ i18n.ts._2fa.renewTOTP }}</MkButton>
 							<MkInfo>{{ i18n.ts._2fa.whyTOTPOnlyRenew }}</MkInfo>
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index c472c4da7b..64b03bc4bc 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 									<span v-if="user.isLocked"><i class="ti ti-lock"></i></span>
 									<span v-if="user.isBot"><i class="ti ti-robot"></i></span>
 									<button v-if="$i && !isEditingMemo && !memoDraft" class="_button add-note-button" @click="showMemoTextarea">
-										<i class="ti ti-edit"/> {{ i18n.ts.addMemo }}
+										<i class="ti ti-edit"></i> {{ i18n.ts.addMemo }}
 									</button>
 								</div>
 							</div>
@@ -71,7 +71,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 							</div>
 						</div>
 						<div v-if="isEditingMemo || memoDraft" class="memo" :class="{'no-memo': !memoDraft}">
-							<div class="heading" v-text="i18n.ts.memo"/>
+							<div class="heading">{{ i18n.ts.memo }}</div>
 							<textarea
 								ref="memoTextareaEl"
 								v-model="memoDraft"
@@ -79,7 +79,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 								@focus="isEditingMemo = true"
 								@blur="updateMemo"
 								@input="adjustMemoTextarea"
-							/>
+							></textarea>
 						</div>
 						<div class="description">
 							<MkOmit>
diff --git a/packages/frontend/src/ui/deck/tl-column.vue b/packages/frontend/src/ui/deck/tl-column.vue
index 0e59913c4c..aab0cde1c8 100644
--- a/packages/frontend/src/ui/deck/tl-column.vue
+++ b/packages/frontend/src/ui/deck/tl-column.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <XColumn :menu="menu" :column="column" :isStacked="isStacked" :refresher="async () => { await timeline?.reloadTimeline() }">
 	<template #header>
-		<i v-if="column.tl != null" :class="basicTimelineIconClass(column.tl)"/>
+		<i v-if="column.tl != null" :class="basicTimelineIconClass(column.tl)"></i>
 		<span style="margin-left: 8px;">{{ column.name || (column.tl ? i18n.ts._timelines[column.tl] : null) || i18n.ts._deck._columns.tl }}</span>
 	</template>
 
-- 
cgit v1.2.3-freya

