From c6946d5f0ea15d8ae2ebd14c723e7b24bb1aa2ba Mon Sep 17 00:00:00 2001
From: ThatOneCalculator <kainoa@t1c.dev>
Date: Fri, 11 Aug 2023 19:57:32 -0700
Subject: [PATCH] refactor: :rotating_light: fix many linter warnings,
 auto-import vue components + remove unused imports

---
 packages/client/.eslintrc-auto-import.json    |  63 +++++
 packages/client/.eslintrc.json                |  17 +-
 packages/client/@types/theme.d.ts             |   2 +-
 packages/client/assets/label-red.svg          |   4 +-
 packages/client/assets/label.svg              |   4 +-
 packages/client/auto-imports.d.ts             | 243 ++++++++++++++++++
 packages/client/components.d.ts               | 198 ++++++++++++++
 packages/client/package.json                  |   6 +-
 packages/client/src/account.ts                |  10 +-
 packages/client/src/components/MkDialog.vue   |   6 +-
 .../client/src/components/MkDrive.file.vue    |   6 +-
 .../client/src/components/MkDrive.folder.vue  |  12 +-
 .../src/components/MkDrive.navFolder.vue      |  10 +-
 packages/client/src/components/MkDrive.vue    |  16 +-
 .../src/components/MkDriveFileThumbnail.vue   |   2 +-
 .../src/components/MkDriveSelectDialog.vue    |   2 +-
 .../client/src/components/MkDriveWindow.vue   |   2 +-
 .../src/components/MkEmojiPicker.section.vue  |   2 +-
 .../client/src/components/MkEmojiPicker.vue   |  12 +-
 .../src/components/MkFeaturedPhotos.vue       |   2 +-
 .../client/src/components/MkFollowButton.vue  |  14 +-
 .../src/components/MkForgotPassword.vue       |   9 +-
 packages/client/src/components/MkFormula.vue  |   2 +-
 packages/client/src/components/MkHeatmap.vue  |   8 +-
 .../client/src/components/MkImageViewer.vue   |   1 -
 .../src/components/MkImgWithBlurhash.vue      |   2 +-
 packages/client/src/components/MkInfo.vue     |   2 +-
 .../src/components/MkInstanceCardMini.vue     |   4 +-
 .../src/components/MkInstanceSelectDialog.vue |  10 +-
 .../client/src/components/MkInstanceStats.vue |  10 +-
 .../src/components/MkInstanceTicker.vue       |   6 +-
 packages/client/src/components/MkMedia.vue    |   6 +-
 .../client/src/components/MkMediaBanner.vue   |   2 +-
 .../client/src/components/MkMediaList.vue     |   6 +-
 .../client/src/components/MkMenu.child.vue    |   2 +-
 packages/client/src/components/MkMenu.vue     |  29 ++-
 .../client/src/components/MkMiniChart.vue     |  10 +-
 packages/client/src/components/MkModal.vue    |  33 ++-
 .../src/components/MkModalPageWindow.vue      |  20 +-
 .../client/src/components/MkModalWindow.vue   |   8 +-
 packages/client/src/components/MkNote.vue     |  33 ++-
 .../client/src/components/MkNoteDetailed.vue  |  56 ++--
 .../client/src/components/MkNoteHeader.vue    |   3 +-
 .../client/src/components/MkNotePreview.vue   |   4 +-
 .../client/src/components/MkNoteSimple.vue    |   2 +-
 packages/client/src/components/MkNoteSub.vue  |  28 +-
 packages/client/src/components/MkNotes.vue    |   2 +-
 .../client/src/components/MkNotification.vue  |   9 +-
 .../MkNotificationSettingWindow.vue           |   7 +-
 .../src/components/MkNotificationToast.vue    |   2 +-
 .../client/src/components/MkNotifications.vue |   9 +-
 .../client/src/components/MkPageWindow.vue    |  12 +-
 .../client/src/components/MkPagination.vue    |  38 ++-
 packages/client/src/components/MkPoll.vue     |   2 +-
 .../client/src/components/MkPollEditor.vue    |   2 +-
 .../client/src/components/MkPopupMenu.vue     |   6 +-
 packages/client/src/components/MkPostForm.vue |  58 +++--
 .../src/components/MkPostFormAttaches.vue     |   9 +-
 .../src/components/MkPostFormDialog.vue       |   7 +-
 .../MkPushNotificationAllowButton.vue         |  10 +-
 .../client/src/components/MkReactedUsers.vue  |  12 +-
 .../components/MkReactionsViewer.reaction.vue |   2 +-
 .../src/components/MkReactionsViewer.vue      |   2 +-
 .../client/src/components/MkRenoteButton.vue  |  10 +-
 .../src/components/MkShowMoreButton.vue       |   2 +-
 packages/client/src/components/MkSignin.vue   |  24 +-
 .../client/src/components/MkSigninDialog.vue  |   1 -
 packages/client/src/components/MkSignup.vue   |  34 +--
 packages/client/src/components/MkSparkle.vue  |   4 +-
 .../src/components/MkStarButtonNoEmoji.vue    |   2 +-
 .../src/components/MkSubNoteContent.vue       |  24 +-
 packages/client/src/components/MkTagCloud.vue |  14 +-
 packages/client/src/components/MkTimeline.vue |  16 +-
 packages/client/src/components/MkToast.vue    |   2 +-
 .../src/components/MkTokenGenerateWindow.vue  |  11 +-
 .../src/components/MkTutorialDialog.vue       |   2 +-
 packages/client/src/components/MkUpdated.vue  |   6 +-
 .../client/src/components/MkUrlPreview.vue    |  28 +-
 .../src/components/MkUrlPreviewPopup.vue      |   4 +-
 .../client/src/components/MkUserCardMini.vue  |   4 +-
 packages/client/src/components/MkUserInfo.vue |   6 +-
 packages/client/src/components/MkUserList.vue |   3 +-
 .../src/components/MkUserOnlineIndicator.vue  |   2 +-
 .../client/src/components/MkUserPreview.vue   |   8 +-
 .../src/components/MkUserSelectDialog.vue     |  18 +-
 .../components/MkUserSelectLocalDialog.vue    |  16 +-
 .../client/src/components/MkUsersTooltip.vue  |   2 +-
 .../client/src/components/MkVisibility.vue    |   6 +-
 .../src/components/MkVisibilityPicker.vue     |   8 +-
 .../client/src/components/MkWaitingDialog.vue |   2 +-
 packages/client/src/components/MkWidgets.vue  |  12 +-
 packages/client/src/components/MkWindow.vue   |  22 +-
 .../client/src/components/form/checkbox.vue   |   5 +-
 .../client/src/components/global/MkAvatar.vue |   4 +-
 .../src/components/global/MkPageHeader.vue    |   4 +-
 .../components/global/MkStickyContainer.vue   |   4 +-
 .../client/src/components/global/MkTime.vue   |   4 +-
 .../src/components/global/RouterView.vue      |  12 +-
 packages/client/src/components/global/i18n.ts |   2 +-
 packages/client/src/components/index.ts       |   2 +-
 packages/client/src/components/mfm.ts         |   3 +-
 .../client/src/components/page/page.block.vue |   7 +-
 .../src/components/page/page.button.vue       |   7 +-
 .../src/components/page/page.canvas.vue       |   7 +-
 .../src/components/page/page.counter.vue      |   7 +-
 .../client/src/components/page/page.if.vue    |   7 +-
 .../client/src/components/page/page.image.vue |   6 +-
 .../client/src/components/page/page.note.vue  |   5 +-
 .../src/components/page/page.number-input.vue |   7 +-
 .../client/src/components/page/page.post.vue  |   7 +-
 .../src/components/page/page.radio-button.vue |   9 +-
 .../src/components/page/page.section.vue      |   7 +-
 .../src/components/page/page.switch.vue       |   7 +-
 .../src/components/page/page.text-input.vue   |   7 +-
 .../client/src/components/page/page.text.vue  |   7 +-
 .../components/page/page.textarea-input.vue   |   7 +-
 .../src/components/page/page.textarea.vue     |   8 +-
 packages/client/src/components/page/page.vue  |  19 +-
 .../client/src/directives/adaptive-border.ts  |   2 +-
 packages/client/src/directives/anim.ts        |   4 +-
 packages/client/src/directives/appear.ts      |   2 +-
 packages/client/src/directives/click-anime.ts |   2 +-
 .../client/src/directives/follow-append.ts    |   2 +-
 packages/client/src/directives/get-size.ts    |   2 +-
 packages/client/src/directives/hotkey.ts      |   2 +-
 packages/client/src/directives/index.ts       |   2 +-
 packages/client/src/directives/panel.ts       |   2 +-
 packages/client/src/directives/size.ts        |  13 +-
 packages/client/src/directives/tooltip.ts     |   5 +-
 .../client/src/directives/user-preview.ts     |   3 +-
 packages/client/src/filters/user.ts           |   2 +-
 packages/client/src/init.ts                   |  38 +--
 packages/client/src/instance.ts               |   2 +-
 packages/client/src/navbar.ts                 |   2 +-
 packages/client/src/nirax.ts                  |  20 +-
 packages/client/src/os.ts                     |  37 +--
 packages/client/src/pages/_error_.vue         |  11 +-
 packages/client/src/pages/about-firefish.vue  |  12 +-
 packages/client/src/pages/about.emojis.vue    |   3 +-
 .../client/src/pages/about.federation.vue     |   6 +-
 packages/client/src/pages/about.vue           |  24 +-
 packages/client/src/pages/admin-file.vue      |  15 +-
 packages/client/src/pages/admin/_header_.vue  |  16 +-
 packages/client/src/pages/admin/abuses.vue    |  14 +-
 .../client/src/pages/admin/announcements.vue  |   5 +-
 .../client/src/pages/admin/bot-protection.vue |  10 +-
 .../client/src/pages/admin/custom-css.vue     |   4 +-
 packages/client/src/pages/admin/database.vue  |   1 -
 .../client/src/pages/admin/email-settings.vue |  17 +-
 .../src/pages/admin/emoji-edit-dialog.vue     |  14 +-
 packages/client/src/pages/admin/emojis.vue    |  11 +-
 .../client/src/pages/admin/experiments.vue    |  13 +-
 packages/client/src/pages/admin/files.vue     |  14 +-
 packages/client/src/pages/admin/hashtags.vue  |   5 +-
 packages/client/src/pages/admin/index.vue     |  72 ++++--
 .../client/src/pages/admin/instance-block.vue |   9 +-
 .../src/pages/admin/integrations.discord.vue  |   9 +-
 .../src/pages/admin/integrations.github.vue   |   9 +-
 .../client/src/pages/admin/integrations.vue   |   9 +-
 .../client/src/pages/admin/object-storage.vue |  29 +--
 .../client/src/pages/admin/other-settings.vue |   1 -
 .../src/pages/admin/overview.active-users.vue |   8 +-
 .../src/pages/admin/overview.ap-requests.vue  |  11 +-
 .../src/pages/admin/overview.federation.vue   |  17 +-
 .../src/pages/admin/overview.heatmap.vue      |   2 +-
 .../src/pages/admin/overview.instances.vue    |   2 +-
 .../src/pages/admin/overview.metrics.vue      |  20 +-
 .../src/pages/admin/overview.moderators.vue   |  10 +-
 .../client/src/pages/admin/overview.pie.vue   |   4 +-
 .../src/pages/admin/overview.queue-chart.vue  |  22 +-
 .../src/pages/admin/overview.queue.chart.vue  |   6 +-
 .../client/src/pages/admin/overview.queue.vue |  10 +-
 .../client/src/pages/admin/overview.stats.vue |  16 +-
 .../client/src/pages/admin/overview.user.vue  |   4 +-
 .../client/src/pages/admin/overview.users.vue |   6 +-
 packages/client/src/pages/admin/overview.vue  |  32 ++-
 .../client/src/pages/admin/promotions.vue     |   9 +-
 .../client/src/pages/admin/proxy-account.vue  |   7 +-
 .../src/pages/admin/queue.chart.chart.vue     |  24 +-
 .../client/src/pages/admin/queue.chart.vue    |  10 +-
 packages/client/src/pages/admin/queue.vue     |  12 +-
 packages/client/src/pages/admin/relays.vue    |   5 +-
 packages/client/src/pages/admin/security.vue  |  28 +-
 packages/client/src/pages/admin/settings.vue  |  74 +++---
 packages/client/src/pages/admin/users.vue     |  16 +-
 packages/client/src/pages/announcements.vue   |   2 +-
 .../client/src/pages/antenna-timeline.vue     |   8 +-
 packages/client/src/pages/api-console.vue     |   4 +-
 packages/client/src/pages/auth.form.vue       |   1 -
 packages/client/src/pages/auth.vue            |   2 +-
 packages/client/src/pages/channel-editor.vue  |  12 +-
 packages/client/src/pages/channel.vue         |   7 +-
 packages/client/src/pages/channels.vue        |  23 +-
 packages/client/src/pages/clip.vue            |   4 +-
 packages/client/src/pages/drive.vue           |   3 +-
 .../client/src/pages/explore.featured.vue     |   2 +-
 packages/client/src/pages/explore.users.vue   |  12 +-
 packages/client/src/pages/explore.vue         |   6 +-
 packages/client/src/pages/follow-requests.vue |  10 +-
 packages/client/src/pages/gallery/edit.vue    |  14 +-
 packages/client/src/pages/gallery/index.vue   |   8 +-
 packages/client/src/pages/gallery/post.vue    |   6 +-
 packages/client/src/pages/instance-info.vue   |  26 +-
 packages/client/src/pages/messaging/index.vue |  12 +-
 .../pages/messaging/messaging-room.form.vue   |  30 +--
 .../messaging/messaging-room.message.vue      |   1 -
 .../src/pages/messaging/messaging-room.vue    |  37 +--
 packages/client/src/pages/mfm-cheat-sheet.vue |  76 +++---
 packages/client/src/pages/miauth.vue          |   3 +-
 .../client/src/pages/my-antennas/create.vue   |   2 +-
 .../client/src/pages/my-antennas/edit.vue     |   4 +-
 .../client/src/pages/my-antennas/editor.vue   |  32 +--
 .../client/src/pages/my-antennas/index.vue    |   6 +-
 packages/client/src/pages/my-clips/index.vue  |   4 +-
 packages/client/src/pages/my-groups/group.vue |   4 +-
 packages/client/src/pages/my-groups/index.vue |   2 +-
 packages/client/src/pages/my-lists/index.vue  |   5 +-
 packages/client/src/pages/my-lists/list.vue   |  10 +-
 packages/client/src/pages/note.vue            |  22 +-
 packages/client/src/pages/notifications.vue   |   8 +-
 .../page-editor/els/page-editor.el.image.vue  |   2 +-
 .../page-editor/els/page-editor.el.note.vue   |   6 +-
 .../els/page-editor.el.radio-button.vue       |   4 +-
 .../pages/page-editor/page-editor.blocks.vue  |   5 +-
 .../src/pages/page-editor/page-editor.vue     |  44 ++--
 packages/client/src/pages/page.vue            |  10 +-
 packages/client/src/pages/pages.vue           |   6 +-
 packages/client/src/pages/registry.keys.vue   |   4 +-
 packages/client/src/pages/registry.value.vue  |   8 +-
 packages/client/src/pages/registry.vue        |   4 +-
 packages/client/src/pages/reset-password.vue  |   4 +-
 packages/client/src/pages/scratchpad.vue      |   2 +-
 packages/client/src/pages/search.vue          |   6 +-
 packages/client/src/pages/settings/2fa.vue    |   6 +-
 .../src/pages/settings/account-info.vue       |   2 +-
 .../client/src/pages/settings/accounts.vue    |  12 +-
 packages/client/src/pages/settings/api.vue    |   4 +-
 packages/client/src/pages/settings/apps.vue   |   2 +-
 .../client/src/pages/settings/custom-css.vue  |   2 +-
 .../src/pages/settings/custom-katex-macro.vue |   2 +-
 packages/client/src/pages/settings/deck.vue   |   6 +-
 .../src/pages/settings/delete-account.vue     |   2 +-
 packages/client/src/pages/settings/drive.vue  |   5 +-
 packages/client/src/pages/settings/email.vue  |   4 +-
 .../client/src/pages/settings/general.vue     |   2 +-
 .../src/pages/settings/import-export.vue      |   2 +-
 packages/client/src/pages/settings/index.vue  |  21 +-
 .../src/pages/settings/instance-mute.vue      |   4 +-
 .../client/src/pages/settings/migration.vue   |   6 +-
 .../client/src/pages/settings/mute-block.vue  |   6 +-
 packages/client/src/pages/settings/navbar.vue |   2 +-
 .../src/pages/settings/notifications.vue      |   9 +-
 packages/client/src/pages/settings/other.vue  |   4 +-
 .../src/pages/settings/plugin.install.vue     |   8 +-
 packages/client/src/pages/settings/plugin.vue |   2 +-
 .../pages/settings/preferences-backups.vue    |  12 +-
 .../client/src/pages/settings/privacy.vue     |  29 +--
 .../client/src/pages/settings/profile.vue     |   4 +-
 .../client/src/pages/settings/reaction.vue    |   6 +-
 .../client/src/pages/settings/security.vue    |   2 +-
 .../pages/settings/statusbar.statusbar.vue    |   3 +-
 .../client/src/pages/settings/statusbar.vue   |   6 +-
 .../src/pages/settings/theme.install.vue      |   5 +-
 .../src/pages/settings/theme.manage.vue       |   3 +-
 .../src/pages/settings/webhook.edit.vue       |  25 +-
 .../client/src/pages/settings/webhook.new.vue |  23 +-
 .../client/src/pages/settings/webhook.vue     |   4 -
 .../client/src/pages/settings/word-mute.vue   |   4 +-
 packages/client/src/pages/share.vue           |  35 ++-
 packages/client/src/pages/signup-complete.vue |   2 +-
 packages/client/src/pages/tag.vue             |   6 +-
 packages/client/src/pages/theme-editor.vue    |  13 +-
 packages/client/src/pages/timeline.vue        |   8 +-
 packages/client/src/pages/user-info.vue       |  35 ++-
 .../client/src/pages/user-list-timeline.vue   |   8 +-
 packages/client/src/pages/user/clips.vue      |   2 +-
 .../client/src/pages/user/follow-list.vue     |   2 +-
 packages/client/src/pages/user/followers.vue  |   8 +-
 packages/client/src/pages/user/following.vue  |   8 +-
 packages/client/src/pages/user/gallery.vue    |   2 +-
 packages/client/src/pages/user/home.vue       |  26 +-
 .../client/src/pages/user/index.activity.vue  |   7 +-
 .../client/src/pages/user/index.photos.vue    |   6 +-
 .../client/src/pages/user/index.timeline.vue  |   5 +-
 packages/client/src/pages/user/index.vue      |  13 +-
 packages/client/src/pages/user/pages.vue      |   2 +-
 packages/client/src/pages/user/reactions.vue  |   2 +-
 packages/client/src/pages/verify-email.vue    |   2 +-
 .../client/src/pages/welcome.entrance.a.vue   |  18 +-
 .../client/src/pages/welcome.entrance.b.vue   |   2 +-
 packages/client/src/pages/welcome.setup.vue   |   7 +-
 .../client/src/pages/welcome.timeline.vue     |  10 +-
 packages/client/src/pages/welcome.vue         |   2 +-
 packages/client/src/pizzax.ts                 |   8 +-
 packages/client/src/plugin.ts                 |  16 +-
 packages/client/src/router.ts                 |   6 +-
 packages/client/src/scripts/array.ts          |   2 +-
 packages/client/src/scripts/autocomplete.ts   |  14 +-
 packages/client/src/scripts/chart-vline.ts    |   2 +-
 .../client/src/scripts/check-word-mute.ts     |  12 +-
 packages/client/src/scripts/emojilist.ts      |   4 +-
 packages/client/src/scripts/extract-mfm.ts    |   2 +-
 .../client/src/scripts/format-time-string.ts  |   4 +-
 .../client/src/scripts/gen-search-query.ts    |   7 +-
 packages/client/src/scripts/get-note-menu.ts  |   7 +-
 .../client/src/scripts/get-note-summary.ts    |   3 +-
 packages/client/src/scripts/get-user-menu.ts  |   8 +-
 packages/client/src/scripts/helpMenu.ts       |   2 +-
 packages/client/src/scripts/hotkey.ts         |  10 +-
 packages/client/src/scripts/hpml/block.ts     |   4 +-
 packages/client/src/scripts/hpml/evaluator.ts |  17 +-
 packages/client/src/scripts/hpml/expr.ts      |  11 +-
 packages/client/src/scripts/hpml/index.ts     |  18 +-
 packages/client/src/scripts/hpml/lib.ts       |   9 +-
 .../client/src/scripts/hpml/type-checker.ts   |  10 +-
 packages/client/src/scripts/i18n.ts           |   4 +-
 packages/client/src/scripts/idb-proxy.ts      |   2 +-
 packages/client/src/scripts/init-chart.ts     |  20 +-
 packages/client/src/scripts/katex-macro.ts    |  54 ++--
 packages/client/src/scripts/page-metadata.ts  |  18 +-
 packages/client/src/scripts/physics.ts        |  18 +-
 packages/client/src/scripts/popout.ts         |   2 +-
 packages/client/src/scripts/popup-position.ts |  14 +-
 packages/client/src/scripts/preprocess.ts     |  10 +-
 .../client/src/scripts/reaction-picker.ts     |   3 +-
 packages/client/src/scripts/search.ts         |   2 +-
 packages/client/src/scripts/select-file.ts    |   4 +-
 packages/client/src/scripts/shuffle.ts        |   4 +-
 packages/client/src/scripts/theme-editor.ts   |  27 +-
 packages/client/src/scripts/theme.ts          |   6 +-
 packages/client/src/scripts/upload.ts         |   8 +-
 .../client/src/scripts/use-chart-tooltip.ts   |   2 +-
 .../client/src/scripts/use-leave-guard.ts     |   4 +-
 .../client/src/scripts/use-note-capture.ts    |   5 +-
 packages/client/src/scripts/use-tooltip.ts    |  32 ++-
 packages/client/src/store.ts                  |   5 +-
 packages/client/src/theme-store.ts            |   2 +-
 packages/client/src/types/menu.ts             |  36 +--
 packages/client/src/ui/_common_/common.vue    |   4 +-
 .../src/ui/_common_/navbar-for-mobile.vue     |  11 +-
 packages/client/src/ui/_common_/navbar.vue    |  12 +-
 .../src/ui/_common_/statusbar-federation.vue  |   8 +-
 .../client/src/ui/_common_/statusbar-rss.vue  |   5 +-
 .../src/ui/_common_/statusbar-user-list.vue   |   6 +-
 .../client/src/ui/_common_/statusbars.vue     |   3 +-
 .../src/ui/_common_/stream-indicator.vue      |   2 +-
 packages/client/src/ui/_common_/sw-inject.ts  |   3 -
 packages/client/src/ui/deck.vue               |  10 +-
 .../client/src/ui/deck/channel-column.vue     |   1 -
 packages/client/src/ui/deck/column.vue        |  17 +-
 packages/client/src/ui/deck/deck-store.ts     |  22 +-
 packages/client/src/ui/deck/list-column.vue   |   1 -
 packages/client/src/ui/deck/main-column.vue   |   7 +-
 packages/client/src/ui/deck/tl-column.vue     |   6 +-
 .../client/src/ui/deck/widgets-column.vue     |   3 +-
 packages/client/src/ui/universal.vue          |   7 +-
 packages/client/src/ui/visitor.vue            |   3 +-
 packages/client/src/ui/visitor/a.vue          |   2 +-
 packages/client/src/ui/visitor/b.vue          |  19 +-
 packages/client/src/ui/visitor/kanban.vue     |   2 +-
 packages/client/src/ui/zen.vue                |   7 +-
 .../client/src/widgets/activity.chart.vue     |  12 +-
 packages/client/src/widgets/activity.vue      |   8 +-
 packages/client/src/widgets/aiscript.vue      |   8 +-
 packages/client/src/widgets/button.vue        |   9 +-
 packages/client/src/widgets/calendar.vue      |  10 +-
 packages/client/src/widgets/clock.vue         |   7 +-
 packages/client/src/widgets/digital-clock.vue |   8 +-
 packages/client/src/widgets/federation.vue    |   8 +-
 packages/client/src/widgets/index.ts          |   3 +-
 .../client/src/widgets/instance-cloud.vue     |   9 +-
 packages/client/src/widgets/job-queue.vue     |   9 +-
 packages/client/src/widgets/memo.vue          |   9 +-
 packages/client/src/widgets/notifications.vue |   6 +-
 packages/client/src/widgets/online-users.vue  |   8 +-
 packages/client/src/widgets/photos.vue        |   8 +-
 packages/client/src/widgets/post-form.vue     |   6 +-
 packages/client/src/widgets/rss-ticker.vue    |  11 +-
 packages/client/src/widgets/rss.vue           |   9 +-
 packages/client/src/widgets/server-info.vue   |   6 +-
 .../src/widgets/server-metric/cpu-mem.vue     |  20 +-
 .../client/src/widgets/server-metric/cpu.vue  |   2 +-
 .../client/src/widgets/server-metric/disk.vue |   1 -
 .../src/widgets/server-metric/index.vue       |   8 +-
 .../src/widgets/server-metric/meilisearch.vue |  10 +-
 .../client/src/widgets/server-metric/mem.vue  |   8 +-
 .../client/src/widgets/server-metric/net.vue  |  20 +-
 .../client/src/widgets/server-metric/pie.vue  |   2 -
 packages/client/src/widgets/slideshow.vue     |   8 +-
 packages/client/src/widgets/timeline.vue      |   9 +-
 packages/client/src/widgets/trends.vue        |   8 +-
 packages/client/src/widgets/unix-clock.vue    |   6 +-
 packages/client/src/widgets/user-list.vue     |  39 +--
 packages/client/src/widgets/widget.ts         |  18 +-
 packages/client/tsconfig.json                 |  21 +-
 packages/client/vite.config.ts                |  20 +-
 packages/client/vite.json5.ts                 |   4 +-
 pnpm-lock.yaml                                | 212 ++++++++++++---
 398 files changed, 2512 insertions(+), 2072 deletions(-)
 create mode 100644 packages/client/.eslintrc-auto-import.json
 create mode 100644 packages/client/auto-imports.d.ts
 create mode 100644 packages/client/components.d.ts

diff --git a/packages/client/.eslintrc-auto-import.json b/packages/client/.eslintrc-auto-import.json
new file mode 100644
index 0000000000..bd42a11385
--- /dev/null
+++ b/packages/client/.eslintrc-auto-import.json
@@ -0,0 +1,63 @@
+{
+  "globals": {
+    "Component": true,
+    "ComponentPublicInstance": true,
+    "ComputedRef": true,
+    "EffectScope": true,
+    "InjectionKey": true,
+    "PropType": true,
+    "Ref": true,
+    "VNode": true,
+    "computed": true,
+    "createApp": true,
+    "customRef": true,
+    "defineAsyncComponent": true,
+    "defineComponent": true,
+    "effectScope": true,
+    "getCurrentInstance": true,
+    "getCurrentScope": true,
+    "h": true,
+    "inject": true,
+    "isProxy": true,
+    "isReactive": true,
+    "isReadonly": true,
+    "isRef": true,
+    "markRaw": true,
+    "nextTick": true,
+    "onActivated": true,
+    "onBeforeMount": true,
+    "onBeforeUnmount": true,
+    "onBeforeUpdate": true,
+    "onDeactivated": true,
+    "onErrorCaptured": true,
+    "onMounted": true,
+    "onRenderTracked": true,
+    "onRenderTriggered": true,
+    "onScopeDispose": true,
+    "onServerPrefetch": true,
+    "onUnmounted": true,
+    "onUpdated": true,
+    "provide": true,
+    "reactive": true,
+    "readonly": true,
+    "ref": true,
+    "resolveComponent": true,
+    "shallowReactive": true,
+    "shallowReadonly": true,
+    "shallowRef": true,
+    "toRaw": true,
+    "toRef": true,
+    "toRefs": true,
+    "toValue": true,
+    "triggerRef": true,
+    "unref": true,
+    "useAttrs": true,
+    "useCssModule": true,
+    "useCssVars": true,
+    "useSlots": true,
+    "watch": true,
+    "watchEffect": true,
+    "watchPostEffect": true,
+    "watchSyncEffect": true
+  }
+}
diff --git a/packages/client/.eslintrc.json b/packages/client/.eslintrc.json
index fd4718003d..104cfec8f4 100644
--- a/packages/client/.eslintrc.json
+++ b/packages/client/.eslintrc.json
@@ -1,7 +1,18 @@
 {
-  "extends": ["@eslint-sets/vue3", "@eslint-sets/vue3-ts"],
-	"plugins": ["file-progress", "prettier"],
+	"extends": [
+		"@eslint-sets/vue3",
+		"@eslint-sets/vue3-ts",
+		"./.eslintrc-auto-import.json"
+	],
+	"plugins": [
+		"file-progress",
+		"prettier",
+		"unused-imports",
+		"eslint-plugin-unused-imports"
+	],
 	"rules": {
-		"file-progress/activate": 1
+		"file-progress/activate": 1,
+		"no-unused-vars": "off",
+		"unused-imports/no-unused-imports": "error"
 	}
 }
diff --git a/packages/client/@types/theme.d.ts b/packages/client/@types/theme.d.ts
index 5f1b81603d..4cfefc55a4 100644
--- a/packages/client/@types/theme.d.ts
+++ b/packages/client/@types/theme.d.ts
@@ -1,5 +1,5 @@
 declare module "@/themes/*.json5" {
-	import { Theme } from "@/scripts/theme";
+	import type { Theme } from "@/scripts/theme";
 
 	const theme: Theme;
 
diff --git a/packages/client/assets/label-red.svg b/packages/client/assets/label-red.svg
index bf1e9cedbc..3c564f4cf2 100644
--- a/packages/client/assets/label-red.svg
+++ b/packages/client/assets/label-red.svg
@@ -1 +1,3 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96"><path fill="#eb6f92" d="M0 45.255 45.254 0h39.6L0 84.854z"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96">
+	<path fill="#eb6f92" d="M0 45.255 45.254 0h39.6L0 84.854z" />
+</svg>;
diff --git a/packages/client/assets/label.svg b/packages/client/assets/label.svg
index 976bf410f9..ff1c514a55 100644
--- a/packages/client/assets/label.svg
+++ b/packages/client/assets/label.svg
@@ -1 +1,3 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96"><path fill="#31748f" d="M0 45.255 45.254 0h39.6L0 84.854z"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96">
+	<path fill="#31748f" d="M0 45.255 45.254 0h39.6L0 84.854z" />
+</svg>;
diff --git a/packages/client/auto-imports.d.ts b/packages/client/auto-imports.d.ts
new file mode 100644
index 0000000000..c3caf0052a
--- /dev/null
+++ b/packages/client/auto-imports.d.ts
@@ -0,0 +1,243 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// noinspection JSUnusedGlobalSymbols
+// Generated by unplugin-auto-import
+export {};
+declare global {
+	const EffectScope: typeof import("vue")["EffectScope"];
+	const computed: typeof import("vue")["computed"];
+	const createApp: typeof import("vue")["createApp"];
+	const customRef: typeof import("vue")["customRef"];
+	const defineAsyncComponent: typeof import("vue")["defineAsyncComponent"];
+	const defineComponent: typeof import("vue")["defineComponent"];
+	const effectScope: typeof import("vue")["effectScope"];
+	const getCurrentInstance: typeof import("vue")["getCurrentInstance"];
+	const getCurrentScope: typeof import("vue")["getCurrentScope"];
+	const h: typeof import("vue")["h"];
+	const inject: typeof import("vue")["inject"];
+	const isProxy: typeof import("vue")["isProxy"];
+	const isReactive: typeof import("vue")["isReactive"];
+	const isReadonly: typeof import("vue")["isReadonly"];
+	const isRef: typeof import("vue")["isRef"];
+	const markRaw: typeof import("vue")["markRaw"];
+	const nextTick: typeof import("vue")["nextTick"];
+	const onActivated: typeof import("vue")["onActivated"];
+	const onBeforeMount: typeof import("vue")["onBeforeMount"];
+	const onBeforeUnmount: typeof import("vue")["onBeforeUnmount"];
+	const onBeforeUpdate: typeof import("vue")["onBeforeUpdate"];
+	const onDeactivated: typeof import("vue")["onDeactivated"];
+	const onErrorCaptured: typeof import("vue")["onErrorCaptured"];
+	const onMounted: typeof import("vue")["onMounted"];
+	const onRenderTracked: typeof import("vue")["onRenderTracked"];
+	const onRenderTriggered: typeof import("vue")["onRenderTriggered"];
+	const onScopeDispose: typeof import("vue")["onScopeDispose"];
+	const onServerPrefetch: typeof import("vue")["onServerPrefetch"];
+	const onUnmounted: typeof import("vue")["onUnmounted"];
+	const onUpdated: typeof import("vue")["onUpdated"];
+	const provide: typeof import("vue")["provide"];
+	const reactive: typeof import("vue")["reactive"];
+	const readonly: typeof import("vue")["readonly"];
+	const ref: typeof import("vue")["ref"];
+	const resolveComponent: typeof import("vue")["resolveComponent"];
+	const shallowReactive: typeof import("vue")["shallowReactive"];
+	const shallowReadonly: typeof import("vue")["shallowReadonly"];
+	const shallowRef: typeof import("vue")["shallowRef"];
+	const toRaw: typeof import("vue")["toRaw"];
+	const toRef: typeof import("vue")["toRef"];
+	const toRefs: typeof import("vue")["toRefs"];
+	const toValue: typeof import("vue")["toValue"];
+	const triggerRef: typeof import("vue")["triggerRef"];
+	const unref: typeof import("vue")["unref"];
+	const useAttrs: typeof import("vue")["useAttrs"];
+	const useCssModule: typeof import("vue")["useCssModule"];
+	const useCssVars: typeof import("vue")["useCssVars"];
+	const useSlots: typeof import("vue")["useSlots"];
+	const watch: typeof import("vue")["watch"];
+	const watchEffect: typeof import("vue")["watchEffect"];
+	const watchPostEffect: typeof import("vue")["watchPostEffect"];
+	const watchSyncEffect: typeof import("vue")["watchSyncEffect"];
+}
+// for type re-export
+declare global {
+	// @ts-ignore
+	export type {
+		Component,
+		ComponentPublicInstance,
+		ComputedRef,
+		InjectionKey,
+		PropType,
+		Ref,
+		VNode,
+	} from "vue";
+}
+// for vue template auto import
+import { UnwrapRef } from "vue";
+declare module "vue" {
+	interface ComponentCustomProperties {
+		readonly EffectScope: UnwrapRef<typeof import("vue")["EffectScope"]>;
+		readonly computed: UnwrapRef<typeof import("vue")["computed"]>;
+		readonly createApp: UnwrapRef<typeof import("vue")["createApp"]>;
+		readonly customRef: UnwrapRef<typeof import("vue")["customRef"]>;
+		readonly defineAsyncComponent: UnwrapRef<
+			typeof import("vue")["defineAsyncComponent"]
+		>;
+		readonly defineComponent: UnwrapRef<
+			typeof import("vue")["defineComponent"]
+		>;
+		readonly effectScope: UnwrapRef<typeof import("vue")["effectScope"]>;
+		readonly getCurrentInstance: UnwrapRef<
+			typeof import("vue")["getCurrentInstance"]
+		>;
+		readonly getCurrentScope: UnwrapRef<
+			typeof import("vue")["getCurrentScope"]
+		>;
+		readonly h: UnwrapRef<typeof import("vue")["h"]>;
+		readonly inject: UnwrapRef<typeof import("vue")["inject"]>;
+		readonly isProxy: UnwrapRef<typeof import("vue")["isProxy"]>;
+		readonly isReactive: UnwrapRef<typeof import("vue")["isReactive"]>;
+		readonly isReadonly: UnwrapRef<typeof import("vue")["isReadonly"]>;
+		readonly isRef: UnwrapRef<typeof import("vue")["isRef"]>;
+		readonly markRaw: UnwrapRef<typeof import("vue")["markRaw"]>;
+		readonly nextTick: UnwrapRef<typeof import("vue")["nextTick"]>;
+		readonly onActivated: UnwrapRef<typeof import("vue")["onActivated"]>;
+		readonly onBeforeMount: UnwrapRef<typeof import("vue")["onBeforeMount"]>;
+		readonly onBeforeUnmount: UnwrapRef<
+			typeof import("vue")["onBeforeUnmount"]
+		>;
+		readonly onBeforeUpdate: UnwrapRef<typeof import("vue")["onBeforeUpdate"]>;
+		readonly onDeactivated: UnwrapRef<typeof import("vue")["onDeactivated"]>;
+		readonly onErrorCaptured: UnwrapRef<
+			typeof import("vue")["onErrorCaptured"]
+		>;
+		readonly onMounted: UnwrapRef<typeof import("vue")["onMounted"]>;
+		readonly onRenderTracked: UnwrapRef<
+			typeof import("vue")["onRenderTracked"]
+		>;
+		readonly onRenderTriggered: UnwrapRef<
+			typeof import("vue")["onRenderTriggered"]
+		>;
+		readonly onScopeDispose: UnwrapRef<typeof import("vue")["onScopeDispose"]>;
+		readonly onServerPrefetch: UnwrapRef<
+			typeof import("vue")["onServerPrefetch"]
+		>;
+		readonly onUnmounted: UnwrapRef<typeof import("vue")["onUnmounted"]>;
+		readonly onUpdated: UnwrapRef<typeof import("vue")["onUpdated"]>;
+		readonly provide: UnwrapRef<typeof import("vue")["provide"]>;
+		readonly reactive: UnwrapRef<typeof import("vue")["reactive"]>;
+		readonly readonly: UnwrapRef<typeof import("vue")["readonly"]>;
+		readonly ref: UnwrapRef<typeof import("vue")["ref"]>;
+		readonly resolveComponent: UnwrapRef<
+			typeof import("vue")["resolveComponent"]
+		>;
+		readonly shallowReactive: UnwrapRef<
+			typeof import("vue")["shallowReactive"]
+		>;
+		readonly shallowReadonly: UnwrapRef<
+			typeof import("vue")["shallowReadonly"]
+		>;
+		readonly shallowRef: UnwrapRef<typeof import("vue")["shallowRef"]>;
+		readonly toRaw: UnwrapRef<typeof import("vue")["toRaw"]>;
+		readonly toRef: UnwrapRef<typeof import("vue")["toRef"]>;
+		readonly toRefs: UnwrapRef<typeof import("vue")["toRefs"]>;
+		readonly toValue: UnwrapRef<typeof import("vue")["toValue"]>;
+		readonly triggerRef: UnwrapRef<typeof import("vue")["triggerRef"]>;
+		readonly unref: UnwrapRef<typeof import("vue")["unref"]>;
+		readonly useAttrs: UnwrapRef<typeof import("vue")["useAttrs"]>;
+		readonly useCssModule: UnwrapRef<typeof import("vue")["useCssModule"]>;
+		readonly useCssVars: UnwrapRef<typeof import("vue")["useCssVars"]>;
+		readonly useSlots: UnwrapRef<typeof import("vue")["useSlots"]>;
+		readonly watch: UnwrapRef<typeof import("vue")["watch"]>;
+		readonly watchEffect: UnwrapRef<typeof import("vue")["watchEffect"]>;
+		readonly watchPostEffect: UnwrapRef<
+			typeof import("vue")["watchPostEffect"]
+		>;
+		readonly watchSyncEffect: UnwrapRef<
+			typeof import("vue")["watchSyncEffect"]
+		>;
+	}
+}
+declare module "@vue/runtime-core" {
+	interface ComponentCustomProperties {
+		readonly EffectScope: UnwrapRef<typeof import("vue")["EffectScope"]>;
+		readonly computed: UnwrapRef<typeof import("vue")["computed"]>;
+		readonly createApp: UnwrapRef<typeof import("vue")["createApp"]>;
+		readonly customRef: UnwrapRef<typeof import("vue")["customRef"]>;
+		readonly defineAsyncComponent: UnwrapRef<
+			typeof import("vue")["defineAsyncComponent"]
+		>;
+		readonly defineComponent: UnwrapRef<
+			typeof import("vue")["defineComponent"]
+		>;
+		readonly effectScope: UnwrapRef<typeof import("vue")["effectScope"]>;
+		readonly getCurrentInstance: UnwrapRef<
+			typeof import("vue")["getCurrentInstance"]
+		>;
+		readonly getCurrentScope: UnwrapRef<
+			typeof import("vue")["getCurrentScope"]
+		>;
+		readonly h: UnwrapRef<typeof import("vue")["h"]>;
+		readonly inject: UnwrapRef<typeof import("vue")["inject"]>;
+		readonly isProxy: UnwrapRef<typeof import("vue")["isProxy"]>;
+		readonly isReactive: UnwrapRef<typeof import("vue")["isReactive"]>;
+		readonly isReadonly: UnwrapRef<typeof import("vue")["isReadonly"]>;
+		readonly isRef: UnwrapRef<typeof import("vue")["isRef"]>;
+		readonly markRaw: UnwrapRef<typeof import("vue")["markRaw"]>;
+		readonly nextTick: UnwrapRef<typeof import("vue")["nextTick"]>;
+		readonly onActivated: UnwrapRef<typeof import("vue")["onActivated"]>;
+		readonly onBeforeMount: UnwrapRef<typeof import("vue")["onBeforeMount"]>;
+		readonly onBeforeUnmount: UnwrapRef<
+			typeof import("vue")["onBeforeUnmount"]
+		>;
+		readonly onBeforeUpdate: UnwrapRef<typeof import("vue")["onBeforeUpdate"]>;
+		readonly onDeactivated: UnwrapRef<typeof import("vue")["onDeactivated"]>;
+		readonly onErrorCaptured: UnwrapRef<
+			typeof import("vue")["onErrorCaptured"]
+		>;
+		readonly onMounted: UnwrapRef<typeof import("vue")["onMounted"]>;
+		readonly onRenderTracked: UnwrapRef<
+			typeof import("vue")["onRenderTracked"]
+		>;
+		readonly onRenderTriggered: UnwrapRef<
+			typeof import("vue")["onRenderTriggered"]
+		>;
+		readonly onScopeDispose: UnwrapRef<typeof import("vue")["onScopeDispose"]>;
+		readonly onServerPrefetch: UnwrapRef<
+			typeof import("vue")["onServerPrefetch"]
+		>;
+		readonly onUnmounted: UnwrapRef<typeof import("vue")["onUnmounted"]>;
+		readonly onUpdated: UnwrapRef<typeof import("vue")["onUpdated"]>;
+		readonly provide: UnwrapRef<typeof import("vue")["provide"]>;
+		readonly reactive: UnwrapRef<typeof import("vue")["reactive"]>;
+		readonly readonly: UnwrapRef<typeof import("vue")["readonly"]>;
+		readonly ref: UnwrapRef<typeof import("vue")["ref"]>;
+		readonly resolveComponent: UnwrapRef<
+			typeof import("vue")["resolveComponent"]
+		>;
+		readonly shallowReactive: UnwrapRef<
+			typeof import("vue")["shallowReactive"]
+		>;
+		readonly shallowReadonly: UnwrapRef<
+			typeof import("vue")["shallowReadonly"]
+		>;
+		readonly shallowRef: UnwrapRef<typeof import("vue")["shallowRef"]>;
+		readonly toRaw: UnwrapRef<typeof import("vue")["toRaw"]>;
+		readonly toRef: UnwrapRef<typeof import("vue")["toRef"]>;
+		readonly toRefs: UnwrapRef<typeof import("vue")["toRefs"]>;
+		readonly toValue: UnwrapRef<typeof import("vue")["toValue"]>;
+		readonly triggerRef: UnwrapRef<typeof import("vue")["triggerRef"]>;
+		readonly unref: UnwrapRef<typeof import("vue")["unref"]>;
+		readonly useAttrs: UnwrapRef<typeof import("vue")["useAttrs"]>;
+		readonly useCssModule: UnwrapRef<typeof import("vue")["useCssModule"]>;
+		readonly useCssVars: UnwrapRef<typeof import("vue")["useCssVars"]>;
+		readonly useSlots: UnwrapRef<typeof import("vue")["useSlots"]>;
+		readonly watch: UnwrapRef<typeof import("vue")["watch"]>;
+		readonly watchEffect: UnwrapRef<typeof import("vue")["watchEffect"]>;
+		readonly watchPostEffect: UnwrapRef<
+			typeof import("vue")["watchPostEffect"]
+		>;
+		readonly watchSyncEffect: UnwrapRef<
+			typeof import("vue")["watchSyncEffect"]
+		>;
+	}
+}
diff --git a/packages/client/components.d.ts b/packages/client/components.d.ts
new file mode 100644
index 0000000000..34984580b0
--- /dev/null
+++ b/packages/client/components.d.ts
@@ -0,0 +1,198 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// Generated by unplugin-vue-components
+// Read more: https://github.com/vuejs/core/pull/3399
+export {};
+
+declare module "vue" {
+	export interface GlobalComponents {
+		Checkbox: typeof import("./src/components/form/checkbox.vue")["default"];
+		Folder: typeof import("./src/components/form/folder.vue")["default"];
+		Input: typeof import("./src/components/form/input.vue")["default"];
+		Link: typeof import("./src/components/form/link.vue")["default"];
+		MkA: typeof import("./src/components/global/MkA.vue")["default"];
+		MkAbuseReport: typeof import("./src/components/MkAbuseReport.vue")["default"];
+		MkAbuseReportWindow: typeof import("./src/components/MkAbuseReportWindow.vue")["default"];
+		MkAcct: typeof import("./src/components/global/MkAcct.vue")["default"];
+		MkAd: typeof import("./src/components/global/MkAd.vue")["default"];
+		MkAnalogClock: typeof import("./src/components/MkAnalogClock.vue")["default"];
+		MkAnnouncement: typeof import("./src/components/MkAnnouncement.vue")["default"];
+		MkAutocomplete: typeof import("./src/components/MkAutocomplete.vue")["default"];
+		MkAvatar: typeof import("./src/components/global/MkAvatar.vue")["default"];
+		MkAvatars: typeof import("./src/components/MkAvatars.vue")["default"];
+		MkButton: typeof import("./src/components/MkButton.vue")["default"];
+		MkCaptcha: typeof import("./src/components/MkCaptcha.vue")["default"];
+		MkChannelFollowButton: typeof import("./src/components/MkChannelFollowButton.vue")["default"];
+		MkChannelList: typeof import("./src/components/MkChannelList.vue")["default"];
+		MkChannelPreview: typeof import("./src/components/MkChannelPreview.vue")["default"];
+		MkChart: typeof import("./src/components/MkChart.vue")["default"];
+		MkChartTooltip: typeof import("./src/components/MkChartTooltip.vue")["default"];
+		MkChatPreview: typeof import("./src/components/MkChatPreview.vue")["default"];
+		MkCheatSheetDialog: typeof import("./src/components/MkCheatSheetDialog.vue")["default"];
+		MkCode: typeof import("./src/components/MkCode.vue")["default"];
+		"MkCode.core": typeof import("./src/components/MkCode.core.vue")["default"];
+		MkContainer: typeof import("./src/components/MkContainer.vue")["default"];
+		MkContextMenu: typeof import("./src/components/MkContextMenu.vue")["default"];
+		MkCropperDialog: typeof import("./src/components/MkCropperDialog.vue")["default"];
+		MkCwButton: typeof import("./src/components/MkCwButton.vue")["default"];
+		MkDateSeparatedList: typeof import("./src/components/MkDateSeparatedList.vue")["default"];
+		MkDialog: typeof import("./src/components/MkDialog.vue")["default"];
+		MkDigitalClock: typeof import("./src/components/MkDigitalClock.vue")["default"];
+		MkDonation: typeof import("./src/components/MkDonation.vue")["default"];
+		MkDrive: typeof import("./src/components/MkDrive.vue")["default"];
+		"MkDrive.file": typeof import("./src/components/MkDrive.file.vue")["default"];
+		"MkDrive.folder": typeof import("./src/components/MkDrive.folder.vue")["default"];
+		"MkDrive.navFolder": typeof import("./src/components/MkDrive.navFolder.vue")["default"];
+		MkDriveFileThumbnail: typeof import("./src/components/MkDriveFileThumbnail.vue")["default"];
+		MkDriveSelectDialog: typeof import("./src/components/MkDriveSelectDialog.vue")["default"];
+		MkDriveWindow: typeof import("./src/components/MkDriveWindow.vue")["default"];
+		MkEllipsis: typeof import("./src/components/global/MkEllipsis.vue")["default"];
+		MkEmoji: typeof import("./src/components/global/MkEmoji.vue")["default"];
+		MkEmojiPicker: typeof import("./src/components/MkEmojiPicker.vue")["default"];
+		"MkEmojiPicker.section": typeof import("./src/components/MkEmojiPicker.section.vue")["default"];
+		MkEmojiPickerDialog: typeof import("./src/components/MkEmojiPickerDialog.vue")["default"];
+		MkError: typeof import("./src/components/global/MkError.vue")["default"];
+		MkFeaturedPhotos: typeof import("./src/components/MkFeaturedPhotos.vue")["default"];
+		MkFileListForAdmin: typeof import("./src/components/MkFileListForAdmin.vue")["default"];
+		MkFileTypeIcon: typeof import("./src/components/MkFileTypeIcon.vue")["default"];
+		MkFolder: typeof import("./src/components/MkFolder.vue")["default"];
+		MkFollowButton: typeof import("./src/components/MkFollowButton.vue")["default"];
+		MkForgotPassword: typeof import("./src/components/MkForgotPassword.vue")["default"];
+		MkFormDialog: typeof import("./src/components/MkFormDialog.vue")["default"];
+		MkFormula: typeof import("./src/components/MkFormula.vue")["default"];
+		MkFormulaCore: typeof import("./src/components/MkFormulaCore.vue")["default"];
+		MkGalleryPostPreview: typeof import("./src/components/MkGalleryPostPreview.vue")["default"];
+		MkGoogle: typeof import("./src/components/MkGoogle.vue")["default"];
+		MkHeatmap: typeof import("./src/components/MkHeatmap.vue")["default"];
+		MkImageViewer: typeof import("./src/components/MkImageViewer.vue")["default"];
+		MkImgWithBlurhash: typeof import("./src/components/MkImgWithBlurhash.vue")["default"];
+		MkInfo: typeof import("./src/components/MkInfo.vue")["default"];
+		MkInstanceCardMini: typeof import("./src/components/MkInstanceCardMini.vue")["default"];
+		MkInstanceSelectDialog: typeof import("./src/components/MkInstanceSelectDialog.vue")["default"];
+		MkInstanceStats: typeof import("./src/components/MkInstanceStats.vue")["default"];
+		MkInstanceTicker: typeof import("./src/components/MkInstanceTicker.vue")["default"];
+		MkKeyValue: typeof import("./src/components/MkKeyValue.vue")["default"];
+		MkLaunchPad: typeof import("./src/components/MkLaunchPad.vue")["default"];
+		MkLink: typeof import("./src/components/MkLink.vue")["default"];
+		MkLoading: typeof import("./src/components/global/MkLoading.vue")["default"];
+		MkManyAnnouncements: typeof import("./src/components/MkManyAnnouncements.vue")["default"];
+		MkMarquee: typeof import("./src/components/MkMarquee.vue")["default"];
+		MkMedia: typeof import("./src/components/MkMedia.vue")["default"];
+		MkMediaBanner: typeof import("./src/components/MkMediaBanner.vue")["default"];
+		MkMediaCaption: typeof import("./src/components/MkMediaCaption.vue")["default"];
+		MkMediaList: typeof import("./src/components/MkMediaList.vue")["default"];
+		MkMention: typeof import("./src/components/MkMention.vue")["default"];
+		MkMenu: typeof import("./src/components/MkMenu.vue")["default"];
+		"MkMenu.child": typeof import("./src/components/MkMenu.child.vue")["default"];
+		MkMiniChart: typeof import("./src/components/MkMiniChart.vue")["default"];
+		MkMisskeyFlavoredMarkdown: typeof import("./src/components/global/MkMisskeyFlavoredMarkdown.vue")["default"];
+		MkModal: typeof import("./src/components/MkModal.vue")["default"];
+		MkModalPageWindow: typeof import("./src/components/MkModalPageWindow.vue")["default"];
+		MkModalWindow: typeof import("./src/components/MkModalWindow.vue")["default"];
+		MkMoved: typeof import("./src/components/MkMoved.vue")["default"];
+		MkNote: typeof import("./src/components/MkNote.vue")["default"];
+		MkNoteDetailed: typeof import("./src/components/MkNoteDetailed.vue")["default"];
+		MkNoteHeader: typeof import("./src/components/MkNoteHeader.vue")["default"];
+		MkNotePreview: typeof import("./src/components/MkNotePreview.vue")["default"];
+		MkNotes: typeof import("./src/components/MkNotes.vue")["default"];
+		MkNoteSimple: typeof import("./src/components/MkNoteSimple.vue")["default"];
+		MkNoteSub: typeof import("./src/components/MkNoteSub.vue")["default"];
+		MkNotification: typeof import("./src/components/MkNotification.vue")["default"];
+		MkNotifications: typeof import("./src/components/MkNotifications.vue")["default"];
+		MkNotificationSettingWindow: typeof import("./src/components/MkNotificationSettingWindow.vue")["default"];
+		MkNotificationToast: typeof import("./src/components/MkNotificationToast.vue")["default"];
+		MkNumber: typeof import("./src/components/MkNumber.vue")["default"];
+		MkNumberDiff: typeof import("./src/components/MkNumberDiff.vue")["default"];
+		MkObjectView: typeof import("./src/components/MkObjectView.vue")["default"];
+		"MkObjectView.value": typeof import("./src/components/MkObjectView.value.vue")["default"];
+		MkPageHeader: typeof import("./src/components/global/MkPageHeader.vue")["default"];
+		MkPagePreview: typeof import("./src/components/MkPagePreview.vue")["default"];
+		MkPageWindow: typeof import("./src/components/MkPageWindow.vue")["default"];
+		MkPagination: typeof import("./src/components/MkPagination.vue")["default"];
+		MkPoll: typeof import("./src/components/MkPoll.vue")["default"];
+		MkPollEditor: typeof import("./src/components/MkPollEditor.vue")["default"];
+		MkPopupMenu: typeof import("./src/components/MkPopupMenu.vue")["default"];
+		MkPostForm: typeof import("./src/components/MkPostForm.vue")["default"];
+		MkPostFormAttaches: typeof import("./src/components/MkPostFormAttaches.vue")["default"];
+		MkPostFormDialog: typeof import("./src/components/MkPostFormDialog.vue")["default"];
+		MkPushNotificationAllowButton: typeof import("./src/components/MkPushNotificationAllowButton.vue")["default"];
+		MkQuoteButton: typeof import("./src/components/MkQuoteButton.vue")["default"];
+		MkReactedUsers: typeof import("./src/components/MkReactedUsers.vue")["default"];
+		MkReactionIcon: typeof import("./src/components/MkReactionIcon.vue")["default"];
+		MkReactionsViewer: typeof import("./src/components/MkReactionsViewer.vue")["default"];
+		"MkReactionsViewer.details": typeof import("./src/components/MkReactionsViewer.details.vue")["default"];
+		"MkReactionsViewer.reaction": typeof import("./src/components/MkReactionsViewer.reaction.vue")["default"];
+		MkReactionTooltip: typeof import("./src/components/MkReactionTooltip.vue")["default"];
+		MkRemoteCaution: typeof import("./src/components/MkRemoteCaution.vue")["default"];
+		MkRenoteButton: typeof import("./src/components/MkRenoteButton.vue")["default"];
+		MkRipple: typeof import("./src/components/MkRipple.vue")["default"];
+		MkSample: typeof import("./src/components/MkSample.vue")["default"];
+		MkShowMoreButton: typeof import("./src/components/MkShowMoreButton.vue")["default"];
+		MkSignin: typeof import("./src/components/MkSignin.vue")["default"];
+		MkSigninDialog: typeof import("./src/components/MkSigninDialog.vue")["default"];
+		MkSignup: typeof import("./src/components/MkSignup.vue")["default"];
+		MkSignupDialog: typeof import("./src/components/MkSignupDialog.vue")["default"];
+		MkSpacer: typeof import("./src/components/global/MkSpacer.vue")["default"];
+		MkSparkle: typeof import("./src/components/MkSparkle.vue")["default"];
+		MkStarButton: typeof import("./src/components/MkStarButton.vue")["default"];
+		MkStarButtonNoEmoji: typeof import("./src/components/MkStarButtonNoEmoji.vue")["default"];
+		MkStickyContainer: typeof import("./src/components/global/MkStickyContainer.vue")["default"];
+		MkSubNoteContent: typeof import("./src/components/MkSubNoteContent.vue")["default"];
+		MkSuperMenu: typeof import("./src/components/MkSuperMenu.vue")["default"];
+		MkTab: typeof import("./src/components/MkTab.vue")["default"];
+		MkTagCloud: typeof import("./src/components/MkTagCloud.vue")["default"];
+		MkTime: typeof import("./src/components/global/MkTime.vue")["default"];
+		MkTimeline: typeof import("./src/components/MkTimeline.vue")["default"];
+		MkToast: typeof import("./src/components/MkToast.vue")["default"];
+		MkTokenGenerateWindow: typeof import("./src/components/MkTokenGenerateWindow.vue")["default"];
+		MkTooltip: typeof import("./src/components/MkTooltip.vue")["default"];
+		MkTutorialDialog: typeof import("./src/components/MkTutorialDialog.vue")["default"];
+		MkUpdated: typeof import("./src/components/MkUpdated.vue")["default"];
+		MkUrl: typeof import("./src/components/global/MkUrl.vue")["default"];
+		MkUrlPreview: typeof import("./src/components/MkUrlPreview.vue")["default"];
+		MkUrlPreviewPopup: typeof import("./src/components/MkUrlPreviewPopup.vue")["default"];
+		MkUserCardMini: typeof import("./src/components/MkUserCardMini.vue")["default"];
+		MkUserInfo: typeof import("./src/components/MkUserInfo.vue")["default"];
+		MkUserList: typeof import("./src/components/MkUserList.vue")["default"];
+		MkUserName: typeof import("./src/components/global/MkUserName.vue")["default"];
+		MkUserOnlineIndicator: typeof import("./src/components/MkUserOnlineIndicator.vue")["default"];
+		MkUserPreview: typeof import("./src/components/MkUserPreview.vue")["default"];
+		MkUserSelectDialog: typeof import("./src/components/MkUserSelectDialog.vue")["default"];
+		MkUserSelectLocalDialog: typeof import("./src/components/MkUserSelectLocalDialog.vue")["default"];
+		MkUsersTooltip: typeof import("./src/components/MkUsersTooltip.vue")["default"];
+		MkVisibility: typeof import("./src/components/MkVisibility.vue")["default"];
+		MkVisibilityPicker: typeof import("./src/components/MkVisibilityPicker.vue")["default"];
+		MkWaitingDialog: typeof import("./src/components/MkWaitingDialog.vue")["default"];
+		MkWidgets: typeof import("./src/components/MkWidgets.vue")["default"];
+		MkWindow: typeof import("./src/components/MkWindow.vue")["default"];
+		Page: typeof import("./src/components/page/page.vue")["default"];
+		"Page.block": typeof import("./src/components/page/page.block.vue")["default"];
+		"Page.button": typeof import("./src/components/page/page.button.vue")["default"];
+		"Page.canvas": typeof import("./src/components/page/page.canvas.vue")["default"];
+		"Page.counter": typeof import("./src/components/page/page.counter.vue")["default"];
+		"Page.if": typeof import("./src/components/page/page.if.vue")["default"];
+		"Page.image": typeof import("./src/components/page/page.image.vue")["default"];
+		"Page.note": typeof import("./src/components/page/page.note.vue")["default"];
+		"Page.numberInput": typeof import("./src/components/page/page.number-input.vue")["default"];
+		"Page.post": typeof import("./src/components/page/page.post.vue")["default"];
+		"Page.radioButton": typeof import("./src/components/page/page.radio-button.vue")["default"];
+		"Page.section": typeof import("./src/components/page/page.section.vue")["default"];
+		"Page.switch": typeof import("./src/components/page/page.switch.vue")["default"];
+		"Page.text": typeof import("./src/components/page/page.text.vue")["default"];
+		"Page.textarea": typeof import("./src/components/page/page.textarea.vue")["default"];
+		"Page.textareaInput": typeof import("./src/components/page/page.textarea-input.vue")["default"];
+		"Page.textInput": typeof import("./src/components/page/page.text-input.vue")["default"];
+		Radio: typeof import("./src/components/form/radio.vue")["default"];
+		Radios: typeof import("./src/components/form/radios.vue")["default"];
+		Range: typeof import("./src/components/form/range.vue")["default"];
+		RouterView: typeof import("./src/components/global/RouterView.vue")["default"];
+		Section: typeof import("./src/components/form/section.vue")["default"];
+		Select: typeof import("./src/components/form/select.vue")["default"];
+		Slot: typeof import("./src/components/form/slot.vue")["default"];
+		Split: typeof import("./src/components/form/split.vue")["default"];
+		Suspense: typeof import("./src/components/form/suspense.vue")["default"];
+		Switch: typeof import("./src/components/form/switch.vue")["default"];
+		Textarea: typeof import("./src/components/form/textarea.vue")["default"];
+	}
+}
diff --git a/packages/client/package.json b/packages/client/package.json
index 125fadcc27..d050e746eb 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -6,7 +6,7 @@
 		"build": "pnpm vite build",
 		"build:debug": "pnpm run build",
 		"lint": "pnpm rome check **/*.ts --apply && pnpm run lint:vue",
-		"lint:vue": "pnpm paralint --ext .vue --fix '**/*.vue' --cache",
+		"lint:vue": "pnpm eslint --fix '**/*' --cache",
 		"format": "pnpm rome format * --write && pnpm prettier --write '**/*.{scss,vue}' --cache --cache-strategy metadata"
 	},
 	"devDependencies": {
@@ -51,6 +51,7 @@
 		"escape-regexp": "0.0.1",
 		"eslint-config-prettier": "^8.9.0",
 		"eslint-plugin-file-progress": "^1.3.0",
+		"eslint-plugin-unused-imports": "^3.0.0",
 		"eventemitter3": "5.0.1",
 		"fast-blurhash": "^1.1.2",
 		"firefish-js": "workspace:*",
@@ -63,7 +64,6 @@
 		"katex": "0.16.8",
 		"matter-js": "0.18.0",
 		"mfm-js": "0.23.3",
-		"paralint": "^1.2.1",
 		"photoswipe": "5.3.8",
 		"prettier": "3.0.1",
 		"prettier-plugin-vue": "1.1.6",
@@ -89,6 +89,8 @@
 		"twemoji-parser": "14.0.0",
 		"typescript": "5.1.6",
 		"unicode-emoji-json": "^0.4.0",
+		"unplugin-auto-import": "^0.16.6",
+		"unplugin-vue-components": "^0.25.1",
 		"uuid": "9.0.0",
 		"vanilla-tilt": "1.8.0",
 		"vite": "4.4.9",
diff --git a/packages/client/src/account.ts b/packages/client/src/account.ts
index b2d6df0332..31014c49d8 100644
--- a/packages/client/src/account.ts
+++ b/packages/client/src/account.ts
@@ -1,10 +1,10 @@
 import { defineAsyncComponent, reactive } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import { i18n } from "./i18n";
 import { del, get, set } from "@/scripts/idb-proxy";
 import { apiUrl } from "@/config";
-import { waiting, api, popup, popupMenu, success, alert } from "@/os";
-import { unisonReload, reloadChannel } from "@/scripts/unison-reload";
+import { alert, api, popup, popupMenu, waiting } from "@/os";
+import { reloadChannel, unisonReload } from "@/scripts/unison-reload";
 
 // TODO: 他のタブと永続化されたstateを同期
 
@@ -28,7 +28,7 @@ export async function signout() {
 
 	const accounts = await getAccounts();
 
-	//#region Remove service worker registration
+	// #region Remove service worker registration
 	try {
 		if (navigator.serviceWorker.controller) {
 			const registration = await navigator.serviceWorker.ready;
@@ -52,7 +52,7 @@ export async function signout() {
 			});
 		}
 	} catch (err) {}
-	//#endregion
+	// #endregion
 
 	document.cookie = "igi=; path=/";
 
diff --git a/packages/client/src/components/MkDialog.vue b/packages/client/src/components/MkDialog.vue
index 3cfd332c7d..5acef39654 100644
--- a/packages/client/src/components/MkDialog.vue
+++ b/packages/client/src/components/MkDialog.vue
@@ -199,7 +199,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onBeforeUnmount, onMounted, ref, shallowRef, computed } from "vue";
+import { computed, onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
 import * as Acct from "firefish-js/built/acct";
 import MkModal from "@/components/MkModal.vue";
 import MkButton from "@/components/MkButton.vue";
@@ -281,7 +281,9 @@ const modal = shallowRef<InstanceType<typeof MkModal>>();
 const inputValue = ref<string | number | null>(props.input?.default ?? null);
 const selectedValue = ref(props.select?.default ?? null);
 
-let disabledReason = ref<null | "charactersExceeded" | "charactersBelow">(null);
+const disabledReason = ref<null | "charactersExceeded" | "charactersBelow">(
+	null,
+);
 const okButtonDisabled = computed<boolean>(() => {
 	if (props.input) {
 		if (props.input.minLength) {
diff --git a/packages/client/src/components/MkDrive.file.vue b/packages/client/src/components/MkDrive.file.vue
index 3fe0316bc1..53705ca23e 100644
--- a/packages/client/src/components/MkDrive.file.vue
+++ b/packages/client/src/components/MkDrive.file.vue
@@ -39,7 +39,7 @@
 
 <script lang="ts" setup>
 import { computed, defineAsyncComponent, ref } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import copyToClipboard from "@/scripts/copy-to-clipboard";
 import MkDriveFileThumbnail from "@/components/MkDriveFileThumbnail.vue";
 import bytes from "@/filters/bytes";
@@ -160,7 +160,7 @@ function rename() {
 		if (canceled) return;
 		os.api("drive/files/update", {
 			fileId: props.file.id,
-			name: name,
+			name,
 		});
 	});
 }
@@ -179,7 +179,7 @@ function describe() {
 		{
 			done: (result) => {
 				if (!result || result.canceled) return;
-				let comment = result.result;
+				const comment = result.result;
 				os.api("drive/files/update", {
 					fileId: props.file.id,
 					comment: comment.length === 0 ? null : comment,
diff --git a/packages/client/src/components/MkDrive.folder.vue b/packages/client/src/components/MkDrive.folder.vue
index 7f63df7718..60700781a2 100644
--- a/packages/client/src/components/MkDrive.folder.vue
+++ b/packages/client/src/components/MkDrive.folder.vue
@@ -38,7 +38,7 @@
 
 <script lang="ts" setup>
 import { computed, defineAsyncComponent, ref } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { defaultStore } from "@/store";
@@ -131,7 +131,7 @@ function onDrop(ev: DragEvent) {
 		return;
 	}
 
-	//#region ドライブのファイル
+	// #region ドライブのファイル
 	const driveFile = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 	if (driveFile != null && driveFile !== "") {
 		const file = JSON.parse(driveFile);
@@ -141,9 +141,9 @@ function onDrop(ev: DragEvent) {
 			folderId: props.folder.id,
 		});
 	}
-	//#endregion
+	// #endregion
 
-	//#region ドライブのフォルダ
+	// #region ドライブのフォルダ
 	const driveFolder = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FOLDER_);
 	if (driveFolder != null && driveFolder !== "") {
 		const folder = JSON.parse(driveFolder);
@@ -175,7 +175,7 @@ function onDrop(ev: DragEvent) {
 				}
 			});
 	}
-	//#endregion
+	// #endregion
 }
 
 function onDragstart(ev: DragEvent) {
@@ -207,7 +207,7 @@ function rename() {
 		if (canceled) return;
 		os.api("drive/folders/update", {
 			folderId: props.folder.id,
-			name: name,
+			name,
 		});
 	});
 }
diff --git a/packages/client/src/components/MkDrive.navFolder.vue b/packages/client/src/components/MkDrive.navFolder.vue
index 4cdd42537b..df0b3c49d1 100644
--- a/packages/client/src/components/MkDrive.navFolder.vue
+++ b/packages/client/src/components/MkDrive.navFolder.vue
@@ -15,7 +15,7 @@
 
 <script lang="ts" setup>
 import { ref } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 
@@ -86,7 +86,7 @@ function onDrop(ev: DragEvent) {
 		return;
 	}
 
-	//#region ドライブのファイル
+	// #region ドライブのファイル
 	const driveFile = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 	if (driveFile != null && driveFile !== "") {
 		const file = JSON.parse(driveFile);
@@ -96,9 +96,9 @@ function onDrop(ev: DragEvent) {
 			folderId: props.folder ? props.folder.id : null,
 		});
 	}
-	//#endregion
+	// #endregion
 
-	//#region ドライブのフォルダ
+	// #region ドライブのフォルダ
 	const driveFolder = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FOLDER_);
 	if (driveFolder != null && driveFolder !== "") {
 		const folder = JSON.parse(driveFolder);
@@ -110,7 +110,7 @@ function onDrop(ev: DragEvent) {
 			parentId: props.folder ? props.folder.id : null,
 		});
 	}
-	//#endregion
+	// #endregion
 }
 </script>
 
diff --git a/packages/client/src/components/MkDrive.vue b/packages/client/src/components/MkDrive.vue
index a0b3713a72..28204fe86c 100644
--- a/packages/client/src/components/MkDrive.vue
+++ b/packages/client/src/components/MkDrive.vue
@@ -139,7 +139,7 @@ import {
 	ref,
 	watch,
 } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import MkButton from "./MkButton.vue";
 import XNavFolder from "@/components/MkDrive.navFolder.vue";
 import XFolder from "@/components/MkDrive.folder.vue";
@@ -294,7 +294,7 @@ function onDrop(ev: DragEvent): any {
 		return;
 	}
 
-	//#region ドライブのファイル
+	// #region ドライブのファイル
 	const driveFile = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 	if (driveFile != null && driveFile !== "") {
 		const file = JSON.parse(driveFile);
@@ -305,9 +305,9 @@ function onDrop(ev: DragEvent): any {
 			folderId: folder.value ? folder.value.id : null,
 		});
 	}
-	//#endregion
+	// #endregion
 
-	//#region ドライブのフォルダ
+	// #region ドライブのフォルダ
 	const driveFolder = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FOLDER_);
 	if (driveFolder != null && driveFolder !== "") {
 		const droppedFolder = JSON.parse(driveFolder);
@@ -339,7 +339,7 @@ function onDrop(ev: DragEvent): any {
 				}
 			});
 	}
-	//#endregion
+	// #endregion
 }
 
 function selectLocalFile() {
@@ -354,7 +354,7 @@ function urlUpload() {
 	}).then(({ canceled, result: url }) => {
 		if (canceled || !url) return;
 		os.api("drive/files/upload-from-url", {
-			url: url,
+			url,
 			folderId: folder.value ? folder.value.id : undefined,
 		});
 
@@ -372,7 +372,7 @@ function createFolder() {
 	}).then(({ canceled, result: name }) => {
 		if (canceled) return;
 		os.api("drive/folders/create", {
-			name: name,
+			name,
 			parentId: folder.value ? folder.value.id : undefined,
 		}).then((createdFolder) => {
 			addFolder(createdFolder, true);
@@ -389,7 +389,7 @@ function renameFolder(folderToRename: Misskey.entities.DriveFolder) {
 		if (canceled) return;
 		os.api("drive/folders/update", {
 			folderId: folderToRename.id,
-			name: name,
+			name,
 		}).then((updatedFolder) => {
 			// FIXME: 画面を更新するために自分自身に移動
 			move(updatedFolder);
diff --git a/packages/client/src/components/MkDriveFileThumbnail.vue b/packages/client/src/components/MkDriveFileThumbnail.vue
index c5af469e91..7d9b43635e 100644
--- a/packages/client/src/components/MkDriveFileThumbnail.vue
+++ b/packages/client/src/components/MkDriveFileThumbnail.vue
@@ -68,7 +68,7 @@ const is = computed(() => {
 			"application/x-tar",
 			"application/gzip",
 			"application/x-7z-compressed",
-		].some((archiveType) => archiveType === props.file.type)
+		].includes(props.file.type)
 	)
 		return "archive";
 	return "unknown";
diff --git a/packages/client/src/components/MkDriveSelectDialog.vue b/packages/client/src/components/MkDriveSelectDialog.vue
index 5b3b33d6c7..ae292b96a7 100644
--- a/packages/client/src/components/MkDriveSelectDialog.vue
+++ b/packages/client/src/components/MkDriveSelectDialog.vue
@@ -37,7 +37,7 @@
 
 <script lang="ts" setup>
 import { ref } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import XDrive from "@/components/MkDrive.vue";
 import XModalWindow from "@/components/MkModalWindow.vue";
 import number from "@/filters/number";
diff --git a/packages/client/src/components/MkDriveWindow.vue b/packages/client/src/components/MkDriveWindow.vue
index 646440cbaa..24daea977b 100644
--- a/packages/client/src/components/MkDriveWindow.vue
+++ b/packages/client/src/components/MkDriveWindow.vue
@@ -15,7 +15,7 @@
 
 <script lang="ts" setup>
 import {} from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import XDrive from "@/components/MkDrive.vue";
 import XWindow from "@/components/MkWindow.vue";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/components/MkEmojiPicker.section.vue b/packages/client/src/components/MkEmojiPicker.section.vue
index d7d1ba8f05..2ffe842899 100644
--- a/packages/client/src/components/MkEmojiPicker.section.vue
+++ b/packages/client/src/components/MkEmojiPicker.section.vue
@@ -48,7 +48,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, onMounted } from "vue";
+import { onMounted, ref, watch } from "vue";
 import { addSkinTone } from "@/scripts/emojilist";
 
 const props = defineProps<{
diff --git a/packages/client/src/components/MkEmojiPicker.vue b/packages/client/src/components/MkEmojiPicker.vue
index b3b5c9d31f..799b7462c4 100644
--- a/packages/client/src/components/MkEmojiPicker.vue
+++ b/packages/client/src/components/MkEmojiPicker.vue
@@ -1,5 +1,5 @@
 <template>
-	<FocusTrap v-bind:active="isActive">
+	<FocusTrap :active="isActive">
 		<div
 			class="omfetrab"
 			:class="['s' + size, 'w' + width, 'h' + height, { asDrawer }]"
@@ -163,14 +163,15 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed, watch, onMounted } from "vue";
-import * as Misskey from "firefish-js";
+import { computed, onMounted, ref, watch } from "vue";
+import type * as Misskey from "firefish-js";
+import { FocusTrap } from "focus-trap-vue";
 import XSection from "@/components/MkEmojiPicker.section.vue";
+import type { UnicodeEmojiDef } from "@/scripts/emojilist";
 import {
 	emojilist,
-	unicodeEmojiCategories,
-	UnicodeEmojiDef,
 	getNicelyLabeledCategory,
+	unicodeEmojiCategories,
 } from "@/scripts/emojilist";
 import { getStaticImageUrl } from "@/scripts/get-static-image-url";
 import Ripple from "@/components/MkRipple.vue";
@@ -180,7 +181,6 @@ import { deviceKind } from "@/scripts/device-kind";
 import { emojiCategories, instance } from "@/instance";
 import { i18n } from "@/i18n";
 import { defaultStore } from "@/store";
-import { FocusTrap } from "focus-trap-vue";
 
 const props = withDefaults(
 	defineProps<{
diff --git a/packages/client/src/components/MkFeaturedPhotos.vue b/packages/client/src/components/MkFeaturedPhotos.vue
index 3ce037d52e..c3610ae2ef 100644
--- a/packages/client/src/components/MkFeaturedPhotos.vue
+++ b/packages/client/src/components/MkFeaturedPhotos.vue
@@ -8,7 +8,7 @@
 
 <script lang="ts" setup>
 import { ref } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import * as os from "@/os";
 
 const meta = ref<Misskey.entities.DetailedInstanceMetadata>();
diff --git a/packages/client/src/components/MkFollowButton.vue b/packages/client/src/components/MkFollowButton.vue
index 6f003b320b..394baab185 100644
--- a/packages/client/src/components/MkFollowButton.vue
+++ b/packages/client/src/components/MkFollowButton.vue
@@ -1,14 +1,15 @@
 <template>
 	<button
 		v-if="!hideMenu"
+		v-tooltip="i18n.ts.menu"
 		class="menu _button"
 		@click.stop="menu"
-		v-tooltip="i18n.ts.menu"
 	>
 		<i class="ph-dots-three-outline ph-bold ph-lg"></i>
 	</button>
 	<button
 		v-if="$i != null && $i.id != user.id"
+		v-tooltip="full ? null : `${state} ${user.name || user.username}`"
 		class="kpoogebi _button follow-button"
 		:class="{
 			wait,
@@ -18,9 +19,8 @@
 			blocking: isBlocking,
 		}"
 		:disabled="wait"
-		@click.stop="onClick"
 		:aria-label="`${state} ${user.name || user.username}`"
-		v-tooltip="full ? null : `${state} ${user.name || user.username}`"
+		@click.stop="onClick"
 	>
 		<template v-if="!wait">
 			<template v-if="isBlocking">
@@ -88,13 +88,13 @@ const props = withDefaults(
 
 const isBlocking = computed(() => props.user.isBlocking);
 
-let state = ref(i18n.ts.processing);
+const state = ref(i18n.ts.processing);
 
-let isFollowing = ref(props.user.isFollowing);
-let hasPendingFollowRequestFromYou = ref(
+const isFollowing = ref(props.user.isFollowing);
+const hasPendingFollowRequestFromYou = ref(
 	props.user.hasPendingFollowRequestFromYou,
 );
-let wait = ref(false);
+const wait = ref(false);
 const connection = stream.useChannel("main");
 
 if (props.user.isFollowing == null) {
diff --git a/packages/client/src/components/MkForgotPassword.vue b/packages/client/src/components/MkForgotPassword.vue
index e4898fabaf..feaaa5f120 100644
--- a/packages/client/src/components/MkForgotPassword.vue
+++ b/packages/client/src/components/MkForgotPassword.vue
@@ -64,7 +64,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import XModalWindow from "@/components/MkModalWindow.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
@@ -77,11 +76,11 @@ const emit = defineEmits<{
 	(ev: "closed"): void;
 }>();
 
-let dialog: InstanceType<typeof XModalWindow> = ref();
+const dialog: InstanceType<typeof XModalWindow> = ref();
 
-let username = ref("");
-let email = ref("");
-let processing = ref(false);
+const username = ref("");
+const email = ref("");
+const processing = ref(false);
 
 async function onSubmit() {
 	processing.value = true;
diff --git a/packages/client/src/components/MkFormula.vue b/packages/client/src/components/MkFormula.vue
index e2e3e11219..f39a8db017 100644
--- a/packages/client/src/components/MkFormula.vue
+++ b/packages/client/src/components/MkFormula.vue
@@ -3,7 +3,7 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, defineAsyncComponent } from "vue";
+import { defineAsyncComponent, defineComponent } from "vue";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/MkHeatmap.vue b/packages/client/src/components/MkHeatmap.vue
index b3592b6e03..0565c5914b 100644
--- a/packages/client/src/components/MkHeatmap.vue
+++ b/packages/client/src/components/MkHeatmap.vue
@@ -8,7 +8,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, nextTick, watch, shallowRef, ref } from "vue";
+import { nextTick, onMounted, ref, shallowRef, watch } from "vue";
 import { Chart } from "chart.js";
 import * as os from "@/os";
 import { defaultStore } from "@/store";
@@ -26,8 +26,8 @@ const props = defineProps<{
 const rootEl = shallowRef<HTMLDivElement>(null);
 const chartEl = shallowRef<HTMLCanvasElement>(null);
 const now = new Date();
-let chartInstance: Chart = null;
-let fetching = ref(true);
+let chartInstance: Chart = null,
+	fetching = ref(true);
 
 const { handler: externalTooltipHandler } = useChartTooltip({
 	position: "middle",
@@ -233,7 +233,7 @@ async function renderChart() {
 							return ["Active: " + v.v];
 						},
 					},
-					//mode: 'index',
+					// mode: 'index',
 					animation: {
 						duration: 0,
 					},
diff --git a/packages/client/src/components/MkImageViewer.vue b/packages/client/src/components/MkImageViewer.vue
index 90db31a8d3..882701e95b 100644
--- a/packages/client/src/components/MkImageViewer.vue
+++ b/packages/client/src/components/MkImageViewer.vue
@@ -28,7 +28,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import type * as misskey from "firefish-js";
 import bytes from "@/filters/bytes";
 import number from "@/filters/number";
diff --git a/packages/client/src/components/MkImgWithBlurhash.vue b/packages/client/src/components/MkImgWithBlurhash.vue
index c436fcd32f..54ea5d9c9c 100644
--- a/packages/client/src/components/MkImgWithBlurhash.vue
+++ b/packages/client/src/components/MkImgWithBlurhash.vue
@@ -49,7 +49,7 @@ const props = withDefaults(
 );
 
 const canvas = ref<HTMLCanvasElement>();
-let loaded = ref(false);
+const loaded = ref(false);
 
 function draw() {
 	if (props.hash == null || canvas.value == null) return;
diff --git a/packages/client/src/components/MkInfo.vue b/packages/client/src/components/MkInfo.vue
index 0a9373885e..92f935e482 100644
--- a/packages/client/src/components/MkInfo.vue
+++ b/packages/client/src/components/MkInfo.vue
@@ -11,8 +11,8 @@
 			v-if="closeable"
 			v-tooltip="i18n.ts.close"
 			class="_buttonIcon close"
-			@click.stop="close"
 			:aria-label="i18n.t('close')"
+			@click.stop="close"
 		>
 			<i class="ph-x ph-bold ph-lg"></i>
 		</button>
diff --git a/packages/client/src/components/MkInstanceCardMini.vue b/packages/client/src/components/MkInstanceCardMini.vue
index c774efcdc6..81aa52dc25 100644
--- a/packages/client/src/components/MkInstanceCardMini.vue
+++ b/packages/client/src/components/MkInstanceCardMini.vue
@@ -26,7 +26,7 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import * as firefish from "firefish-js";
+import type * as firefish from "firefish-js";
 import MkMiniChart from "@/components/MkMiniChart.vue";
 import * as os from "@/os";
 import { getProxiedImageUrlNullable } from "@/scripts/media-proxy";
@@ -35,7 +35,7 @@ const props = defineProps<{
 	instance: firefish.entities.Instance;
 }>();
 
-let chartValues = ref<number[] | null>(null);
+const chartValues = ref<number[] | null>(null);
 
 os.apiGet("charts/instance", {
 	host: props.instance.host,
diff --git a/packages/client/src/components/MkInstanceSelectDialog.vue b/packages/client/src/components/MkInstanceSelectDialog.vue
index 312b656ba4..e328695e22 100644
--- a/packages/client/src/components/MkInstanceSelectDialog.vue
+++ b/packages/client/src/components/MkInstanceSelectDialog.vue
@@ -58,11 +58,11 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
+import type { Instance } from "firefish-js/built/entities";
 import MkInput from "@/components/form/input.vue";
 import XModalWindow from "@/components/MkModalWindow.vue";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
-import { Instance } from "firefish-js/built/entities";
 
 const emit = defineEmits<{
 	(ev: "ok", selected: Instance): void;
@@ -70,10 +70,10 @@ const emit = defineEmits<{
 	(ev: "closed"): void;
 }>();
 
-let hostname = ref("");
-let instances: Instance[] = ref([]);
-let selected: Instance | null = ref(null);
-let dialogEl = ref<InstanceType<typeof XModalWindow>>();
+const hostname = ref("");
+const instances: Instance[] = ref([]);
+const selected: Instance | null = ref(null);
+const dialogEl = ref<InstanceType<typeof XModalWindow>>();
 
 let searchOrderLatch = 0;
 const search = () => {
diff --git a/packages/client/src/components/MkInstanceStats.vue b/packages/client/src/components/MkInstanceStats.vue
index 516264e3a4..768c55344c 100644
--- a/packages/client/src/components/MkInstanceStats.vue
+++ b/packages/client/src/components/MkInstanceStats.vue
@@ -116,11 +116,11 @@ import { initChart } from "@/scripts/init-chart";
 initChart();
 
 const chartLimit = 500;
-let chartSpan = ref<"hour" | "day">("hour");
-let chartSrc = ref("active-users");
-let heatmapSrc = ref("active-users");
-let subDoughnutEl = shallowRef<HTMLCanvasElement>();
-let pubDoughnutEl = shallowRef<HTMLCanvasElement>();
+const chartSpan = ref<"hour" | "day">("hour");
+const chartSrc = ref("active-users");
+const heatmapSrc = ref("active-users");
+const subDoughnutEl = shallowRef<HTMLCanvasElement>();
+const pubDoughnutEl = shallowRef<HTMLCanvasElement>();
 
 const { handler: externalTooltipHandler1 } = useChartTooltip({
 	position: "middle",
diff --git a/packages/client/src/components/MkInstanceTicker.vue b/packages/client/src/components/MkInstanceTicker.vue
index 8043f4e6c6..e916c48bfc 100644
--- a/packages/client/src/components/MkInstanceTicker.vue
+++ b/packages/client/src/components/MkInstanceTicker.vue
@@ -1,8 +1,8 @@
 <template>
 	<div
-		class="hpaizdrt"
-		v-tooltip="capitalize(instance.softwareName)"
 		ref="ticker"
+		v-tooltip="capitalize(instance.softwareName)"
+		class="hpaizdrt"
 		:style="bg"
 	>
 		<img class="icon" :src="getInstanceIcon(instance)" aria-hidden="true" />
@@ -26,7 +26,7 @@ const props = defineProps<{
 	};
 }>();
 
-let ticker = ref<HTMLElement | null>(null);
+const ticker = ref<HTMLElement | null>(null);
 
 // if no instance data is given, this is for the local instance
 const instance = props.instance ?? {
diff --git a/packages/client/src/components/MkMedia.vue b/packages/client/src/components/MkMedia.vue
index 0539ed44f2..6428eeafb0 100644
--- a/packages/client/src/components/MkMedia.vue
+++ b/packages/client/src/components/MkMedia.vue
@@ -1,5 +1,5 @@
 <template>
-	<div class="media" v-size="{ max: [350] }">
+	<div v-size="{ max: [350] }" class="media">
 		<button v-if="hide" class="hidden" @click="hide = false">
 			<ImgWithBlurhash
 				:hash="media.blurhash"
@@ -89,7 +89,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import VuePlyr from "vue-plyr";
 import "vue-plyr/dist/vue-plyr.css";
 import type * as misskey from "firefish-js";
@@ -104,7 +104,7 @@ const props = defineProps<{
 	raw?: boolean;
 }>();
 
-let hide = ref(true);
+const hide = ref(true);
 
 const plyr = ref();
 
diff --git a/packages/client/src/components/MkMediaBanner.vue b/packages/client/src/components/MkMediaBanner.vue
index bcf2b83055..21f2f80330 100644
--- a/packages/client/src/components/MkMediaBanner.vue
+++ b/packages/client/src/components/MkMediaBanner.vue
@@ -71,7 +71,7 @@ const props = withDefaults(
 );
 
 const audioEl = ref<HTMLAudioElement | null>();
-let hide = ref(true);
+const hide = ref(true);
 
 function volumechange() {
 	if (audioEl.value)
diff --git a/packages/client/src/components/MkMediaList.vue b/packages/client/src/components/MkMediaList.vue
index 4b7b7e7161..5a51be9388 100644
--- a/packages/client/src/components/MkMediaList.vue
+++ b/packages/client/src/components/MkMediaList.vue
@@ -29,7 +29,7 @@
 
 <script lang="ts" setup>
 import { onMounted, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import PhotoSwipeLightbox from "photoswipe/lightbox";
 import PhotoSwipe from "photoswipe";
 import "photoswipe/style.css";
@@ -125,11 +125,11 @@ onMounted(() => {
 			className: "pwsp__alt-text-container",
 			appendTo: "wrapper",
 			onInit: (el, pwsp) => {
-				let textBox = document.createElement("p");
+				const textBox = document.createElement("p");
 				textBox.className = "pwsp__alt-text";
 				el.appendChild(textBox);
 
-				let preventProp = function (ev: Event): void {
+				const preventProp = function (ev: Event): void {
 					ev.stopPropagation();
 				};
 
diff --git a/packages/client/src/components/MkMenu.child.vue b/packages/client/src/components/MkMenu.child.vue
index c7813e8504..688b3ce3a4 100644
--- a/packages/client/src/components/MkMenu.child.vue
+++ b/packages/client/src/components/MkMenu.child.vue
@@ -14,7 +14,7 @@
 <script lang="ts" setup>
 import { nextTick, onMounted, ref } from "vue";
 import MkMenu from "./MkMenu.vue";
-import { MenuItem } from "@/types/menu";
+import type { MenuItem } from "@/types/menu";
 
 const props = defineProps<{
 	items: MenuItem[];
diff --git a/packages/client/src/components/MkMenu.vue b/packages/client/src/components/MkMenu.vue
index 95370eebd5..323983c495 100644
--- a/packages/client/src/components/MkMenu.vue
+++ b/packages/client/src/components/MkMenu.vue
@@ -14,8 +14,8 @@
 					width: width && !asDrawer ? width + 'px' : '',
 					maxHeight: maxHeight ? maxHeight + 'px' : '',
 				}"
-				@contextmenu.self="(e) => e.preventDefault()"
 				tabindex="-1"
+				@contextmenu.self="(e) => e.preventDefault()"
 			>
 				<template v-for="item in items2">
 					<div v-if="item === null" class="divider"></div>
@@ -47,7 +47,7 @@
 							v-if="item.avatar"
 							:user="item.avatar"
 							class="avatar"
-							disableLink
+							disable-link
 						/>
 						<span :style="item.textStyle || ''">{{
 							item.text
@@ -100,7 +100,7 @@
 						<MkAvatar
 							:user="item.user"
 							class="avatar"
-							disableLink
+							disable-link
 						/><MkUserName :user="item.user" />
 						<span
 							v-if="item.indicate"
@@ -168,7 +168,7 @@
 							v-if="item.avatar"
 							:user="item.avatar"
 							class="avatar"
-							disableLink
+							disable-link
 						/>
 						<span :style="item.textStyle || ''">{{
 							item.text
@@ -210,11 +210,16 @@ import {
 	ref,
 	watch,
 } from "vue";
+import { FocusTrap } from "focus-trap-vue";
 import FormSwitch from "@/components/form/switch.vue";
-import { MenuItem, InnerMenuItem, MenuPending, MenuAction } from "@/types/menu";
+import type {
+	InnerMenuItem,
+	MenuAction,
+	MenuItem,
+	MenuPending,
+} from "@/types/menu";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
-import { FocusTrap } from "focus-trap-vue";
 
 const XChild = defineAsyncComponent(() => import("./MkMenu.child.vue"));
 const focusTrap = ref();
@@ -233,13 +238,13 @@ const emit = defineEmits<{
 	(ev: "close", actioned?: boolean): void;
 }>();
 
-let itemsEl = ref<HTMLDivElement>();
+const itemsEl = ref<HTMLDivElement>();
 
-let items2: InnerMenuItem[] = ref([]);
+const items2: InnerMenuItem[] = ref([]);
 
-let child = ref<InstanceType<typeof XChild>>();
+const child = ref<InstanceType<typeof XChild>>();
 
-let childShowingItem = ref<MenuItem | null>();
+const childShowingItem = ref<MenuItem | null>();
 
 watch(
 	() => props.items,
@@ -267,8 +272,8 @@ watch(
 	},
 );
 
-let childMenu = ref<MenuItem[] | null>();
-let childTarget = ref<HTMLElement | null>();
+const childMenu = ref<MenuItem[] | null>();
+const childTarget = ref<HTMLElement | null>();
 
 function closeChild() {
 	childMenu.value = null;
diff --git a/packages/client/src/components/MkMiniChart.vue b/packages/client/src/components/MkMiniChart.vue
index 8c604e5fc6..bfa83f3d80 100644
--- a/packages/client/src/components/MkMiniChart.vue
+++ b/packages/client/src/components/MkMiniChart.vue
@@ -25,7 +25,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref } from "vue";
+import { ref, watch } from "vue";
 import { v4 as uuid } from "uuid";
 import tinycolor from "tinycolor2";
 import { useInterval } from "@/scripts/use-interval";
@@ -37,10 +37,10 @@ const props = defineProps<{
 const viewBoxX = 50;
 const viewBoxY = 50;
 const gradientId = uuid();
-let polylinePoints = ref("");
-let polygonPoints = ref("");
-let headX = ref<number | null>(null);
-let headY = ref<number | null>(null);
+const polylinePoints = ref("");
+const polygonPoints = ref("");
+const headX = ref<number | null>(null);
+const headY = ref<number | null>(null);
 const accent = tinycolor(
 	getComputedStyle(document.documentElement).getPropertyValue("--accent"),
 );
diff --git a/packages/client/src/components/MkModal.vue b/packages/client/src/components/MkModal.vue
index c7a12ecad6..893cced0d5 100644
--- a/packages/client/src/components/MkModal.vue
+++ b/packages/client/src/components/MkModal.vue
@@ -25,6 +25,7 @@
 			<div
 				v-show="manualShowing != null ? manualShowing : showing"
 				v-hotkey.global="keymap"
+				v-focus
 				:class="[
 					$style.root,
 					{
@@ -44,7 +45,6 @@
 					'--transformOrigin': transformOrigin,
 				}"
 				tabindex="-1"
-				v-focus
 			>
 				<div
 					class="_modalBg data-cy-bg"
@@ -78,20 +78,20 @@
 
 <script lang="ts" setup>
 import {
+	computed,
 	nextTick,
 	onMounted,
-	watch,
-	provide,
 	onUnmounted,
+	provide,
 	ref,
 	shallowRef,
-	computed,
+	watch,
 } from "vue";
+import { FocusTrap } from "focus-trap-vue";
 import * as os from "@/os";
 import { isTouchUsing } from "@/scripts/touch";
 import { defaultStore } from "@/store";
 import { deviceKind } from "@/scripts/device-kind";
-import { FocusTrap } from "focus-trap-vue";
 
 function getFixedContainer(el: Element | null): Element | null {
 	if (el == null || el.tagName === "BODY") return null;
@@ -139,13 +139,13 @@ const emit = defineEmits<{
 
 provide("modal", true);
 
-let maxHeight = ref<number>();
-let fixed = ref(false);
-let transformOrigin = ref("center");
-let showing = ref(true);
-let content = shallowRef<HTMLElement>();
+const maxHeight = ref<number>();
+const fixed = ref(false);
+const transformOrigin = ref("center");
+const showing = ref(true);
+const content = shallowRef<HTMLElement>();
 const zIndex = os.claimZIndex(props.zPriority);
-let useSendAnime = ref(false);
+const useSendAnime = ref(false);
 const type = computed<ModalTypes>(() => {
 	if (props.preferType === "auto") {
 		if (
@@ -164,7 +164,7 @@ const type = computed<ModalTypes>(() => {
 const isEnableBgTransparent = computed(
 	() => props.transparentBg && type.value === "popup",
 );
-let transitionName = computed(() =>
+const transitionName = computed(() =>
 	defaultStore.state.animation
 		? useSendAnime.value
 			? "send"
@@ -175,7 +175,7 @@ let transitionName = computed(() =>
 			: "modal"
 		: "",
 );
-let transitionDuration = computed(() =>
+const transitionDuration = computed(() =>
 	transitionName.value === "send"
 		? 400
 		: transitionName.value === "modal-popup"
@@ -235,8 +235,7 @@ const align = () => {
 	const width = content.value!.offsetWidth;
 	const height = content.value!.offsetHeight;
 
-	let left;
-	let top;
+	let left, top;
 
 	const x = srcRect.left + (fixed.value ? 0 : window.pageXOffset);
 	const y = srcRect.top + (fixed.value ? 0 : window.pageYOffset);
@@ -321,8 +320,8 @@ const align = () => {
 		left = 0;
 	}
 
-	let transformOriginX = "center";
-	let transformOriginY = "center";
+	let transformOriginX = "center",
+		transformOriginY = "center";
 
 	if (
 		top >=
diff --git a/packages/client/src/components/MkModalPageWindow.vue b/packages/client/src/components/MkModalPageWindow.vue
index 811f3cad72..e745499ddc 100644
--- a/packages/client/src/components/MkModalPageWindow.vue
+++ b/packages/client/src/components/MkModalPageWindow.vue
@@ -28,8 +28,8 @@
 				</span>
 				<button
 					class="_button"
-					@click="$refs.modal.close()"
 					:aria-label="i18n.t('close')"
+					@click="$refs.modal.close()"
 				>
 					<i class="ph-x ph-bold ph-lg"></i>
 				</button>
@@ -52,7 +52,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ComputedRef, provide, ref, computed } from "vue";
+import type { ComputedRef } from "vue";
+import { computed, provide, ref } from "vue";
 import MkModal from "@/components/MkModal.vue";
 import { popout as _popout } from "@/scripts/popout";
 import copyToClipboard from "@/scripts/copy-to-clipboard";
@@ -60,7 +61,8 @@ import { url } from "@/config";
 import * as os from "@/os";
 import { mainRouter, routes } from "@/router";
 import { i18n } from "@/i18n";
-import { PageMetadata, provideMetadataReceiver } from "@/scripts/page-metadata";
+import type { PageMetadata } from "@/scripts/page-metadata";
+import { provideMetadataReceiver } from "@/scripts/page-metadata";
 import { Router } from "@/nirax";
 
 const props = defineProps<{
@@ -76,12 +78,12 @@ const router = new Router(routes, props.initialPath);
 
 router.addListener("push", (ctx) => {});
 
-let pageMetadata = ref<null | ComputedRef<PageMetadata>>();
-let rootEl = ref();
-let modal = ref<InstanceType<typeof MkModal>>();
-let path = ref(props.initialPath);
-let width = ref(860);
-let height = ref(660);
+const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
+const rootEl = ref();
+const modal = ref<InstanceType<typeof MkModal>>();
+const path = ref(props.initialPath);
+const width = ref(860);
+const height = ref(660);
 const history = [];
 
 provide("router", router);
diff --git a/packages/client/src/components/MkModalWindow.vue b/packages/client/src/components/MkModalWindow.vue
index e0d1366a17..6e5a321ae1 100644
--- a/packages/client/src/components/MkModalWindow.vue
+++ b/packages/client/src/components/MkModalWindow.vue
@@ -25,10 +25,10 @@
 				<div ref="headerEl" class="header">
 					<button
 						v-if="props.withOkButton"
+						v-tooltip="i18n.ts.close"
 						:aria-label="i18n.t('close')"
 						class="_button"
 						@click="$emit('close')"
-						v-tooltip="i18n.ts.close"
 					>
 						<i class="ph-x ph-bold ph-lg"></i>
 					</button>
@@ -92,9 +92,9 @@ const emit = defineEmits<{
 	(event: "ok"): void;
 }>();
 
-let modal = shallowRef<InstanceType<typeof MkModal>>();
-let rootEl = shallowRef<HTMLElement>();
-let headerEl = shallowRef<HTMLElement>();
+const modal = shallowRef<InstanceType<typeof MkModal>>();
+const rootEl = shallowRef<HTMLElement>();
+const headerEl = shallowRef<HTMLElement>();
 
 const close = (ev) => {
 	modal.value?.close(ev);
diff --git a/packages/client/src/components/MkNote.vue b/packages/client/src/components/MkNote.vue
index b1c6114e1f..f8c2b6ceac 100644
--- a/packages/client/src/components/MkNote.vue
+++ b/packages/client/src/components/MkNote.vue
@@ -1,15 +1,15 @@
 <template>
 	<div
-		:aria-label="accessibleLabel"
 		v-if="!muted.muted"
 		v-show="!isDeleted"
+		:id="appearNote.id"
 		ref="el"
 		v-hotkey="keymap"
 		v-size="{ max: [500, 350] }"
+		:aria-label="accessibleLabel"
 		class="tkcbzcuz note-container"
 		:tabindex="!isDeleted ? '-1' : null"
 		:class="{ renote: isRenote }"
-		:id="appearNote.id"
 	>
 		<MkNoteSub
 			v-if="appearNote.reply && !detailedView && !collapsedReply"
@@ -19,10 +19,10 @@
 		<div
 			v-if="!detailedView"
 			class="note-context"
-			@click="noteClick"
 			:class="{
 				collapsedReply: collapsedReply && appearNote.reply,
 			}"
+			@click="noteClick"
 		>
 			<div class="line"></div>
 			<div v-if="appearNote._prId_" class="info">
@@ -87,11 +87,11 @@
 		</div>
 		<article
 			class="article"
-			@contextmenu.stop="onContextmenu"
-			@click="noteClick"
 			:style="{
 				cursor: expandOnNoteClick && !detailedView ? 'pointer' : '',
 			}"
+			@contextmenu.stop="onContextmenu"
+			@click="noteClick"
 		>
 			<div class="main">
 				<div class="header-container">
@@ -103,8 +103,8 @@
 						class="text"
 						:note="appearNote"
 						:detailed="true"
-						:detailedView="detailedView"
-						:parentId="appearNote.parentId"
+						:detailed-view="detailedView"
+						:parent-id="appearNote.parentId"
 						@push="(e) => router.push(notePage(e))"
 						@focusfooter="footerEl.focus()"
 						@expanded="(e) => setPostExpanded(e)"
@@ -171,7 +171,7 @@
 						class="button"
 						:note="appearNote"
 						:count="appearNote.renoteCount"
-						:detailedView="detailedView"
+						:detailed-view="detailedView"
 					/>
 					<XStarButtonNoEmoji
 						v-if="!enableEmojiReactions"
@@ -212,9 +212,9 @@
 							appearNote.myReaction != null
 						"
 						ref="reactButton"
+						v-tooltip.noDelay.bottom="i18n.ts.removeReaction"
 						class="button _button reacted"
 						@click.stop="undoReact(appearNote)"
-						v-tooltip.noDelay.bottom="i18n.ts.removeReaction"
 					>
 						<i class="ph-minus ph-bold ph-lg"></i>
 					</button>
@@ -256,11 +256,10 @@
 
 <script lang="ts" setup>
 import { computed, inject, onMounted, ref } from "vue";
-import * as mfm from "mfm-js";
 import type { Ref } from "vue";
 import type * as misskey from "firefish-js";
-import MkNoteSub from "@/components/MkNoteSub.vue";
 import MkSubNoteContent from "./MkSubNoteContent.vue";
+import MkNoteSub from "@/components/MkNoteSub.vue";
 import XNoteHeader from "@/components/MkNoteHeader.vue";
 import XRenoteButton from "@/components/MkRenoteButton.vue";
 import XReactionsViewer from "@/components/MkReactionsViewer.vue";
@@ -271,7 +270,7 @@ import MkVisibility from "@/components/MkVisibility.vue";
 import copyToClipboard from "@/scripts/copy-to-clipboard";
 import { url } from "@/config";
 import { pleaseLogin } from "@/scripts/please-login";
-import { focusPrev, focusNext } from "@/scripts/focus";
+import { focusNext, focusPrev } from "@/scripts/focus";
 import { getWordSoftMute } from "@/scripts/check-word-mute";
 import { useRouter } from "@/router";
 import { userPage } from "@/filters/user";
@@ -297,7 +296,7 @@ const props = defineProps<{
 
 const inChannel = inject("inChannel", null);
 
-let note = ref(deepClone(props.note));
+const note = ref(deepClone(props.note));
 
 const softMuteReasonI18nSrc = (what?: string) => {
 	if (what === "note") return i18n.ts.userSaysSomethingReason;
@@ -333,7 +332,7 @@ const starButton = ref<InstanceType<typeof XStarButton>>();
 const renoteButton = ref<InstanceType<typeof XRenoteButton>>();
 const renoteTime = ref<HTMLElement>();
 const reactButton = ref<HTMLElement>();
-let appearNote = computed(() =>
+const appearNote = computed(() =>
 	isRenote ? (note.value.renote as misskey.entities.Note) : note.value,
 );
 const isMyRenote = $i && $i.id === note.value.userId;
@@ -385,7 +384,7 @@ function react(viaKeyboard = false): void {
 		(reaction) => {
 			os.api("notes/reactions/create", {
 				noteId: appearNote.value.id,
-				reaction: reaction,
+				reaction,
 			});
 		},
 		() => {
@@ -516,7 +515,7 @@ function showRenoteMenu(viaKeyboard = false): void {
 		],
 		renoteTime.value,
 		{
-			viaKeyboard: viaKeyboard,
+			viaKeyboard,
 		},
 	);
 }
@@ -560,7 +559,7 @@ function readPromo() {
 	isDeleted.value = true;
 }
 
-let postIsExpanded = ref(false);
+const postIsExpanded = ref(false);
 
 function setPostExpanded(val: boolean) {
 	postIsExpanded.value = val;
diff --git a/packages/client/src/components/MkNoteDetailed.vue b/packages/client/src/components/MkNoteDetailed.vue
index 041239b19d..9da05073ab 100644
--- a/packages/client/src/components/MkNoteDetailed.vue
+++ b/packages/client/src/components/MkNoteDetailed.vue
@@ -10,27 +10,27 @@
 		:class="{ renote: isRenote }"
 	>
 		<MkNoteSub
-			v-if="conversation"
 			v-for="note in conversation"
+			v-if="conversation"
 			:key="note.id"
 			class="reply-to"
 			:note="note"
-			:detailedView="true"
+			:detailed-view="true"
 		/>
 		<MkLoading v-else-if="note.reply" mini />
 		<MkNoteSub
 			v-if="note.reply"
 			:note="note.reply"
 			class="reply-to"
-			:detailedView="true"
+			:detailed-view="true"
 		/>
 
 		<MkNote
 			ref="noteEl"
-			@contextmenu.stop="onContextmenu"
 			tabindex="-1"
 			:note="note"
-			detailedView
+			detailed-view
+			@contextmenu.stop="onContextmenu"
 		></MkNote>
 
 		<MkTab v-model="tab" :style="'underline'" @update:modelValue="loadTab">
@@ -41,22 +41,22 @@
 				}}</span>
 				{{ i18n.ts._notification._types.reply }}
 			</option>
-			<option value="renotes" v-if="note.renoteCount > 0">
+			<option v-if="note.renoteCount > 0" value="renotes">
 				<!-- <i class="ph-repeat ph-bold ph-lg"></i> -->
 				<span class="count">{{ note.renoteCount }}</span>
 				{{ i18n.ts._notification._types.renote }}
 			</option>
-			<option value="reactions" v-if="reactionsCount > 0">
+			<option v-if="reactionsCount > 0" value="reactions">
 				<!-- <i class="ph-smiley ph-bold ph-lg"></i> -->
 				<span class="count">{{ reactionsCount }}</span>
 				{{ i18n.ts.reaction }}
 			</option>
-			<option value="quotes" v-if="directQuotes?.length > 0">
+			<option v-if="directQuotes?.length > 0" value="quotes">
 				<!-- <i class="ph-quotes ph-bold ph-lg"></i> -->
 				<span class="count">{{ directQuotes.length }}</span>
 				{{ i18n.ts._notification._types.quote }}
 			</option>
-			<option value="clips" v-if="clips?.length > 0">
+			<option v-if="clips?.length > 0" value="clips">
 				<!-- <i class="ph-paperclip ph-bold ph-lg"></i> -->
 				<span class="count">{{ clips.length }}</span>
 				{{ i18n.ts.clips }}
@@ -64,26 +64,26 @@
 		</MkTab>
 
 		<MkNoteSub
-			v-if="directReplies && tab === 'replies'"
 			v-for="note in directReplies"
+			v-if="directReplies && tab === 'replies'"
 			:key="note.id"
 			:note="note"
 			class="reply"
 			:conversation="replies"
-			:detailedView="true"
-			:parentId="note.id"
+			:detailed-view="true"
+			:parent-id="note.id"
 		/>
 		<MkLoading v-else-if="tab === 'replies' && note.repliesCount > 0" />
 
 		<MkNoteSub
-			v-if="directQuotes && tab === 'quotes'"
 			v-for="note in directQuotes"
+			v-if="directQuotes && tab === 'quotes'"
 			:key="note.id"
 			:note="note"
 			class="reply"
 			:conversation="replies"
-			:detailedView="true"
-			:parentId="note.id"
+			:detailed-view="true"
+			:parent-id="note.id"
 		/>
 		<MkLoading v-else-if="tab === 'quotes' && directQuotes.length > 0" />
 
@@ -94,8 +94,8 @@
 			:pagination="pagination"
 		> -->
 		<MkUserCardMini
-			v-if="tab === 'renotes' && renotes"
 			v-for="item in renotes"
+			v-if="tab === 'renotes' && renotes"
 			:key="item.user.id"
 			:user="item.user"
 			:with-chart="false"
@@ -151,11 +151,12 @@
 
 <script lang="ts" setup>
 import { onMounted, onUnmounted, onUpdated, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
+import type { NoteUpdatedEvent } from "firefish-js/built/streaming.types";
 import MkTab from "@/components/MkTab.vue";
 import MkNote from "@/components/MkNote.vue";
 import MkNoteSub from "@/components/MkNoteSub.vue";
-import XRenoteButton from "@/components/MkRenoteButton.vue";
+import type XRenoteButton from "@/components/MkRenoteButton.vue";
 import MkUserCardMini from "@/components/MkUserCardMini.vue";
 import MkReactedUsers from "@/components/MkReactedUsers.vue";
 import { pleaseLogin } from "@/scripts/please-login";
@@ -170,16 +171,15 @@ import { getNoteMenu } from "@/scripts/get-note-menu";
 import { useNoteCapture } from "@/scripts/use-note-capture";
 import { deepClone } from "@/scripts/clone";
 import { stream } from "@/stream";
-import { NoteUpdatedEvent } from "firefish-js/built/streaming.types";
 
 const props = defineProps<{
 	note: misskey.entities.Note;
 	pinned?: boolean;
 }>();
 
-let tab = ref("replies");
+const tab = ref("replies");
 
-let note = ref(deepClone(props.note));
+const note = ref(deepClone(props.note));
 
 const softMuteReasonI18nSrc = (what?: string) => {
 	if (what === "note") return i18n.ts.userSaysSomethingReason;
@@ -214,12 +214,12 @@ const muted = ref(
 );
 const translation = ref(null);
 const translating = ref(false);
-let conversation = ref<null | misskey.entities.Note[]>([]);
+const conversation = ref<null | misskey.entities.Note[]>([]);
 const replies = ref<misskey.entities.Note[]>([]);
-let directReplies = ref<null | misskey.entities.Note[]>([]);
-let directQuotes = ref<null | misskey.entities.Note[]>([]);
-let clips = ref();
-let renotes = ref();
+const directReplies = ref<null | misskey.entities.Note[]>([]);
+const directQuotes = ref<null | misskey.entities.Note[]>([]);
+const clips = ref();
+const renotes = ref();
 let isScrolling;
 
 const reactionsCount = Object.values(props.note.reactions).reduce(
@@ -238,7 +238,7 @@ const keymap = {
 
 useNoteCapture({
 	rootEl: el,
-	note: note,
+	note,
 	isDeletedRef: isDeleted,
 });
 
@@ -260,7 +260,7 @@ function react(viaKeyboard = false): void {
 		(reaction) => {
 			os.api("notes/reactions/create", {
 				noteId: note.value.id,
-				reaction: reaction,
+				reaction,
 			});
 		},
 		() => {
diff --git a/packages/client/src/components/MkNoteHeader.vue b/packages/client/src/components/MkNoteHeader.vue
index a0ccedd603..c3429bddff 100644
--- a/packages/client/src/components/MkNoteHeader.vue
+++ b/packages/client/src/components/MkNoteHeader.vue
@@ -49,7 +49,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import type * as misskey from "firefish-js";
 import { defaultStore } from "@/store";
 import MkVisibility from "@/components/MkVisibility.vue";
@@ -63,7 +62,7 @@ const props = defineProps<{
 	pinned?: boolean;
 }>();
 
-let note = ref(props.note);
+const note = ref(props.note);
 
 const showTicker =
 	defaultStore.state.instanceTicker === "always" ||
diff --git a/packages/client/src/components/MkNotePreview.vue b/packages/client/src/components/MkNotePreview.vue
index 607df89eb9..88ea43a9fe 100644
--- a/packages/client/src/components/MkNotePreview.vue
+++ b/packages/client/src/components/MkNotePreview.vue
@@ -1,6 +1,6 @@
 <template>
 	<div v-size="{ min: [350, 500] }" class="fefdfafb">
-		<MkAvatar class="avatar" :user="$i" disableLink />
+		<MkAvatar class="avatar" :user="$i" disable-link />
 		<div class="main">
 			<div class="header">
 				<MkUserName :user="$i" />
@@ -11,7 +11,7 @@
 						:text="preprocess(text).trim()"
 						:author="$i"
 						:i="$i"
-						advancedMfm
+						advanced-mfm
 					/>
 				</div>
 			</div>
diff --git a/packages/client/src/components/MkNoteSimple.vue b/packages/client/src/components/MkNoteSimple.vue
index b8f4a218aa..280abe25a4 100644
--- a/packages/client/src/components/MkNoteSimple.vue
+++ b/packages/client/src/components/MkNoteSimple.vue
@@ -11,7 +11,7 @@
 </template>
 
 <script lang="ts" setup>
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import XNoteHeader from "@/components/MkNoteHeader.vue";
 import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
 
diff --git a/packages/client/src/components/MkNoteSub.vue b/packages/client/src/components/MkNoteSub.vue
index 5d73ac24b4..11db10dddf 100644
--- a/packages/client/src/components/MkNoteSub.vue
+++ b/packages/client/src/components/MkNoteSub.vue
@@ -1,10 +1,10 @@
 <template>
 	<article
 		v-if="!muted.muted || muted.what === 'reply'"
+		:id="detailedView ? appearNote.id : null"
 		ref="el"
 		v-size="{ max: [450, 500] }"
 		class="wrpstxzv"
-		:id="detailedView ? appearNote.id : null"
 		tabindex="-1"
 		:class="{
 			children: depth > 1,
@@ -16,8 +16,8 @@
 		<div v-if="conversation && depth > 1" class="line"></div>
 		<div
 			class="main"
-			@click="noteClick"
 			:style="{ cursor: expandOnNoteClick ? 'pointer' : '' }"
+			@click="noteClick"
 		>
 			<div class="avatar-container">
 				<MkAvatar class="avatar" :user="appearNote.user" />
@@ -32,9 +32,9 @@
 					<MkSubNoteContent
 						class="text"
 						:note="note"
-						:parentId="parentId"
+						:parent-id="parentId"
 						:conversation="conversation"
-						:detailedView="detailedView"
+						:detailed-view="detailedView"
 						@focusfooter="footerEl.focus()"
 					/>
 					<div v-if="translating || translation" class="translation">
@@ -117,9 +117,9 @@
 							appearNote.myReaction != null
 						"
 						ref="reactButton"
+						v-tooltip.noDelay.bottom="i18n.ts.removeReaction"
 						class="button _button reacted"
 						@click.stop="undoReact(appearNote)"
-						v-tooltip.noDelay.bottom="i18n.ts.removeReaction"
 					>
 						<i class="ph-minus ph-bold ph-lg"></i>
 					</button>
@@ -137,17 +137,17 @@
 		</div>
 		<template v-if="conversation">
 			<MkNoteSub
-				v-if="replyLevel < 11 && depth < 5"
 				v-for="reply in replies"
+				v-if="replyLevel < 11 && depth < 5"
 				:key="reply.id"
 				:note="reply"
 				class="reply"
 				:class="{ single: replies.length == 1 }"
 				:conversation="conversation"
 				:depth="replies.length == 1 ? depth : depth + 1"
-				:replyLevel="replyLevel + 1"
-				:parentId="appearNote.id"
-				:detailedView="detailedView"
+				:reply-level="replyLevel + 1"
+				:parent-id="appearNote.id"
+				:detailed-view="detailedView"
 			/>
 			<div v-else-if="replies.length > 0" class="more">
 				<div class="line"></div>
@@ -177,9 +177,9 @@
 </template>
 
 <script lang="ts" setup>
-import { inject, ref, computed } from "vue";
+import { computed, inject, ref } from "vue";
 import type { Ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import XNoteHeader from "@/components/MkNoteHeader.vue";
 import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
 import XReactionsViewer from "@/components/MkReactionsViewer.vue";
@@ -223,7 +223,7 @@ const props = withDefaults(
 	},
 );
 
-let note = ref(deepClone(props.note));
+const note = ref(deepClone(props.note));
 
 const softMuteReasonI18nSrc = (what?: string) => {
 	if (what === "note") return i18n.ts.userSaysSomethingReason;
@@ -247,7 +247,7 @@ const menuButton = ref<HTMLElement>();
 const starButton = ref<InstanceType<typeof XStarButton>>();
 const renoteButton = ref<InstanceType<typeof XRenoteButton>>();
 const reactButton = ref<HTMLElement>();
-let appearNote = computed(() =>
+const appearNote = computed(() =>
 	isRenote ? (note.value.renote as misskey.entities.Note) : note.value,
 );
 const isDeleted = ref(false);
@@ -291,7 +291,7 @@ function react(viaKeyboard = false): void {
 		(reaction) => {
 			os.api("notes/reactions/create", {
 				noteId: appearNote.value.id,
-				reaction: reaction,
+				reaction,
 			});
 		},
 		() => {
diff --git a/packages/client/src/components/MkNotes.vue b/packages/client/src/components/MkNotes.vue
index 5916621840..07881b2e6e 100644
--- a/packages/client/src/components/MkNotes.vue
+++ b/packages/client/src/components/MkNotes.vue
@@ -12,7 +12,7 @@
 		</template>
 
 		<template #default="{ items: notes }">
-			<div class="giivymft" :class="{ noGap }" ref="tlEl">
+			<div ref="tlEl" class="giivymft" :class="{ noGap }">
 				<XList
 					ref="notes"
 					v-slot="{ item: note }"
diff --git a/packages/client/src/components/MkNotification.vue b/packages/client/src/components/MkNotification.vue
index 76fbdd29fe..d89e27c88a 100644
--- a/packages/client/src/components/MkNotification.vue
+++ b/packages/client/src/components/MkNotification.vue
@@ -219,7 +219,7 @@
 					<MkFollowButton
 						:user="notification.user"
 						:full="true"
-						:hideMenu="true"
+						:hide-menu="true"
 					/></div
 			></span>
 			<span
@@ -273,8 +273,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, onMounted, onUnmounted, watch } from "vue";
-import * as misskey from "firefish-js";
+import { onMounted, onUnmounted, ref, watch } from "vue";
+import type * as misskey from "firefish-js";
 import XReactionIcon from "@/components/MkReactionIcon.vue";
 import MkFollowButton from "@/components/MkFollowButton.vue";
 import XReactionTooltip from "@/components/MkReactionTooltip.vue";
@@ -310,8 +310,7 @@ const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReact
 	? instance.defaultReaction
 	: "⭐";
 
-let readObserver: IntersectionObserver | undefined;
-let connection;
+let readObserver: IntersectionObserver | undefined, connection;
 
 onMounted(() => {
 	if (!props.notification.isRead) {
diff --git a/packages/client/src/components/MkNotificationSettingWindow.vue b/packages/client/src/components/MkNotificationSettingWindow.vue
index 9131a67780..df5d162466 100644
--- a/packages/client/src/components/MkNotificationSettingWindow.vue
+++ b/packages/client/src/components/MkNotificationSettingWindow.vue
@@ -41,7 +41,6 @@
 <script lang="ts" setup>
 import { computed, ref } from "vue";
 
-import {} from "vue";
 import { notificationTypes } from "firefish-js";
 import MkSwitch from "./form/switch.vue";
 import MkInfo from "./MkInfo.vue";
@@ -65,12 +64,12 @@ const props = withDefaults(
 	},
 );
 
-let includingTypes = computed(() => props.includingTypes || []);
+const includingTypes = computed(() => props.includingTypes || []);
 
 const dialog = ref<InstanceType<typeof XModalWindow>>();
 
-let typesMap = ref<Record<(typeof notificationTypes)[number], boolean>>({});
-let useGlobalSetting = ref(
+const typesMap = ref<Record<(typeof notificationTypes)[number], boolean>>({});
+const useGlobalSetting = ref(
 	(includingTypes.value === null || includingTypes.value.length === 0) &&
 		props.showGlobalToggle,
 );
diff --git a/packages/client/src/components/MkNotificationToast.vue b/packages/client/src/components/MkNotificationToast.vue
index d6ee9ea6b3..491595e231 100644
--- a/packages/client/src/components/MkNotificationToast.vue
+++ b/packages/client/src/components/MkNotificationToast.vue
@@ -28,7 +28,7 @@ const emit = defineEmits<{
 }>();
 
 const zIndex = os.claimZIndex("high");
-let showing = ref(true);
+const showing = ref(true);
 
 onMounted(() => {
 	window.setTimeout(() => {
diff --git a/packages/client/src/components/MkNotifications.vue b/packages/client/src/components/MkNotifications.vue
index f136696126..980eb1040d 100644
--- a/packages/client/src/components/MkNotifications.vue
+++ b/packages/client/src/components/MkNotifications.vue
@@ -26,7 +26,7 @@
 					"
 					:key="notification.id"
 					:note="notification.note"
-					:collapsedReply="
+					:collapsed-reply="
 						notification.type === 'reply' ||
 						(notification.type === 'mention' &&
 							notification.note.replyId != null)
@@ -46,9 +46,10 @@
 </template>
 
 <script lang="ts" setup>
-import { onUnmounted, onMounted, computed, ref } from "vue";
-import { notificationTypes } from "firefish-js";
-import MkPagination, { Paging } from "@/components/MkPagination.vue";
+import { computed, onMounted, onUnmounted, ref } from "vue";
+import type { notificationTypes } from "firefish-js";
+import type { Paging } from "@/components/MkPagination.vue";
+import MkPagination from "@/components/MkPagination.vue";
 import XNotification from "@/components/MkNotification.vue";
 import XList from "@/components/MkDateSeparatedList.vue";
 import XNote from "@/components/MkNote.vue";
diff --git a/packages/client/src/components/MkPageWindow.vue b/packages/client/src/components/MkPageWindow.vue
index dc4d29c895..47c9db522f 100644
--- a/packages/client/src/components/MkPageWindow.vue
+++ b/packages/client/src/components/MkPageWindow.vue
@@ -8,8 +8,8 @@
 		:buttons-left="buttonsLeft"
 		:buttons-right="buttonsRight"
 		:contextmenu="contextmenu"
-		@closed="$emit('closed')"
 		class="page-window"
+		@closed="$emit('closed')"
 	>
 		<template #header>
 			<template v-if="pageMetadata?.value">
@@ -30,7 +30,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ComputedRef, provide, ref, computed } from "vue";
+import type { ComputedRef } from "vue";
+import { computed, provide, ref } from "vue";
 import RouterView from "@/components/global/RouterView.vue";
 import XWindow from "@/components/MkWindow.vue";
 import { popout as _popout } from "@/scripts/popout";
@@ -39,7 +40,8 @@ import { url } from "@/config";
 import { mainRouter, routes } from "@/router";
 import { Router } from "@/nirax";
 import { i18n } from "@/i18n";
-import { PageMetadata, provideMetadataReceiver } from "@/scripts/page-metadata";
+import type { PageMetadata } from "@/scripts/page-metadata";
+import { provideMetadataReceiver } from "@/scripts/page-metadata";
 
 const props = defineProps<{
 	initialPath: string;
@@ -51,8 +53,8 @@ defineEmits<{
 
 const router = new Router(routes, props.initialPath);
 
-let pageMetadata = ref<null | ComputedRef<PageMetadata>>();
-let windowEl = ref<InstanceType<typeof XWindow>>();
+const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
+const windowEl = ref<InstanceType<typeof XWindow>>();
 const history = ref<{ path: string; key: any }[]>([
 	{
 		path: router.getCurrentPath(),
diff --git a/packages/client/src/components/MkPagination.vue b/packages/client/src/components/MkPagination.vue
index 2d9aeb72e8..6acc5b2851 100644
--- a/packages/client/src/components/MkPagination.vue
+++ b/packages/client/src/components/MkPagination.vue
@@ -63,29 +63,22 @@
 </template>
 
 <script lang="ts" setup>
-import {
-	computed,
-	ComputedRef,
-	isRef,
-	onActivated,
-	onDeactivated,
-	ref,
-	watch,
-} from "vue";
-import * as misskey from "firefish-js";
+import type { ComputedRef } from "vue";
+import { computed, isRef, onActivated, onDeactivated, ref, watch } from "vue";
+import type * as misskey from "firefish-js";
 import * as os from "@/os";
 import {
-	onScrollTop,
-	isTopVisible,
-	getScrollPosition,
 	getScrollContainer,
+	getScrollPosition,
+	isTopVisible,
+	onScrollTop,
 } from "@/scripts/scroll";
 import MkButton from "@/components/MkButton.vue";
 import { i18n } from "@/i18n";
 
-export type Paging<
+export interface Paging<
 	E extends keyof misskey.Endpoints = keyof misskey.Endpoints,
-> = {
+> {
 	endpoint: E;
 	limit: number;
 	params?:
@@ -104,7 +97,7 @@ export type Paging<
 	reversed?: boolean;
 
 	offsetMode?: boolean;
-};
+}
 
 const SECOND_FETCH_LIMIT = 30;
 
@@ -123,7 +116,10 @@ const emit = defineEmits<{
 	(ev: "queue", count: number): void;
 }>();
 
-type Item = { id: string; [another: string]: unknown };
+interface Item {
+	id: string;
+	[another: string]: unknown;
+}
 
 const rootEl = ref<HTMLElement>();
 const items = ref<Item[]>([]);
@@ -207,12 +203,12 @@ const refresh = async (): void => {
 		})
 		.then(
 			(res) => {
-				let ids = items.value.reduce(
+				const ids = items.value.reduce(
 					(a, b) => {
 						a[b.id] = true;
 						return a;
 					},
-					{} as { [id: string]: boolean },
+					{} as Record<string, boolean>,
 				);
 
 				for (let i = 0; i < res.length; i++) {
@@ -364,7 +360,7 @@ const prepend = (item: Item): void => {
 					// オーバーフローしたら古いアイテムは捨てる
 					if (items.value.length >= props.displayLimit) {
 						// このやり方だとVue 3.2以降アニメーションが動かなくなる
-						//items.value = items.value.slice(-props.displayLimit);
+						// items.value = items.value.slice(-props.displayLimit);
 						while (items.value.length >= props.displayLimit) {
 							items.value.shift();
 						}
@@ -394,7 +390,7 @@ const prepend = (item: Item): void => {
 			// オーバーフローしたら古いアイテムは捨てる
 			if (items.value.length >= props.displayLimit) {
 				// このやり方だとVue 3.2以降アニメーションが動かなくなる
-				//this.items = items.value.slice(0, props.displayLimit);
+				// this.items = items.value.slice(0, props.displayLimit);
 				while (items.value.length >= props.displayLimit) {
 					items.value.pop();
 				}
diff --git a/packages/client/src/components/MkPoll.vue b/packages/client/src/components/MkPoll.vue
index 899e6c2dac..8eb83a2dce 100644
--- a/packages/client/src/components/MkPoll.vue
+++ b/packages/client/src/components/MkPoll.vue
@@ -53,7 +53,7 @@
 
 <script lang="ts" setup>
 import { computed, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import { sum } from "@/scripts/array";
 import { pleaseLogin } from "@/scripts/please-login";
 import * as os from "@/os";
diff --git a/packages/client/src/components/MkPollEditor.vue b/packages/client/src/components/MkPollEditor.vue
index de691ba889..51d0a80d3c 100644
--- a/packages/client/src/components/MkPollEditor.vue
+++ b/packages/client/src/components/MkPollEditor.vue
@@ -16,8 +16,8 @@
 				</MkInput>
 				<button
 					class="_button"
-					@click="remove(i)"
 					:aria-label="i18n.t('remove')"
+					@click="remove(i)"
 				>
 					<i class="ph-x ph-bold ph-lg"></i>
 				</button>
diff --git a/packages/client/src/components/MkPopupMenu.vue b/packages/client/src/components/MkPopupMenu.vue
index 9537ac9edf..9a98648ea2 100644
--- a/packages/client/src/components/MkPopupMenu.vue
+++ b/packages/client/src/components/MkPopupMenu.vue
@@ -5,9 +5,9 @@
 		:z-priority="'high'"
 		:src="src"
 		:transparent-bg="true"
+		tabindex="-1"
 		@click="modal?.close()"
 		@closed="emit('closed')"
-		tabindex="-1"
 	>
 		<MkMenu
 			:items="items"
@@ -28,7 +28,7 @@ import { ref } from "vue";
 
 import MkModal from "./MkModal.vue";
 import MkMenu from "./MkMenu.vue";
-import { MenuItem } from "@/types/menu";
+import type { MenuItem } from "@/types/menu";
 
 defineProps<{
 	items: MenuItem[];
@@ -43,7 +43,7 @@ const emit = defineEmits<{
 	(ev: "closed"): void;
 }>();
 
-let modal = ref<InstanceType<typeof MkModal>>();
+const modal = ref<InstanceType<typeof MkModal>>();
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue
index a65f48d568..9e08edbefe 100644
--- a/packages/client/src/components/MkPostForm.vue
+++ b/packages/client/src/components/MkPostForm.vue
@@ -86,8 +86,8 @@
 				{{ i18n.ts.quoteAttached
 				}}<button
 					class="_button"
-					@click="quoteId = null"
 					:aria-label="i18n.t('removeQuote')"
+					@click="quoteId = null"
 				>
 					<i class="ph-x ph-bold ph-lg"></i>
 				</button>
@@ -99,8 +99,8 @@
 						<MkAcct :user="u" />
 						<button
 							class="_button"
-							@click="removeVisibleUser(u)"
 							:aria-label="i18n.t('removeRecipient')"
+							@click="removeVisibleUser(u)"
 						>
 							<i class="ph-x ph-bold ph-lg"></i>
 						</button>
@@ -234,16 +234,16 @@
 
 <script lang="ts" setup>
 import {
+	computed,
+	defineAsyncComponent,
 	inject,
-	watch,
 	nextTick,
 	onMounted,
-	defineAsyncComponent,
 	ref,
-	computed,
+	watch,
 } from "vue";
 import * as mfm from "mfm-js";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import autosize from "autosize";
 import insertTextAtCursor from "insert-text-at-cursor";
 import { length } from "stringz";
@@ -315,40 +315,42 @@ const cwInputEl = ref<HTMLInputElement | null>(null);
 const hashtagsInputEl = ref<HTMLInputElement | null>(null);
 const visibilityButton = ref<HTMLElement | null>(null);
 
-let posting = ref(false);
-let text = ref(props.initialText ?? "");
-let files = ref(props.initialFiles ?? []);
-let poll = ref<{
+const posting = ref(false);
+const text = ref(props.initialText ?? "");
+const files = ref(props.initialFiles ?? []);
+const poll = ref<{
 	choices: string[];
 	multiple: boolean;
 	expiresAt: string | null;
 	expiredAfter: string | null;
 } | null>(null);
-let useCw = ref(false);
-let showPreview = ref(false);
-let cw = ref<string | null>(null);
-let localOnly = ref<boolean>(
+const useCw = ref(false);
+const showPreview = ref(false);
+const cw = ref<string | null>(null);
+const localOnly = ref<boolean>(
 	props.initialLocalOnly ?? defaultStore.state.rememberNoteVisibility
 		? defaultStore.state.localOnly
 		: defaultStore.state.defaultNoteLocalOnly,
 );
-let visibility = ref(
+const visibility = ref(
 	props.initialVisibility ??
 		((defaultStore.state.rememberNoteVisibility
 			? defaultStore.state.visibility
 			: defaultStore.state
 					.defaultNoteVisibility) as (typeof misskey.noteVisibilities)[number]),
 );
-let visibleUsers = ref([]);
+const visibleUsers = ref([]);
 if (props.initialVisibleUsers) {
 	props.initialVisibleUsers.forEach(pushVisibleUser);
 }
-let autocomplete = ref(null);
-let draghover = ref(false);
-let quoteId = ref(null);
-let hasNotSpecifiedMentions = ref(false);
-let recentHashtags = ref(JSON.parse(localStorage.getItem("hashtags") || "[]"));
-let imeText = ref("");
+const autocomplete = ref(null);
+const draghover = ref(false);
+const quoteId = ref(null);
+const hasNotSpecifiedMentions = ref(false);
+const recentHashtags = ref(
+	JSON.parse(localStorage.getItem("hashtags") || "[]"),
+);
+const imeText = ref("");
 
 const typing = throttle(3000, () => {
 	if (props.channel) {
@@ -415,8 +417,8 @@ const maxTextLength = computed((): number => {
 const canPost = computed((): boolean => {
 	return (
 		!posting.value &&
-		(1 <= textLength.value ||
-			1 <= files.value.length ||
+		(textLength.value >= 1 ||
+			files.value.length >= 1 ||
 			!!poll.value ||
 			!!props.renote) &&
 		textLength.value <= maxTextLength.value &&
@@ -816,14 +818,14 @@ function onDrop(ev): void {
 		return;
 	}
 
-	//#region ドライブのファイル
+	// #region ドライブのファイル
 	const driveFile = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 	if (driveFile != null && driveFile !== "") {
 		const file = JSON.parse(driveFile);
 		files.value.push(file);
 		ev.preventDefault();
 	}
-	//#endregion
+	// #endregion
 }
 
 function saveDraft() {
@@ -896,7 +898,7 @@ async function post() {
 		}
 	}
 
-	let token = undefined;
+	let token;
 
 	if (postAccount.value) {
 		const storedAccounts = await getAccounts();
@@ -976,7 +978,7 @@ function showActions(ev) {
 	);
 }
 
-let postAccount = ref<misskey.entities.UserDetailed | null>(null);
+const postAccount = ref<misskey.entities.UserDetailed | null>(null);
 
 function openAccountMenu(ev: MouseEvent) {
 	openAccountMenu_(
diff --git a/packages/client/src/components/MkPostFormAttaches.vue b/packages/client/src/components/MkPostFormAttaches.vue
index a1cb191de7..9ab02558ee 100644
--- a/packages/client/src/components/MkPostFormAttaches.vue
+++ b/packages/client/src/components/MkPostFormAttaches.vue
@@ -8,9 +8,9 @@
 			delay-on-touch-only="true"
 		>
 			<div
-				class="file"
 				v-for="element in _files"
 				:key="element.id"
+				class="file"
 				@click="showFileMenu(element, $event)"
 				@contextmenu.prevent="showFileMenu(element, $event)"
 			>
@@ -30,7 +30,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, ref, computed } from "vue";
+import { computed, defineAsyncComponent } from "vue";
 import { VueDraggable } from "vue-draggable-plus";
 import MkDriveFileThumbnail from "@/components/MkDriveFileThumbnail.vue";
 import * as os from "@/os";
@@ -105,10 +105,11 @@ async function describe(file) {
 		{
 			done: (result) => {
 				if (!result || result.canceled) return;
-				let comment = result.result.length === 0 ? null : result.result;
+				const comment =
+					result.result.length === 0 ? null : result.result;
 				os.api("drive/files/update", {
 					fileId: file.id,
-					comment: comment,
+					comment,
 				}).then(() => {
 					file.comment = comment;
 				});
diff --git a/packages/client/src/components/MkPostFormDialog.vue b/packages/client/src/components/MkPostFormDialog.vue
index 9e43aef4fb..1dd90eebed 100644
--- a/packages/client/src/components/MkPostFormDialog.vue
+++ b/packages/client/src/components/MkPostFormDialog.vue
@@ -21,8 +21,7 @@
 <script lang="ts" setup>
 import { shallowRef } from "vue";
 
-import {} from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkModal from "@/components/MkModal.vue";
 import MkPostForm from "@/components/MkPostForm.vue";
 
@@ -48,8 +47,8 @@ const emit = defineEmits<{
 	(ev: "closed"): void;
 }>();
 
-let modal = shallowRef<InstanceType<typeof MkModal>>();
-let form = shallowRef<InstanceType<typeof MkPostForm>>();
+const modal = shallowRef<InstanceType<typeof MkModal>>();
+const form = shallowRef<InstanceType<typeof MkPostForm>>();
 
 function onPosted() {
 	modal.value.close({
diff --git a/packages/client/src/components/MkPushNotificationAllowButton.vue b/packages/client/src/components/MkPushNotificationAllowButton.vue
index f911cfe41e..37ba5ceef3 100644
--- a/packages/client/src/components/MkPushNotificationAllowButton.vue
+++ b/packages/client/src/components/MkPushNotificationAllowButton.vue
@@ -76,12 +76,12 @@ defineProps<{
 }>();
 
 // ServiceWorker registration
-let registration = ref<ServiceWorkerRegistration | undefined>();
+const registration = ref<ServiceWorkerRegistration | undefined>();
 // If this browser supports push notification
-let supported = ref(false);
+const supported = ref(false);
 // If this browser has already subscribed to push notification
-let pushSubscription = ref<PushSubscription | null>(null);
-let pushRegistrationInServer = ref<
+const pushSubscription = ref<PushSubscription | null>(null);
+const pushRegistrationInServer = ref<
 	| {
 			state?: string;
 			key?: string;
@@ -209,6 +209,6 @@ if (navigator.serviceWorker == null) {
 }
 
 defineExpose({
-	pushRegistrationInServer: pushRegistrationInServer,
+	pushRegistrationInServer,
 });
 </script>
diff --git a/packages/client/src/components/MkReactedUsers.vue b/packages/client/src/components/MkReactedUsers.vue
index ab740c8592..3b0c7f0d08 100644
--- a/packages/client/src/components/MkReactedUsers.vue
+++ b/packages/client/src/components/MkReactedUsers.vue
@@ -36,8 +36,8 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, watch, ref } from "vue";
-import * as misskey from "firefish-js";
+import { onMounted, ref, watch } from "vue";
+import type * as misskey from "firefish-js";
 import MkReactionIcon from "@/components/MkReactionIcon.vue";
 import MkUserCardMini from "@/components/MkUserCardMini.vue";
 import * as os from "@/os";
@@ -46,10 +46,10 @@ const props = defineProps<{
 	noteId: misskey.entities.Note["id"];
 }>();
 
-let note = ref<misskey.entities.Note>();
-let tab = ref<string>();
-let reactions = ref<string[]>();
-let users = ref();
+const note = ref<misskey.entities.Note>();
+const tab = ref<string>();
+const reactions = ref<string[]>();
+const users = ref();
 
 watch(tab, async () => {
 	const res = await os.api("notes/reactions", {
diff --git a/packages/client/src/components/MkReactionsViewer.reaction.vue b/packages/client/src/components/MkReactionsViewer.reaction.vue
index 8dbdc86da9..3f7935e27c 100644
--- a/packages/client/src/components/MkReactionsViewer.reaction.vue
+++ b/packages/client/src/components/MkReactionsViewer.reaction.vue
@@ -22,7 +22,7 @@
 
 <script lang="ts" setup>
 import { computed, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import XDetails from "@/components/MkReactionsViewer.details.vue";
 import XReactionIcon from "@/components/MkReactionIcon.vue";
 import * as os from "@/os";
diff --git a/packages/client/src/components/MkReactionsViewer.vue b/packages/client/src/components/MkReactionsViewer.vue
index 4608628f1a..fc41499adf 100644
--- a/packages/client/src/components/MkReactionsViewer.vue
+++ b/packages/client/src/components/MkReactionsViewer.vue
@@ -18,7 +18,7 @@
 
 <script lang="ts" setup>
 import { computed, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import { $i } from "@/account";
 import XReaction from "@/components/MkReactionsViewer.reaction.vue";
 
diff --git a/packages/client/src/components/MkRenoteButton.vue b/packages/client/src/components/MkRenoteButton.vue
index c008137d8c..bf1275f3ff 100644
--- a/packages/client/src/components/MkRenoteButton.vue
+++ b/packages/client/src/components/MkRenoteButton.vue
@@ -12,9 +12,9 @@
 	</button>
 	<button
 		v-else
+		v-tooltip.noDelay.bottom="i18n.ts.disabled"
 		class="eddddedb _button"
 		disabled="true"
-		v-tooltip.noDelay.bottom="i18n.ts.disabled"
 	>
 		<i class="ph-repeat ph-bold ph-lg"></i>
 	</button>
@@ -31,7 +31,7 @@ import { $i } from "@/account";
 import { useTooltip } from "@/scripts/use-tooltip";
 import { i18n } from "@/i18n";
 import { defaultStore } from "@/store";
-import { MenuItem } from "@/types/menu";
+import type { MenuItem } from "@/types/menu";
 
 const props = defineProps<{
 	note: misskey.entities.Note;
@@ -70,7 +70,7 @@ useTooltip(buttonRef, async (showing) => {
 	);
 });
 
-let hasRenotedBefore = ref(false);
+const hasRenotedBefore = ref(false);
 os.api("notes/renotes", {
 	noteId: props.note.id,
 	userId: $i.id,
@@ -82,7 +82,7 @@ os.api("notes/renotes", {
 const renote = (viaKeyboard = false, ev?: MouseEvent) => {
 	pleaseLogin();
 
-	let buttonActions: Array<MenuItem> = [];
+	const buttonActions: Array<MenuItem> = [];
 
 	if (props.note.visibility === "public") {
 		buttonActions.push({
@@ -191,7 +191,7 @@ const renote = (viaKeyboard = false, ev?: MouseEvent) => {
 		});
 	}
 
-	if (canRenote) {
+	if (canRenote.value) {
 		buttonActions.push({
 			text: `${i18n.ts.renote} (${i18n.ts.local})`,
 			icon: "ph-hand-fist ph-bold ph-lg",
diff --git a/packages/client/src/components/MkShowMoreButton.vue b/packages/client/src/components/MkShowMoreButton.vue
index e2d9b7d499..9b817e1263 100644
--- a/packages/client/src/components/MkShowMoreButton.vue
+++ b/packages/client/src/components/MkShowMoreButton.vue
@@ -9,8 +9,8 @@
 	</button>
 </template>
 <script lang="ts" setup>
-import { i18n } from "@/i18n";
 import { ref } from "vue";
+import { i18n } from "@/i18n";
 
 const props = defineProps<{
 	modelValue: boolean;
diff --git a/packages/client/src/components/MkSignin.vue b/packages/client/src/components/MkSignin.vue
index b9e7a3d5cd..d7630f8d05 100644
--- a/packages/client/src/components/MkSignin.vue
+++ b/packages/client/src/components/MkSignin.vue
@@ -160,7 +160,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, ref, computed } from "vue";
+import { computed, defineAsyncComponent, ref } from "vue";
 import { toUnicode } from "punycode/";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
@@ -172,17 +172,17 @@ import { login } from "@/account";
 import { instance } from "@/instance";
 import { i18n } from "@/i18n";
 
-let signing = ref(false);
-let user = ref(null);
-let username = ref("");
-let password = ref("");
-let token = ref("");
-let host = ref(toUnicode(configHost));
-let totpLogin = ref(false);
-let challengeData = ref(null);
-let queryingKey = ref(false);
-let hCaptchaResponse = ref(null);
-let reCaptchaResponse = ref(null);
+const signing = ref(false);
+const user = ref(null);
+const username = ref("");
+const password = ref("");
+const token = ref("");
+const host = ref(toUnicode(configHost));
+const totpLogin = ref(false);
+const challengeData = ref(null);
+const queryingKey = ref(false);
+const hCaptchaResponse = ref(null);
+const reCaptchaResponse = ref(null);
 
 const meta = computed(() => instance);
 
diff --git a/packages/client/src/components/MkSigninDialog.vue b/packages/client/src/components/MkSigninDialog.vue
index 0afb1f7895..cecf605945 100644
--- a/packages/client/src/components/MkSigninDialog.vue
+++ b/packages/client/src/components/MkSigninDialog.vue
@@ -14,7 +14,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import MkSignin from "@/components/MkSignin.vue";
 import XModalWindow from "@/components/MkModalWindow.vue";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/components/MkSignup.vue b/packages/client/src/components/MkSignup.vue
index 274463a578..933a262043 100644
--- a/packages/client/src/components/MkSignup.vue
+++ b/packages/client/src/components/MkSignup.vue
@@ -284,7 +284,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
 import getPasswordStrength from "syuilo-password-strength";
 import { toUnicode } from "punycode/";
@@ -314,15 +314,15 @@ const emit = defineEmits<{
 
 const host = toUnicode(config.host);
 
-let hcaptcha = ref();
-let recaptcha = ref();
+const hcaptcha = ref();
+const recaptcha = ref();
 
-let username: string = ref("");
-let password: string = ref("");
-let retypedPassword: string = ref("");
-let invitationCode: string = ref("");
-let email = ref("");
-let usernameState:
+const username: string = ref("");
+const password: string = ref("");
+const retypedPassword: string = ref("");
+const invitationCode: string = ref("");
+const email = ref("");
+const usernameState:
 	| null
 	| "wait"
 	| "ok"
@@ -331,8 +331,8 @@ let usernameState:
 	| "invalid-format"
 	| "min-range"
 	| "max-range" = ref(null);
-let invitationState: null | "entered" = ref(null);
-let emailState:
+const invitationState: null | "entered" = ref(null);
+const emailState:
 	| null
 	| "wait"
 	| "ok"
@@ -343,12 +343,12 @@ let emailState:
 	| "unavailable:smtp"
 	| "unavailable"
 	| "error" = ref(null);
-let passwordStrength: "" | "low" | "medium" | "high" = ref("");
-let passwordRetypeState: null | "match" | "not-match" = ref(null);
-let submitting: boolean = ref(false);
-let ToSAgreement: boolean = ref(false);
-let hCaptchaResponse = ref(null);
-let reCaptchaResponse = ref(null);
+const passwordStrength: "" | "low" | "medium" | "high" = ref("");
+const passwordRetypeState: null | "match" | "not-match" = ref(null);
+const submitting: boolean = ref(false);
+const ToSAgreement: boolean = ref(false);
+const hCaptchaResponse = ref(null);
+const reCaptchaResponse = ref(null);
 
 const shouldDisableSubmitting = computed((): boolean => {
 	return (
diff --git a/packages/client/src/components/MkSparkle.vue b/packages/client/src/components/MkSparkle.vue
index 6cfe4401a7..f97a9d686d 100644
--- a/packages/client/src/components/MkSparkle.vue
+++ b/packages/client/src/components/MkSparkle.vue
@@ -79,8 +79,8 @@ const el = ref<HTMLElement>();
 const width = ref(0);
 const height = ref(0);
 const colors = ["#eb6f92", "#9ccfd8", "#f6c177", "#f6c177", "#f6c177"];
-let stop = false;
-let ro: ResizeObserver | undefined;
+let stop = false,
+	ro: ResizeObserver | undefined;
 
 onMounted(() => {
 	if (!reducedMotion()) {
diff --git a/packages/client/src/components/MkStarButtonNoEmoji.vue b/packages/client/src/components/MkStarButtonNoEmoji.vue
index aa4dea64b6..1e29ca5e26 100644
--- a/packages/client/src/components/MkStarButtonNoEmoji.vue
+++ b/packages/client/src/components/MkStarButtonNoEmoji.vue
@@ -1,9 +1,9 @@
 <template>
 	<button
+		ref="buttonRef"
 		v-tooltip.noDelay.bottom="i18n.ts._gallery.like"
 		class="button _button"
 		:class="$style.root"
-		ref="buttonRef"
 		@click.stop="toggleStar($event)"
 	>
 		<span v-if="!reacted">
diff --git a/packages/client/src/components/MkSubNoteContent.vue b/packages/client/src/components/MkSubNoteContent.vue
index 2ffc9483b7..394dfb34c7 100644
--- a/packages/client/src/components/MkSubNoteContent.vue
+++ b/packages/client/src/components/MkSubNoteContent.vue
@@ -13,13 +13,13 @@
 		</MkA>
 		<MkA
 			v-else-if="!detailed && note.replyId"
+			v-tooltip="i18n.ts.jumpToPrevious"
 			:to="
 				detailedView
 					? `#${note.replyId}`
 					: `${notePage(note)}#${note.replyId}`
 			"
 			behavior="browser"
-			v-tooltip="i18n.ts.jumpToPrevious"
 			class="reply-icon"
 			@click.stop
 		>
@@ -46,18 +46,18 @@
 			}"
 		>
 			<XShowMoreButton
-				ref="showMoreButton"
 				v-if="isLong && collapsed"
+				ref="showMoreButton"
 				v-model="collapsed"
-				v-on:keydown="focusFooter"
+				@keydown="focusFooter"
 			></XShowMoreButton>
 			<XCwButton
-				ref="cwButton"
 				v-if="note.cw && !showContent"
+				ref="cwButton"
 				v-model="showContent"
 				:note="note"
-				v-on:keydown="focusFooter"
-				v-on:update:model-value="(val) => emit('expanded', val)"
+				@keydown="focusFooter"
+				@update:model-value="(val) => emit('expanded', val)"
 			/>
 			<div
 				class="body"
@@ -85,13 +85,13 @@
 					</MkA>
 					<MkA
 						v-else-if="!detailed && note.replyId"
+						v-tooltip="i18n.ts.jumpToPrevious"
 						:to="
 							detailedView
 								? `#${note.replyId}`
 								: `${notePage(note)}#${note.replyId}`
 						"
 						behavior="browser"
-						v-tooltip="i18n.ts.jumpToPrevious"
 						class="reply-icon"
 						@click.stop
 					>
@@ -139,7 +139,7 @@
 						(showMoreButton && collapsed)
 					"
 					tabindex="0"
-					v-on:focus="
+					@focus="
 						cwButton?.focus();
 						showMoreButton?.focus();
 					"
@@ -157,9 +157,9 @@
 		</div>
 		<MkButton
 			v-if="hasMfm && defaultStore.state.animatedMfm"
-			@click.stop="toggleMfm"
 			mini
 			rounded
+			@click.stop="toggleMfm"
 		>
 			<template v-if="disableMfm">
 				<i class="ph-play ph-bold"></i> {{ i18n.ts._mfm.play }}
@@ -177,7 +177,7 @@
 
 <script lang="ts" setup>
 import { ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import * as mfm from "mfm-js";
 import * as os from "@/os";
 import XNoteSimple from "@/components/MkNoteSimple.vue";
@@ -222,7 +222,7 @@ const urls = props.note.text
 	? extractUrlFromMfm(mfm.parse(props.note.text)).slice(0, 5)
 	: null;
 
-let showContent = ref(false);
+const showContent = ref(false);
 
 const mfms = props.note.text
 	? extractMfmWithAnimation(mfm.parse(props.note.text))
@@ -230,7 +230,7 @@ const mfms = props.note.text
 
 const hasMfm = ref(mfms && mfms.length > 0);
 
-let disableMfm = ref(defaultStore.state.animatedMfm);
+const disableMfm = ref(defaultStore.state.animatedMfm);
 
 async function toggleMfm() {
 	if (disableMfm.value) {
diff --git a/packages/client/src/components/MkTagCloud.vue b/packages/client/src/components/MkTagCloud.vue
index 41db861616..3a40fbde6b 100644
--- a/packages/client/src/components/MkTagCloud.vue
+++ b/packages/client/src/components/MkTagCloud.vue
@@ -17,7 +17,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, watch, onBeforeUnmount, ref } from "vue";
+import { onBeforeUnmount, onMounted, ref, watch } from "vue";
 import tinycolor from "tinycolor2";
 
 const loaded = !!window.TagCanvas;
@@ -39,11 +39,11 @@ const idForTags = Array.from(Array(16))
 			],
 	)
 	.join("");
-let available = ref(false);
-let rootEl = ref<HTMLElement | null>(null);
-let canvasEl = ref<HTMLCanvasElement | null>(null);
-let tagsEl = ref<HTMLElement | null>(null);
-let width = ref(300);
+const available = ref(false);
+const rootEl = ref<HTMLElement | null>(null);
+const canvasEl = ref<HTMLCanvasElement | null>(null);
+const tagsEl = ref<HTMLElement | null>(null);
+const width = ref(300);
 
 watch(available, () => {
 	try {
@@ -56,7 +56,7 @@ watch(available, () => {
 			initial: [-0.03, -0.01],
 			frontSelect: true,
 			imageRadius: 8,
-			//dragControl: true,
+			// dragControl: true,
 			dragThreshold: 3,
 			wheelZoom: false,
 			reverse: true,
diff --git a/packages/client/src/components/MkTimeline.vue b/packages/client/src/components/MkTimeline.vue
index 8f7808694f..812c330710 100644
--- a/packages/client/src/components/MkTimeline.vue
+++ b/packages/client/src/components/MkTimeline.vue
@@ -12,8 +12,8 @@
 	<div v-if="queue > 0" class="new">
 		<button
 			class="_buttonPrimary _shadow"
-			@click="tlComponent.scrollTop()"
 			:class="{ instant: !$store.state.animation }"
+			@click="tlComponent.scrollTop()"
 		>
 			{{ i18n.ts.newNoteRecived }}
 			<i class="ph-arrow-up ph-bold"></i>
@@ -28,7 +28,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, provide, onUnmounted, ref } from "vue";
+import { computed, onUnmounted, provide, ref } from "vue";
 import XNotes from "@/components/MkNotes.vue";
 import MkInfo from "@/components/MkInfo.vue";
 import { stream } from "@/stream";
@@ -45,7 +45,7 @@ const props = defineProps<{
 	sound?: boolean;
 }>();
 
-let queue = ref(0);
+const queue = ref(0);
 
 const emit = defineEmits<{
 	(ev: "note"): void;
@@ -83,13 +83,7 @@ const onChangeFollowing = () => {
 	}
 };
 
-let endpoint;
-let query;
-let connection;
-let connection2;
-
-let tlHint;
-let tlHintClosed;
+let endpoint, query, connection, connection2, tlHint, tlHintClosed;
 
 if (props.src === "antenna") {
 	endpoint = "antennas/notes";
@@ -223,7 +217,7 @@ function closeHint() {
 }
 
 const pagination = {
-	endpoint: endpoint,
+	endpoint,
 	limit: 10,
 	params: query,
 };
diff --git a/packages/client/src/components/MkToast.vue b/packages/client/src/components/MkToast.vue
index a068202532..8ef5abbb91 100644
--- a/packages/client/src/components/MkToast.vue
+++ b/packages/client/src/components/MkToast.vue
@@ -30,7 +30,7 @@ const emit = defineEmits<{
 }>();
 
 const zIndex = os.claimZIndex("high");
-let showing = ref(true);
+const showing = ref(true);
 
 onMounted(() => {
 	window.setTimeout(() => {
diff --git a/packages/client/src/components/MkTokenGenerateWindow.vue b/packages/client/src/components/MkTokenGenerateWindow.vue
index 6386f6c6d0..7e440c959b 100644
--- a/packages/client/src/components/MkTokenGenerateWindow.vue
+++ b/packages/client/src/components/MkTokenGenerateWindow.vue
@@ -6,10 +6,10 @@
 		:with-ok-button="true"
 		:ok-button-disabled="false"
 		:can-close="false"
+		style="padding: 12px"
 		@close="dialog.close()"
 		@closed="$emit('closed')"
 		@ok="ok()"
-		style="padding: 12px"
 	>
 		<template #header>{{ title || i18n.ts.generateAccessToken }}</template>
 		<div v-if="information" class="_section">
@@ -19,7 +19,7 @@
 			<div style="margin-bottom: 16px">
 				<b>{{ i18n.ts.name }}</b>
 			</div>
-			<MkInput style="margin-bottom: 16px" v-model="name" />
+			<MkInput v-model="name" style="margin-bottom: 16px" />
 		</div>
 		<div class="_section">
 			<div style="margin-bottom: 16px">
@@ -32,10 +32,10 @@
 				i18n.ts.enableAll
 			}}</MkButton>
 			<MkSwitch
-				style="margin-bottom: 6px"
 				v-for="kind in initialPermissions || kinds"
 				:key="kind"
 				v-model="permissions[kind]"
+				style="margin-bottom: 6px"
 				>{{ i18n.t(`_permissions.${kind}`) }}</MkSwitch
 			>
 		</div>
@@ -45,7 +45,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import { permissions as kinds } from "firefish-js";
 import MkInput from "./form/input.vue";
 import MkSwitch from "./form/switch.vue";
@@ -75,8 +74,8 @@ const emit = defineEmits<{
 }>();
 
 const dialog = ref<InstanceType<typeof XModalWindow>>();
-let name = ref(props.initialName);
-let permissions = ref({});
+const name = ref(props.initialName);
+const permissions = ref({});
 
 if (props.initialPermissions) {
 	for (const kind of props.initialPermissions) {
diff --git a/packages/client/src/components/MkTutorialDialog.vue b/packages/client/src/components/MkTutorialDialog.vue
index 1c5ec315dc..5f9a108e9a 100644
--- a/packages/client/src/components/MkTutorialDialog.vue
+++ b/packages/client/src/components/MkTutorialDialog.vue
@@ -230,7 +230,7 @@ const isGlobalTimelineAvailable =
 	!instance.disableGlobalTimeline ||
 	($i != null && ($i.isModerator || $i.isAdmin));
 
-let timelines = ["home"];
+const timelines = ["home"];
 
 if (isLocalTimelineAvailable) {
 	timelines.push("local");
diff --git a/packages/client/src/components/MkUpdated.vue b/packages/client/src/components/MkUpdated.vue
index bd62d8e227..7004be11cf 100644
--- a/packages/client/src/components/MkUpdated.vue
+++ b/packages/client/src/components/MkUpdated.vue
@@ -33,7 +33,7 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, ref } from "vue";
+import { ref, shallowRef } from "vue";
 import MkModal from "@/components/MkModal.vue";
 import MkSparkle from "@/components/MkSparkle.vue";
 import MkButton from "@/components/MkButton.vue";
@@ -43,8 +43,8 @@ import * as os from "@/os";
 
 const modal = shallowRef<InstanceType<typeof MkModal>>();
 
-let newRelease = ref(false);
-let data = ref(Object);
+const newRelease = ref(false);
+const data = ref(Object);
 
 os.api("release").then((res) => {
 	data.value = res;
diff --git a/packages/client/src/components/MkUrlPreview.vue b/packages/client/src/components/MkUrlPreview.vue
index 4e37805986..6814c9b83b 100644
--- a/packages/client/src/components/MkUrlPreview.vue
+++ b/packages/client/src/components/MkUrlPreview.vue
@@ -20,10 +20,10 @@
 					<img :src="thumbnail" loading="lazy" />
 					<button
 						v-if="tweetId"
-						class="_button"
 						v-tooltip="
 							tweetExpanded ? i18n.ts.close : i18n.ts.expandTweet
 						"
+						class="_button"
 						@click.stop.prevent="tweetExpanded = !tweetExpanded"
 					>
 						<i
@@ -34,10 +34,10 @@
 					</button>
 					<button
 						v-else-if="player.url"
-						class="_button"
 						v-tooltip="
 							playerEnabled ? i18n.ts.close : i18n.ts.enablePlayer
 						"
+						class="_button"
 						@click.stop.prevent="playerEnabled = !playerEnabled"
 					>
 						<i
@@ -100,7 +100,7 @@
 
 <script lang="ts" setup>
 import { onUnmounted, ref } from "vue";
-import { url as local, lang } from "@/config";
+import { lang, url as local } from "@/config";
 import { i18n } from "@/i18n";
 import { defaultStore } from "@/store";
 
@@ -117,22 +117,22 @@ const props = withDefaults(
 const self = props.url.startsWith(local);
 const attr = self ? "to" : "href";
 const target = self ? null : "_blank";
-let fetching = ref(true);
-let title = ref<string | null>(null);
-let description = ref<string | null>(null);
-let thumbnail = ref<string | null>(null);
-let icon = ref<string | null>(null);
-let sitename = ref<string | null>(null);
-let player = ref({
+const fetching = ref(true);
+const title = ref<string | null>(null);
+const description = ref<string | null>(null);
+const thumbnail = ref<string | null>(null);
+const icon = ref<string | null>(null);
+const sitename = ref<string | null>(null);
+const player = ref({
 	url: null,
 	width: null,
 	height: null,
 });
-let playerEnabled = ref(false);
-let tweetId = ref<string | null>(null);
-let tweetExpanded = ref(props.detail);
+const playerEnabled = ref(false);
+const tweetId = ref<string | null>(null);
+const tweetExpanded = ref(props.detail);
 const embedId = `embed${Math.random().toString().replace(/\D/, "")}`;
-let tweetHeight = ref(150);
+const tweetHeight = ref(150);
 
 const requestUrl = new URL(props.url);
 if (!["http:", "https:"].includes(requestUrl.protocol))
diff --git a/packages/client/src/components/MkUrlPreviewPopup.vue b/packages/client/src/components/MkUrlPreviewPopup.vue
index aaaf9ad7db..c0ee0b284e 100644
--- a/packages/client/src/components/MkUrlPreviewPopup.vue
+++ b/packages/client/src/components/MkUrlPreviewPopup.vue
@@ -28,8 +28,8 @@ const emit = defineEmits<{
 }>();
 
 const zIndex = os.claimZIndex("middle");
-let top = ref(0);
-let left = ref(0);
+const top = ref(0);
+const left = ref(0);
 
 onMounted(() => {
 	const rect = props.source.getBoundingClientRect();
diff --git a/packages/client/src/components/MkUserCardMini.vue b/packages/client/src/components/MkUserCardMini.vue
index 9ab9237b29..2a22858f83 100644
--- a/packages/client/src/components/MkUserCardMini.vue
+++ b/packages/client/src/components/MkUserCardMini.vue
@@ -26,7 +26,7 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkMiniChart from "@/components/MkMiniChart.vue";
 import * as os from "@/os";
 import { acct, userPage } from "@/filters/user";
@@ -43,7 +43,7 @@ const props = withDefaults(
 	},
 );
 
-let chartValues = ref<number[] | null>(null);
+const chartValues = ref<number[] | null>(null);
 
 if (props.withChart) {
 	os.apiGet("charts/user/notes", {
diff --git a/packages/client/src/components/MkUserInfo.vue b/packages/client/src/components/MkUserInfo.vue
index 784211057f..27a75a4bec 100644
--- a/packages/client/src/components/MkUserInfo.vue
+++ b/packages/client/src/components/MkUserInfo.vue
@@ -88,7 +88,7 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkFollowButton from "@/components/MkFollowButton.vue";
 import XShowMoreButton from "@/components/MkShowMoreButton.vue";
 import MkNumber from "@/components/MkNumber.vue";
@@ -100,13 +100,13 @@ const props = defineProps<{
 	detailed?: boolean;
 }>();
 
-let isLong = ref(
+const isLong = ref(
 	props.detailed &&
 		props.user.description &&
 		(props.user.description.split("\n").length > 9 ||
 			props.user.description.length > 400),
 );
-let collapsed = ref(isLong.value);
+const collapsed = ref(isLong.value);
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/MkUserList.vue b/packages/client/src/components/MkUserList.vue
index d9560290f4..ec5bf8a719 100644
--- a/packages/client/src/components/MkUserList.vue
+++ b/packages/client/src/components/MkUserList.vue
@@ -27,7 +27,8 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 import MkUserInfo from "@/components/MkUserInfo.vue";
-import MkPagination, { Paging } from "@/components/MkPagination.vue";
+import type { Paging } from "@/components/MkPagination.vue";
+import MkPagination from "@/components/MkPagination.vue";
 import { i18n } from "@/i18n";
 
 const props = defineProps<{
diff --git a/packages/client/src/components/MkUserOnlineIndicator.vue b/packages/client/src/components/MkUserOnlineIndicator.vue
index f219988d79..b988aa7321 100644
--- a/packages/client/src/components/MkUserOnlineIndicator.vue
+++ b/packages/client/src/components/MkUserOnlineIndicator.vue
@@ -5,7 +5,7 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import { i18n } from "@/i18n";
 
 const props = defineProps<{
diff --git a/packages/client/src/components/MkUserPreview.vue b/packages/client/src/components/MkUserPreview.vue
index dd195947a9..38fc41df46 100644
--- a/packages/client/src/components/MkUserPreview.vue
+++ b/packages/client/src/components/MkUserPreview.vue
@@ -29,9 +29,9 @@
 
 <script lang="ts" setup>
 import { onMounted, ref } from "vue";
-import MkUserInfo from "@/components/MkUserInfo.vue";
 import * as Acct from "firefish-js/built/acct";
 import type * as misskey from "firefish-js";
+import MkUserInfo from "@/components/MkUserInfo.vue";
 import * as os from "@/os";
 
 const props = defineProps<{
@@ -47,9 +47,9 @@ const emit = defineEmits<{
 }>();
 
 const zIndex = os.claimZIndex("middle");
-let user = ref<misskey.entities.UserDetailed | null>(null);
-let top = ref(0);
-let left = ref(0);
+const user = ref<misskey.entities.UserDetailed | null>(null);
+const top = ref(0);
+const left = ref(0);
 
 onMounted(() => {
 	if (typeof props.q === "object") {
diff --git a/packages/client/src/components/MkUserSelectDialog.vue b/packages/client/src/components/MkUserSelectDialog.vue
index 458e9a4bd6..3a4310c0b5 100644
--- a/packages/client/src/components/MkUserSelectDialog.vue
+++ b/packages/client/src/components/MkUserSelectDialog.vue
@@ -46,7 +46,7 @@
 							:user="user"
 							class="avatar"
 							:show-indicator="true"
-							disableLink
+							disable-link
 						/>
 						<div class="body">
 							<MkUserName :user="user" class="name" />
@@ -74,7 +74,7 @@
 							:user="user"
 							class="avatar"
 							:show-indicator="true"
-							disableLink
+							disable-link
 						/>
 						<div class="body">
 							<MkUserName :user="user" class="name" />
@@ -89,7 +89,7 @@
 
 <script lang="ts" setup>
 import { onMounted, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkInput from "@/components/form/input.vue";
 import FormSplit from "@/components/form/split.vue";
 import XModalWindow from "@/components/MkModalWindow.vue";
@@ -103,12 +103,12 @@ const emit = defineEmits<{
 	(ev: "closed"): void;
 }>();
 
-let username = ref("");
-let host = ref("");
-let users: misskey.entities.UserDetailed[] = ref([]);
-let recentUsers: misskey.entities.UserDetailed[] = ref([]);
-let selected: misskey.entities.UserDetailed | null = ref(null);
-let dialogEl = ref();
+const username = ref("");
+const host = ref("");
+const users: misskey.entities.UserDetailed[] = ref([]);
+const recentUsers: misskey.entities.UserDetailed[] = ref([]);
+const selected: misskey.entities.UserDetailed | null = ref(null);
+const dialogEl = ref();
 
 const search = () => {
 	if (username.value === "" && host.value === "") {
diff --git a/packages/client/src/components/MkUserSelectLocalDialog.vue b/packages/client/src/components/MkUserSelectLocalDialog.vue
index 595e61c3b6..d72892edc4 100644
--- a/packages/client/src/components/MkUserSelectLocalDialog.vue
+++ b/packages/client/src/components/MkUserSelectLocalDialog.vue
@@ -42,7 +42,7 @@
 							:user="user"
 							class="avatar"
 							:show-indicator="true"
-							disableLink
+							disable-link
 						/>
 						<div class="body">
 							<MkUserName :user="user" class="name" />
@@ -70,7 +70,7 @@
 							:user="user"
 							class="avatar"
 							:show-indicator="true"
-							disableLink
+							disable-link
 						/>
 						<div class="body">
 							<MkUserName :user="user" class="name" />
@@ -85,7 +85,7 @@
 
 <script lang="ts" setup>
 import { onMounted, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkInput from "@/components/form/input.vue";
 import FormSplit from "@/components/form/split.vue";
 import XModalWindow from "@/components/MkModalWindow.vue";
@@ -99,11 +99,11 @@ const emit = defineEmits<{
 	(ev: "closed"): void;
 }>();
 
-let username = ref("");
-let users: misskey.entities.UserDetailed[] = ref([]);
-let recentUsers: misskey.entities.UserDetailed[] = ref([]);
-let selected: misskey.entities.UserDetailed | null = ref(null);
-let dialogEl = ref();
+const username = ref("");
+const users: misskey.entities.UserDetailed[] = ref([]);
+const recentUsers: misskey.entities.UserDetailed[] = ref([]);
+const selected: misskey.entities.UserDetailed | null = ref(null);
+const dialogEl = ref();
 
 const search = () => {
 	if (username.value === "") {
diff --git a/packages/client/src/components/MkUsersTooltip.vue b/packages/client/src/components/MkUsersTooltip.vue
index 78a4f90f25..dd6018cb61 100644
--- a/packages/client/src/components/MkUsersTooltip.vue
+++ b/packages/client/src/components/MkUsersTooltip.vue
@@ -7,7 +7,7 @@
 	>
 		<div class="beaffaef">
 			<div v-for="u in users" :key="u.id" class="user">
-				<MkAvatar class="avatar" :user="u" disableLink />
+				<MkAvatar class="avatar" :user="u" disable-link />
 				<MkUserName class="name" :user="u" :nowrap="true" />
 			</div>
 			<div v-if="users.length < count" class="omitted">
diff --git a/packages/client/src/components/MkVisibility.vue b/packages/client/src/components/MkVisibility.vue
index fb7c472f94..72e2dd7ce7 100644
--- a/packages/client/src/components/MkVisibility.vue
+++ b/packages/client/src/components/MkVisibility.vue
@@ -2,13 +2,13 @@
 	<span v-if="note.visibility !== 'public'" :class="$style.visibility">
 		<i
 			v-if="note.visibility === 'home'"
-			class="ph-house ph-bold ph-lg"
 			v-tooltip="i18n.ts._visibility.home"
+			class="ph-house ph-bold ph-lg"
 		></i>
 		<i
 			v-else-if="note.visibility === 'followers'"
-			class="ph-lock ph-bold ph-lg"
 			v-tooltip="i18n.ts._visibility.followers"
+			class="ph-lock ph-bold ph-lg"
 		></i>
 		<i
 			v-else-if="note.visibility === 'specified'"
@@ -18,8 +18,8 @@
 	</span>
 	<span v-if="note.localOnly" :class="$style.localOnly"
 		><i
-			class="ph-hand-fist ph-bold ph-lg"
 			v-tooltip="i18n.ts._visibility.localOnly"
+			class="ph-hand-fist ph-bold ph-lg"
 		></i
 	></span>
 </template>
diff --git a/packages/client/src/components/MkVisibilityPicker.vue b/packages/client/src/components/MkVisibilityPicker.vue
index e44b5b71e2..9b521711f1 100644
--- a/packages/client/src/components/MkVisibilityPicker.vue
+++ b/packages/client/src/components/MkVisibilityPicker.vue
@@ -122,8 +122,8 @@
 </template>
 
 <script lang="ts" setup>
-import { nextTick, watch, shallowRef, ref } from "vue";
-import * as misskey from "firefish-js";
+import { nextTick, ref, shallowRef, watch } from "vue";
+import type * as misskey from "firefish-js";
 import MkModal from "@/components/MkModal.vue";
 import { i18n } from "@/i18n";
 
@@ -147,8 +147,8 @@ const emit = defineEmits<{
 	(ev: "closed"): void;
 }>();
 
-let v = ref(props.currentVisibility);
-let localOnly = ref(props.currentLocalOnly);
+const v = ref(props.currentVisibility);
+const localOnly = ref(props.currentLocalOnly);
 
 watch(localOnly, () => {
 	emit("changeLocalOnly", localOnly.value);
diff --git a/packages/client/src/components/MkWaitingDialog.vue b/packages/client/src/components/MkWaitingDialog.vue
index cc9784d8de..d16be15eb6 100644
--- a/packages/client/src/components/MkWaitingDialog.vue
+++ b/packages/client/src/components/MkWaitingDialog.vue
@@ -30,7 +30,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, shallowRef } from "vue";
+import { shallowRef, watch } from "vue";
 import MkModal from "@/components/MkModal.vue";
 
 const modal = shallowRef<InstanceType<typeof MkModal>>();
diff --git a/packages/client/src/components/MkWidgets.vue b/packages/client/src/components/MkWidgets.vue
index 6b9827ddf7..b8411c7328 100644
--- a/packages/client/src/components/MkWidgets.vue
+++ b/packages/client/src/components/MkWidgets.vue
@@ -1,7 +1,7 @@
 <template>
 	<div class="vjoppmmu">
 		<template v-if="edit">
-			<header tabindex="-1" v-focus>
+			<header v-focus tabindex="-1">
 				<MkSelect
 					v-model="widgetAdderSelected"
 					style="margin-bottom: var(--margin)"
@@ -39,8 +39,8 @@
 						</button>
 						<button
 							class="remove _button"
-							@click.prevent.stop="removeWidget(element)"
 							:aria-label="i18n.t('close')"
+							@click.prevent.stop="removeWidget(element)"
 						>
 							<i class="ph-x ph-bold ph-lg"></i>
 						</button>
@@ -72,7 +72,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 import { v4 as uuid } from "uuid";
 import { VueDraggable } from "vue-draggable-plus";
 import MkSelect from "@/components/form/select.vue";
@@ -81,11 +81,11 @@ import { widgets as widgetDefs } from "@/widgets";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 
-type Widget = {
+interface Widget {
 	name: string;
 	id: string;
 	data: Record<string, any>;
-};
+}
 
 const props = defineProps<{
 	widgets: Widget[];
@@ -141,7 +141,7 @@ function onContextmenu(widget: Widget, ev: MouseEvent) {
 		["INPUT", "TEXTAREA", "IMG", "VIDEO", "CANVAS"].includes(
 			ev.target.tagName,
 		) ||
-		ev.target.attributes["contenteditable"]
+		ev.target.attributes.contenteditable
 	)
 		return;
 	if (window.getSelection()?.toString() !== "") return;
diff --git a/packages/client/src/components/MkWindow.vue b/packages/client/src/components/MkWindow.vue
index 7f80b7f888..98482c8e37 100644
--- a/packages/client/src/components/MkWindow.vue
+++ b/packages/client/src/components/MkWindow.vue
@@ -118,7 +118,7 @@
 import { onBeforeUnmount, onMounted, provide, ref } from "vue";
 import contains from "@/scripts/contains";
 import * as os from "@/os";
-import { MenuItem } from "@/types/menu";
+import type { MenuItem } from "@/types/menu";
 
 const minHeight = 50;
 const minWidth = 250;
@@ -170,14 +170,14 @@ const emit = defineEmits<{
 
 provide("inWindow", true);
 
-let rootEl = ref<HTMLElement | null>();
-let showing = ref(true);
-let beforeClickedAt = 0;
-let maximized = ref(false);
-let unMaximizedTop = "";
-let unMaximizedLeft = "";
-let unMaximizedWidth = "";
-let unMaximizedHeight = "";
+const rootEl = ref<HTMLElement | null>();
+const showing = ref(true);
+let beforeClickedAt = 0,
+	maximized = ref(false),
+	unMaximizedTop = "",
+	unMaximizedLeft = "",
+	unMaximizedWidth = "",
+	unMaximizedHeight = "";
 
 function close() {
 	showing.value = false;
@@ -280,8 +280,8 @@ function onHeaderMousedown(evt: MouseEvent) {
 	const windowHeight = main.offsetHeight;
 
 	function move(x: number, y: number) {
-		let moveLeft = x - moveBaseX;
-		let moveTop = y - moveBaseY;
+		let moveLeft = x - moveBaseX,
+			moveTop = y - moveBaseY;
 
 		// 下はみ出し
 		if (moveTop + windowHeight > browserHeight)
diff --git a/packages/client/src/components/form/checkbox.vue b/packages/client/src/components/form/checkbox.vue
index 0f45288087..352fbac9e1 100644
--- a/packages/client/src/components/form/checkbox.vue
+++ b/packages/client/src/components/form/checkbox.vue
@@ -24,7 +24,8 @@
 </template>
 
 <script lang="ts" setup>
-import { toRefs, Ref, ref } from "vue";
+import type { Ref } from "vue";
+import { ref, toRefs } from "vue";
 import * as os from "@/os";
 import Ripple from "@/components/MkRipple.vue";
 import { i18n } from "@/i18n";
@@ -38,7 +39,7 @@ const emit = defineEmits<{
 	(ev: "update:modelValue", v: boolean): void;
 }>();
 
-let button = ref<HTMLElement>();
+const button = ref<HTMLElement>();
 const checked = toRefs(props).modelValue;
 const toggle = () => {
 	if (props.disabled) return;
diff --git a/packages/client/src/components/global/MkAvatar.vue b/packages/client/src/components/global/MkAvatar.vue
index 3c363c249c..cf780009ad 100644
--- a/packages/client/src/components/global/MkAvatar.vue
+++ b/packages/client/src/components/global/MkAvatar.vue
@@ -36,7 +36,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, computed, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import type * as misskey from "firefish-js";
 import { getStaticImageUrl } from "@/scripts/get-static-image-url";
 import { extractAvgColorFromBlurhash } from "@/scripts/extract-avg-color-from-blurhash";
@@ -74,7 +74,7 @@ function onClick(ev: MouseEvent) {
 	emit("click", ev);
 }
 
-let color = ref();
+const color = ref();
 
 watch(
 	() => props.user.avatarBlurhash,
diff --git a/packages/client/src/components/global/MkPageHeader.vue b/packages/client/src/components/global/MkPageHeader.vue
index cad993bf8a..639d472d0b 100644
--- a/packages/client/src/components/global/MkPageHeader.vue
+++ b/packages/client/src/components/global/MkPageHeader.vue
@@ -122,13 +122,13 @@
 
 <script lang="ts" setup>
 import {
+	computed,
 	inject,
 	nextTick,
 	onMounted,
 	onUnmounted,
 	ref,
 	watch,
-	computed,
 } from "vue";
 import MkFollowButton from "@/components/MkFollowButton.vue";
 import { popupMenu } from "@/os";
@@ -178,7 +178,7 @@ const tabRefs = {};
 const tabHighlightEl = ref<HTMLElement | null>(null);
 const tabsEl = ref<HTMLElement | null>(null);
 const bg = ref(null);
-let narrow = ref(false);
+const narrow = ref(false);
 const hasTabs = computed(() => props.tabs && props.tabs.length > 0);
 const hasActions = computed(() => props.actions && props.actions.length > 0);
 const show = computed(() => {
diff --git a/packages/client/src/components/global/MkStickyContainer.vue b/packages/client/src/components/global/MkStickyContainer.vue
index 0bb8ebee9d..8d426ce779 100644
--- a/packages/client/src/components/global/MkStickyContainer.vue
+++ b/packages/client/src/components/global/MkStickyContainer.vue
@@ -22,8 +22,8 @@ import { inject, onMounted, onUnmounted, provide, ref, watch } from "vue";
 const headerEl = ref<HTMLElement>();
 const bodyEl = ref<HTMLElement>();
 
-let headerHeight = ref<string | undefined>(),
-	childStickyTop = ref(0);
+const headerHeight = ref<string | undefined>();
+const childStickyTop = ref(0);
 const parentStickyTop = inject<Ref<number>>(CURRENT_STICKY_TOP, ref(0));
 provide(CURRENT_STICKY_TOP, childStickyTop);
 
diff --git a/packages/client/src/components/global/MkTime.vue b/packages/client/src/components/global/MkTime.vue
index 39d0217124..a8819c610f 100644
--- a/packages/client/src/components/global/MkTime.vue
+++ b/packages/client/src/components/global/MkTime.vue
@@ -10,7 +10,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, computed } from "vue";
+import { computed, onMounted, onUnmounted, ref } from "vue";
 import { i18n } from "@/i18n";
 import { dateTimeFormat } from "@/scripts/intl-const";
 
@@ -37,7 +37,7 @@ const _time =
 const invalid = Number.isNaN(_time);
 const absolute = !invalid ? dateTimeFormat.format(_time) : i18n.ts._ago.invalid;
 
-let now = ref((props.origin ?? new Date()).getTime());
+const now = ref((props.origin ?? new Date()).getTime());
 const relative = computed<string>(() => {
 	if (props.mode === "absolute") return ""; // absoluteではrelativeを使わないので計算しない
 	if (invalid) return i18n.ts._ago.invalid;
diff --git a/packages/client/src/components/global/RouterView.vue b/packages/client/src/components/global/RouterView.vue
index 9f6f2dafc8..7b93cf8270 100644
--- a/packages/client/src/components/global/RouterView.vue
+++ b/packages/client/src/components/global/RouterView.vue
@@ -18,7 +18,7 @@
 </template>
 
 <script lang="ts" setup>
-import { inject, onBeforeUnmount, provide, shallowRef, ref } from "vue";
+import { inject, onBeforeUnmount, provide, ref, shallowRef } from "vue";
 import type { Resolved, Router } from "@/nirax";
 import { defaultStore } from "@/store";
 
@@ -48,11 +48,11 @@ function resolveNested(current: Resolved, d = 0): Resolved | null {
 }
 
 const current = resolveNested(router.current)!;
-let currentPageComponent = shallowRef(current.route.component),
-	currentPageProps = ref(current.props),
-	key = ref(
-		current.route.path + JSON.stringify(Object.fromEntries(current.props)),
-	);
+const currentPageComponent = shallowRef(current.route.component);
+const currentPageProps = ref(current.props);
+const key = ref(
+	current.route.path + JSON.stringify(Object.fromEntries(current.props)),
+);
 
 function onChange({ resolved, key: newKey }) {
 	const current = resolveNested(resolved);
diff --git a/packages/client/src/components/global/i18n.ts b/packages/client/src/components/global/i18n.ts
index 4475b62a4b..a0113a6549 100644
--- a/packages/client/src/components/global/i18n.ts
+++ b/packages/client/src/components/global/i18n.ts
@@ -1,4 +1,4 @@
-import { h, defineComponent } from "vue";
+import { defineComponent, h } from "vue";
 
 export default defineComponent({
 	props: {
diff --git a/packages/client/src/components/index.ts b/packages/client/src/components/index.ts
index 7da095e7dc..6cf61617d1 100644
--- a/packages/client/src/components/index.ts
+++ b/packages/client/src/components/index.ts
@@ -1,4 +1,4 @@
-import { App } from "vue";
+import type { App } from "vue";
 
 import Mfm from "./global/MkMisskeyFlavoredMarkdown.vue";
 import MkA from "./global/MkA.vue";
diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts
index cb0942a338..6b467fa2aa 100644
--- a/packages/client/src/components/mfm.ts
+++ b/packages/client/src/components/mfm.ts
@@ -13,7 +13,6 @@ import MkSparkle from "@/components/MkSparkle.vue";
 import MkA from "@/components/global/MkA.vue";
 import { host } from "@/config";
 import { reducedMotion } from "@/scripts/reduced-motion";
-import { defaultStore } from "@/store";
 
 export default defineComponent({
 	props: {
@@ -498,7 +497,7 @@ export default defineComponent({
 							// (see the issue #9816 on Codeberg)
 							if (token.props.content.slice(-6).toLowerCase() === "search") {
 								const sentinel = "#";
-								let ast2 = (isPlain ? mfm.parseSimple : mfm.parse)(
+								const ast2 = (isPlain ? mfm.parseSimple : mfm.parse)(
 									token.props.content.slice(0, -6) + sentinel,
 								);
 								if (
diff --git a/packages/client/src/components/page/page.block.vue b/packages/client/src/components/page/page.block.vue
index edeb33a143..b75c2caa12 100644
--- a/packages/client/src/components/page/page.block.vue
+++ b/packages/client/src/components/page/page.block.vue
@@ -9,7 +9,8 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { defineComponent } from "vue";
 import XText from "./page.text.vue";
 import XSection from "./page.section.vue";
 import XImage from "./page.image.vue";
@@ -25,8 +26,8 @@ import XCounter from "./page.counter.vue";
 import XRadioButton from "./page.radio-button.vue";
 import XCanvas from "./page.canvas.vue";
 import XNote from "./page.note.vue";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { Block } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
+import type { Block } from "@/scripts/hpml/block";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.button.vue b/packages/client/src/components/page/page.button.vue
index b3c42eb603..c4efa59f23 100644
--- a/packages/client/src/components/page/page.button.vue
+++ b/packages/client/src/components/page/page.button.vue
@@ -7,11 +7,12 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, PropType, unref } from "vue";
+import type { PropType } from "vue";
+import { defineComponent, unref } from "vue";
 import MkButton from "../MkButton.vue";
 import * as os from "@/os";
-import { ButtonBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
+import type { ButtonBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.canvas.vue b/packages/client/src/components/page/page.canvas.vue
index 2e5a0baea2..0568d6ef90 100644
--- a/packages/client/src/components/page/page.canvas.vue
+++ b/packages/client/src/components/page/page.canvas.vue
@@ -5,9 +5,10 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, onMounted, PropType, Ref, ref } from "vue";
-import { CanvasBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
+import type { PropType, Ref } from "vue";
+import { defineComponent, onMounted, ref } from "vue";
+import type { CanvasBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 export default defineComponent({
 	props: {
diff --git a/packages/client/src/components/page/page.counter.vue b/packages/client/src/components/page/page.counter.vue
index a17217f54b..bd3338c2fa 100644
--- a/packages/client/src/components/page/page.counter.vue
+++ b/packages/client/src/components/page/page.counter.vue
@@ -7,10 +7,11 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { computed, defineComponent } from "vue";
 import MkButton from "../MkButton.vue";
-import { CounterVarBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
+import type { CounterVarBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.if.vue b/packages/client/src/components/page/page.if.vue
index 7cc25f2125..87d2612dd2 100644
--- a/packages/client/src/components/page/page.if.vue
+++ b/packages/client/src/components/page/page.if.vue
@@ -11,9 +11,10 @@
 </template>
 
 <script lang="ts">
-import { IfBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { defineComponent, defineAsyncComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { defineAsyncComponent, defineComponent } from "vue";
+import type { IfBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.image.vue b/packages/client/src/components/page/page.image.vue
index 0e900dc57a..de0a190c44 100644
--- a/packages/client/src/components/page/page.image.vue
+++ b/packages/client/src/components/page/page.image.vue
@@ -12,10 +12,10 @@
 </template>
 
 <script lang="ts" setup>
-import { PropType } from "vue";
+import type { PropType } from "vue";
 import ImgWithBlurhash from "@/components/MkImgWithBlurhash.vue";
-import { ImageBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
+import type { ImageBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 const props = defineProps<{
 	block: PropType<ImageBlock>;
diff --git a/packages/client/src/components/page/page.note.vue b/packages/client/src/components/page/page.note.vue
index 868418cd42..f28e0b465f 100644
--- a/packages/client/src/components/page/page.note.vue
+++ b/packages/client/src/components/page/page.note.vue
@@ -14,11 +14,12 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, onMounted, PropType, Ref, ref } from "vue";
+import type { PropType, Ref } from "vue";
+import { defineComponent, onMounted, ref } from "vue";
 import XNote from "@/components/MkNote.vue";
 import XNoteDetailed from "@/components/MkNoteDetailed.vue";
 import * as os from "@/os";
-import { NoteBlock } from "@/scripts/hpml/block";
+import type { NoteBlock } from "@/scripts/hpml/block";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.number-input.vue b/packages/client/src/components/page/page.number-input.vue
index 6a0c86cc71..bf2f891000 100644
--- a/packages/client/src/components/page/page.number-input.vue
+++ b/packages/client/src/components/page/page.number-input.vue
@@ -12,10 +12,11 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { computed, defineComponent } from "vue";
 import MkInput from "../form/input.vue";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { NumberInputVarBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
+import type { NumberInputVarBlock } from "@/scripts/hpml/block";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.post.vue b/packages/client/src/components/page/page.post.vue
index 2213d3021c..2b9b57917d 100644
--- a/packages/client/src/components/page/page.post.vue
+++ b/packages/client/src/components/page/page.post.vue
@@ -14,13 +14,14 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { defineComponent } from "vue";
 import MkTextarea from "../form/textarea.vue";
 import MkButton from "../MkButton.vue";
 import { apiUrl } from "@/config";
 import * as os from "@/os";
-import { PostBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
+import type { PostBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.radio-button.vue b/packages/client/src/components/page/page.radio-button.vue
index 279974222f..c222acfc2d 100644
--- a/packages/client/src/components/page/page.radio-button.vue
+++ b/packages/client/src/components/page/page.radio-button.vue
@@ -4,7 +4,7 @@
 		<MkRadio
 			v-for="item in block.values"
 			:key="item"
-			:modelValue="value"
+			:model-value="value"
 			:value="item"
 			@update:modelValue="updateValue($event)"
 			>{{ item }}</MkRadio
@@ -13,10 +13,11 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { computed, defineComponent } from "vue";
 import MkRadio from "../form/radio.vue";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { RadioButtonVarBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
+import type { RadioButtonVarBlock } from "@/scripts/hpml/block";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.section.vue b/packages/client/src/components/page/page.section.vue
index 72b112f695..8f2ae61114 100644
--- a/packages/client/src/components/page/page.section.vue
+++ b/packages/client/src/components/page/page.section.vue
@@ -15,9 +15,10 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, defineAsyncComponent, PropType } from "vue";
-import { SectionBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
+import type { PropType } from "vue";
+import { defineAsyncComponent, defineComponent } from "vue";
+import type { SectionBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.switch.vue b/packages/client/src/components/page/page.switch.vue
index dd33fc07c9..f9314cc8c5 100644
--- a/packages/client/src/components/page/page.switch.vue
+++ b/packages/client/src/components/page/page.switch.vue
@@ -9,10 +9,11 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { computed, defineComponent } from "vue";
 import MkSwitch from "../form/switch.vue";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { SwitchVarBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
+import type { SwitchVarBlock } from "@/scripts/hpml/block";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.text-input.vue b/packages/client/src/components/page/page.text-input.vue
index f2286f0820..5b868f09f7 100644
--- a/packages/client/src/components/page/page.text-input.vue
+++ b/packages/client/src/components/page/page.text-input.vue
@@ -12,10 +12,11 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { computed, defineComponent } from "vue";
 import MkInput from "../form/input.vue";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { TextInputVarBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
+import type { TextInputVarBlock } from "@/scripts/hpml/block";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.text.vue b/packages/client/src/components/page/page.text.vue
index 72854bf39a..ba7f69a7aa 100644
--- a/packages/client/src/components/page/page.text.vue
+++ b/packages/client/src/components/page/page.text.vue
@@ -6,10 +6,11 @@
 </template>
 
 <script lang="ts">
-import { TextBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { defineAsyncComponent, defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { defineAsyncComponent, defineComponent } from "vue";
 import * as mfm from "mfm-js";
+import type { TextBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.textarea-input.vue b/packages/client/src/components/page/page.textarea-input.vue
index c074479cf6..bb0541946b 100644
--- a/packages/client/src/components/page/page.textarea-input.vue
+++ b/packages/client/src/components/page/page.textarea-input.vue
@@ -10,10 +10,11 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, PropType } from "vue";
+import type { PropType } from "vue";
+import { computed, defineComponent } from "vue";
 import MkTextarea from "../form/textarea.vue";
-import { Hpml } from "@/scripts/hpml/evaluator";
-import { TextInputVarBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
+import type { TextInputVarBlock } from "@/scripts/hpml/block";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/components/page/page.textarea.vue b/packages/client/src/components/page/page.textarea.vue
index 4bcd72eceb..a37a742e50 100644
--- a/packages/client/src/components/page/page.textarea.vue
+++ b/packages/client/src/components/page/page.textarea.vue
@@ -3,17 +3,17 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref } from "vue";
+import { ref, watch } from "vue";
 import MkTextarea from "../form/textarea.vue";
-import { TextBlock } from "@/scripts/hpml/block";
-import { Hpml } from "@/scripts/hpml/evaluator";
+import type { TextBlock } from "@/scripts/hpml/block";
+import type { Hpml } from "@/scripts/hpml/evaluator";
 
 const props = defineProps<{
 	block: TextBlock;
 	hpml: Hpml;
 }>();
 
-let text = ref("");
+const text = ref("");
 
 watch(
 	props.hpml.vars,
diff --git a/packages/client/src/components/page/page.vue b/packages/client/src/components/page/page.vue
index f2079c9ba8..4041b0e6fd 100644
--- a/packages/client/src/components/page/page.vue
+++ b/packages/client/src/components/page/page.vue
@@ -15,13 +15,8 @@
 </template>
 
 <script lang="ts">
-import {
-	defineComponent,
-	onMounted,
-	nextTick,
-	onUnmounted,
-	PropType,
-} from "vue";
+import type { PropType } from "vue";
+import { defineComponent, nextTick, onMounted, onUnmounted } from "vue";
 import { parse } from "@syuilo/aiscript";
 import XBlock from "./page.block.vue";
 import { Hpml } from "@/scripts/hpml/evaluator";
@@ -43,7 +38,7 @@ export default defineComponent({
 		const hpml = new Hpml(props.page, {
 			randomSeed: Math.random(),
 			visitor: $i,
-			url: url,
+			url,
 			enableAiScript: !defaultStore.state.disablePagesScript,
 		});
 
@@ -55,10 +50,10 @@ export default defineComponent({
 						ast = parse(props.page.script);
 					} catch (err) {
 						console.error(err);
-						/*os.alert({
+						/* os.alert({
 							type: 'error',
 							text: 'Syntax error :('
-						});*/
+						}); */
 						return;
 					}
 					hpml.aiscript
@@ -68,10 +63,10 @@ export default defineComponent({
 						})
 						.catch((err) => {
 							console.error(err);
-							/*os.alert({
+							/* os.alert({
 							type: 'error',
 							text: err
-						});*/
+						}); */
 						});
 				} else {
 					hpml.eval();
diff --git a/packages/client/src/directives/adaptive-border.ts b/packages/client/src/directives/adaptive-border.ts
index c882c49b18..a5a7ddbd68 100644
--- a/packages/client/src/directives/adaptive-border.ts
+++ b/packages/client/src/directives/adaptive-border.ts
@@ -1,4 +1,4 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 
 export default {
 	mounted(src, binding, vn) {
diff --git a/packages/client/src/directives/anim.ts b/packages/client/src/directives/anim.ts
index 9e69e11efe..b738f6c478 100644
--- a/packages/client/src/directives/anim.ts
+++ b/packages/client/src/directives/anim.ts
@@ -1,11 +1,11 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 
 export default {
 	beforeMount(src, binding, vn) {
 		src.style.opacity = "0";
 		src.style.transform = "scale(0.9)";
 		// ページネーションと相性が悪いので
-		//if (typeof binding.value === 'number') src.style.transitionDelay = `${binding.value * 30}ms`;
+		// if (typeof binding.value === 'number') src.style.transitionDelay = `${binding.value * 30}ms`;
 		src.classList.add("_zoom");
 	},
 
diff --git a/packages/client/src/directives/appear.ts b/packages/client/src/directives/appear.ts
index 16f3218019..8e93ebd221 100644
--- a/packages/client/src/directives/appear.ts
+++ b/packages/client/src/directives/appear.ts
@@ -1,4 +1,4 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 
 export default {
 	mounted(src, binding, vn) {
diff --git a/packages/client/src/directives/click-anime.ts b/packages/client/src/directives/click-anime.ts
index 5c2dff1ed1..cca10c8284 100644
--- a/packages/client/src/directives/click-anime.ts
+++ b/packages/client/src/directives/click-anime.ts
@@ -1,4 +1,4 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 // import { defaultStore } from "@/store";
 
 export default {
diff --git a/packages/client/src/directives/follow-append.ts b/packages/client/src/directives/follow-append.ts
index 1c500628d4..8c713f64f6 100644
--- a/packages/client/src/directives/follow-append.ts
+++ b/packages/client/src/directives/follow-append.ts
@@ -1,4 +1,4 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 import { getScrollContainer, getScrollPosition } from "@/scripts/scroll";
 
 export default {
diff --git a/packages/client/src/directives/get-size.ts b/packages/client/src/directives/get-size.ts
index 69278a2618..e30eac758f 100644
--- a/packages/client/src/directives/get-size.ts
+++ b/packages/client/src/directives/get-size.ts
@@ -1,4 +1,4 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 
 const mountings = new Map<
 	Element,
diff --git a/packages/client/src/directives/hotkey.ts b/packages/client/src/directives/hotkey.ts
index 8df74c48d1..9e89c271dc 100644
--- a/packages/client/src/directives/hotkey.ts
+++ b/packages/client/src/directives/hotkey.ts
@@ -1,4 +1,4 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 import { makeHotkey } from "../scripts/hotkey";
 
 export default {
diff --git a/packages/client/src/directives/index.ts b/packages/client/src/directives/index.ts
index 77639e2f37..6c80d4e94f 100644
--- a/packages/client/src/directives/index.ts
+++ b/packages/client/src/directives/index.ts
@@ -1,4 +1,4 @@
-import { App } from "vue";
+import type { App } from "vue";
 
 import userPreview from "./user-preview";
 import size from "./size";
diff --git a/packages/client/src/directives/panel.ts b/packages/client/src/directives/panel.ts
index 229f72698c..f1328fa367 100644
--- a/packages/client/src/directives/panel.ts
+++ b/packages/client/src/directives/panel.ts
@@ -1,4 +1,4 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 
 export default {
 	mounted(src, binding, vn) {
diff --git a/packages/client/src/directives/size.ts b/packages/client/src/directives/size.ts
index 90d868c6c1..700b560a33 100644
--- a/packages/client/src/directives/size.ts
+++ b/packages/client/src/directives/size.ts
@@ -1,8 +1,11 @@
-import { Directive } from "vue";
+import type { Directive } from "vue";
 
-type Value = { max?: number[]; min?: number[] };
+interface Value {
+	max?: number[];
+	min?: number[];
+}
 
-//const observers = new Map<Element, ResizeObserver>();
+// const observers = new Map<Element, ResizeObserver>();
 const mountings = new Map<
 	Element,
 	{
@@ -13,10 +16,10 @@ const mountings = new Map<
 	}
 >();
 
-type ClassOrder = {
+interface ClassOrder {
 	add: string[];
 	remove: string[];
-};
+}
 
 const cache = new Map<string, ClassOrder>();
 
diff --git a/packages/client/src/directives/tooltip.ts b/packages/client/src/directives/tooltip.ts
index e2db3fbf57..0b29b65560 100644
--- a/packages/client/src/directives/tooltip.ts
+++ b/packages/client/src/directives/tooltip.ts
@@ -1,9 +1,10 @@
 // TODO: useTooltip関数使うようにしたい
 // ただディレクティブ内でonUnmountedなどのcomposition api使えるのか不明
 
-import { defineAsyncComponent, Directive, ref } from "vue";
+import type { Directive } from "vue";
+import { defineAsyncComponent, ref } from "vue";
 import { isTouchUsing } from "@/scripts/touch";
-import { popup, alert } from "@/os";
+import { alert, popup } from "@/os";
 import { mainRouter } from "@/router";
 
 const start = isTouchUsing ? "touchstart" : "mouseover";
diff --git a/packages/client/src/directives/user-preview.ts b/packages/client/src/directives/user-preview.ts
index 90c9ba3d0d..dbbdb8b008 100644
--- a/packages/client/src/directives/user-preview.ts
+++ b/packages/client/src/directives/user-preview.ts
@@ -1,4 +1,5 @@
-import { defineAsyncComponent, Directive, ref } from "vue";
+import type { Directive } from "vue";
+import { defineAsyncComponent, ref } from "vue";
 import { popup } from "@/os";
 
 export class UserPreview {
diff --git a/packages/client/src/filters/user.ts b/packages/client/src/filters/user.ts
index c9f932bd2a..66a2de49d5 100644
--- a/packages/client/src/filters/user.ts
+++ b/packages/client/src/filters/user.ts
@@ -1,4 +1,4 @@
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import * as Acct from "firefish-js/built/acct";
 import { url } from "@/config";
 
diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts
index 519368138e..a8b860e51e 100644
--- a/packages/client/src/init.ts
+++ b/packages/client/src/init.ts
@@ -9,7 +9,7 @@ import "@/style.scss";
 import "@phosphor-icons/web/bold";
 import "@phosphor-icons/web/fill";
 
-//#region account indexedDB migration
+// #region account indexedDB migration
 import { set } from "@/scripts/idb-proxy";
 
 const accounts = localStorage.getItem("accounts");
@@ -17,30 +17,30 @@ if (accounts) {
 	set("accounts", JSON.parse(accounts));
 	localStorage.removeItem("accounts");
 }
-//#endregion
+// #endregion
 
 import {
 	computed,
 	createApp,
-	watch,
+	defineAsyncComponent,
 	markRaw,
 	version as vueVersion,
-	defineAsyncComponent,
+	watch,
 } from "vue";
 import { compareVersions } from "compare-versions";
 
 import widgets from "@/widgets";
 import directives from "@/directives";
 import components from "@/components";
-import { version, ui, lang, host } from "@/config";
+import { lang, ui, version } from "@/config";
 import { applyTheme } from "@/scripts/theme";
 import { isDeviceDarkmode } from "@/scripts/is-device-darkmode";
 import { i18n } from "@/i18n";
-import { confirm, alert, post, popup, toast, api } from "@/os";
+import { alert, api, confirm, popup, post, toast } from "@/os";
 import { stream } from "@/stream";
 import * as sound from "@/scripts/sound";
-import { $i, refreshAccount, login, updateAccount, signout } from "@/account";
-import { defaultStore, ColdDeviceStorage } from "@/store";
+import { $i, login, refreshAccount, signout, updateAccount } from "@/account";
+import { ColdDeviceStorage, defaultStore } from "@/store";
 import { fetchInstance, instance } from "@/instance";
 import { makeHotkey } from "@/scripts/hotkey";
 import { search } from "@/scripts/search";
@@ -106,7 +106,7 @@ function checkForSplash() {
 		else location.reload();
 	});
 
-	//#region SEE: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
+	// #region SEE: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
 	// TODO: いつの日にか消したい
 	const vh = window.innerHeight * 0.01;
 	document.documentElement.style.setProperty("--vh", `${vh}px`);
@@ -114,14 +114,14 @@ function checkForSplash() {
 		const vh = window.innerHeight * 0.01;
 		document.documentElement.style.setProperty("--vh", `${vh}px`);
 	});
-	//#endregion
+	// #endregion
 
-	//#region Set lang attr
+	// #region Set lang attr
 	const html = document.documentElement;
 	html.setAttribute("lang", lang || "en-US");
-	//#endregion
+	// #endregion
 
-	//#region loginId
+	// #region loginId
 	const params = new URLSearchParams(location.search);
 	const loginId = params.get("loginId");
 
@@ -138,9 +138,9 @@ function checkForSplash() {
 		history.replaceState({ misskey: "loginId" }, "", target);
 	}
 
-	//#endregion
+	// #endregion
 
-	//#region Fetch user
+	// #region Fetch user
 	if ($i?.token) {
 		if (_DEV_) {
 			console.log("account cache found. refreshing...");
@@ -174,7 +174,7 @@ function checkForSplash() {
 			}
 		}
 	}
-	//#endregion
+	// #endregion
 
 	const fetchInstanceMetaPromise = fetchInstance();
 
@@ -336,7 +336,7 @@ function checkForSplash() {
 		}
 	});
 
-	//#region Sync dark mode
+	// #region Sync dark mode
 	if (ColdDeviceStorage.get("syncDeviceDarkMode")) {
 		defaultStore.set("darkMode", isDeviceDarkmode());
 	}
@@ -345,7 +345,7 @@ function checkForSplash() {
 			defaultStore.set("darkMode", mql.matches);
 		}
 	};
-	//#endregion
+	// #endregion
 
 	fetchInstanceMetaPromise.then(() => {
 		if (defaultStore.state.themeInitial) {
@@ -407,7 +407,7 @@ function checkForSplash() {
 
 	stream.on("emojiAdded", (emojiData) => {
 		// TODO
-		//store.commit('instance/set', );
+		// store.commit('instance/set', );
 	});
 
 	for (const plugin of ColdDeviceStorage.get("plugins").filter(
diff --git a/packages/client/src/instance.ts b/packages/client/src/instance.ts
index 70ba0abfaa..1ed32fbfc1 100644
--- a/packages/client/src/instance.ts
+++ b/packages/client/src/instance.ts
@@ -1,6 +1,6 @@
 import { computed, reactive } from "vue";
-import { api } from "./os";
 import type * as Misskey from "firefish-js";
+import { api } from "./os";
 
 // TODO: 他のタブと永続化されたstateを同期
 
diff --git a/packages/client/src/navbar.ts b/packages/client/src/navbar.ts
index fa4bdaf87b..f8b54b4a8a 100644
--- a/packages/client/src/navbar.ts
+++ b/packages/client/src/navbar.ts
@@ -1,4 +1,4 @@
-import { computed, ref, reactive } from "vue";
+import { computed, reactive } from "vue";
 import { $i } from "./account";
 import { search } from "@/scripts/search";
 import * as os from "@/os";
diff --git a/packages/client/src/nirax.ts b/packages/client/src/nirax.ts
index 7e481f1484..0ce413d393 100644
--- a/packages/client/src/nirax.ts
+++ b/packages/client/src/nirax.ts
@@ -1,11 +1,12 @@
 // NIRAX --- A lightweight router
 
 import { EventEmitter } from "eventemitter3";
-import { Ref, Component, ref, shallowRef, ShallowRef } from "vue";
+import type { Component, ShallowRef } from "vue";
+import { shallowRef } from "vue";
 import { pleaseLogin } from "@/scripts/please-login";
 import { safeURIDecode } from "@/scripts/safe-uri-decode";
 
-type RouteDef = {
+interface RouteDef {
 	path: string;
 	component: Component;
 	query?: Record<string, string>;
@@ -14,7 +15,7 @@ type RouteDef = {
 	hash?: string;
 	globalCacheKey?: string;
 	children?: RouteDef[];
-};
+}
 
 type ParsedPath = (
 	| string
@@ -26,11 +27,11 @@ type ParsedPath = (
 	  }
 )[];
 
-export type Resolved = {
+export interface Resolved {
 	route: RouteDef;
 	props: Map<string, string>;
 	child?: Resolved;
-};
+}
 
 function parsePath(path: string): ParsedPath {
 	const res = [] as ParsedPath;
@@ -64,10 +65,7 @@ export class Router extends EventEmitter<{
 		resolved: Resolved;
 		key: string;
 	}) => void;
-	replace: (ctx: {
-		path: string;
-		key: string;
-	}) => void;
+	replace: (ctx: { path: string; key: string }) => void;
 	push: (ctx: {
 		beforePath: string;
 		path: string;
@@ -95,8 +93,8 @@ export class Router extends EventEmitter<{
 	}
 
 	public resolve(path: string): Resolved | null {
-		let queryString: string | null = null;
-		let hash: string | null = null;
+		let queryString: string | null = null,
+			hash: string | null = null;
 		if (path[0] === "/") path = path.substring(1);
 		if (path.includes("#")) {
 			hash = path.substring(path.indexOf("#") + 1);
diff --git a/packages/client/src/os.ts b/packages/client/src/os.ts
index d95edd7bf5..b309185270 100644
--- a/packages/client/src/os.ts
+++ b/packages/client/src/os.ts
@@ -1,17 +1,18 @@
 // TODO: なんでもかんでもos.tsに突っ込むのやめたいのでよしなに分割する
 
-import { Component, markRaw, Ref, ref, defineAsyncComponent } from "vue";
+import type { Component, Ref } from "vue";
+import { defineAsyncComponent, markRaw, ref } from "vue";
 import { EventEmitter } from "eventemitter3";
 import insertTextAtCursor from "insert-text-at-cursor";
 import * as Misskey from "firefish-js";
+import { i18n } from "./i18n";
 import { apiUrl, url } from "@/config";
 import MkPostFormDialog from "@/components/MkPostFormDialog.vue";
 import MkWaitingDialog from "@/components/MkWaitingDialog.vue";
 import MkToast from "@/components/MkToast.vue";
 import MkDialog from "@/components/MkDialog.vue";
-import { MenuItem } from "@/types/menu";
+import type { MenuItem } from "@/types/menu";
 import { $i } from "@/account";
-import { i18n } from "./i18n";
 
 export const pendingApiRequestsCount = ref(0);
 
@@ -36,7 +37,7 @@ export const api = ((
 		: undefined;
 
 	const promise = new Promise((resolve, reject) => {
-		fetch(endpoint.indexOf("://") > -1 ? endpoint : `${apiUrl}/${endpoint}`, {
+		fetch(endpoint.includes("://") ? endpoint : `${apiUrl}/${endpoint}`, {
 			method: "POST",
 			body: JSON.stringify(data),
 			credentials: "omit",
@@ -160,9 +161,9 @@ export function promiseDialog<T extends Promise<any>>(
 	popup(
 		MkWaitingDialog,
 		{
-			success: success,
-			showing: showing,
-			text: text,
+			success,
+			showing,
+			text,
 		},
 		{},
 		"closed",
@@ -310,7 +311,7 @@ export function confirm(props: {
 			},
 			{
 				done: (result) => {
-					resolve(result ? result : { canceled: true });
+					resolve(result || { canceled: true });
 				},
 			},
 			"closed",
@@ -337,7 +338,7 @@ export function yesno(props: {
 			},
 			{
 				done: (result) => {
-					resolve(result ? result : { canceled: true });
+					resolve(result || { canceled: true });
 				},
 			},
 			"closed",
@@ -378,7 +379,7 @@ export function inputText(props: {
 			},
 			{
 				done: (result) => {
-					resolve(result ? result : { canceled: true });
+					resolve(result || { canceled: true });
 				},
 			},
 			"closed",
@@ -416,7 +417,7 @@ export function inputParagraph(props: {
 			},
 			{
 				done: (result) => {
-					resolve(result ? result : { canceled: true });
+					resolve(result || { canceled: true });
 				},
 			},
 			"closed",
@@ -456,7 +457,7 @@ export function inputNumber(props: {
 			},
 			{
 				done: (result) => {
-					resolve(result ? result : { canceled: true });
+					resolve(result || { canceled: true });
 				},
 			},
 			"closed",
@@ -548,7 +549,7 @@ export function select<C = any>(
 			},
 			{
 				done: (result) => {
-					resolve(result ? result : { canceled: true });
+					resolve(result || { canceled: true });
 				},
 			},
 			"closed",
@@ -566,7 +567,7 @@ export function success(): Promise<void> {
 			MkWaitingDialog,
 			{
 				success: true,
-				showing: showing,
+				showing,
 			},
 			{
 				done: () => resolve(),
@@ -583,7 +584,7 @@ export function waiting(): Promise<void> {
 			MkWaitingDialog,
 			{
 				success: false,
-				showing: showing,
+				showing,
 			},
 			{
 				done: () => resolve(),
@@ -771,8 +772,8 @@ type AwaitType<T> = T extends Promise<infer U>
 	: T extends (...args: any[]) => Promise<infer V>
 	? V
 	: T;
-let openingEmojiPicker: AwaitType<ReturnType<typeof popup>> | null = null;
-let activeTextarea: HTMLTextAreaElement | HTMLInputElement | null = null;
+let openingEmojiPicker: AwaitType<ReturnType<typeof popup>> | null = null,
+	activeTextarea: HTMLTextAreaElement | HTMLInputElement | null = null;
 export async function openEmojiPicker(
 	src?: HTMLElement,
 	opts,
@@ -940,4 +941,4 @@ export function checkExistence(fileData: ArrayBuffer): Promise<any> {
 			resolve(resp.length > 0 ? resp[0] : null);
 		});
 	});
-}*/
+} */
diff --git a/packages/client/src/pages/_error_.vue b/packages/client/src/pages/_error_.vue
index 7bc79fdf3c..94bd1e056a 100644
--- a/packages/client/src/pages/_error_.vue
+++ b/packages/client/src/pages/_error_.vue
@@ -35,10 +35,9 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkButton from "@/components/MkButton.vue";
 import { version } from "@/config";
 import * as os from "@/os";
@@ -53,9 +52,9 @@ const props = withDefaults(
 	{},
 );
 
-let loaded = ref(false);
-let serverIsDead = ref(false);
-let meta = ref<misskey.entities.LiteInstanceMetadata | null>(null);
+const loaded = ref(false);
+const serverIsDead = ref(false);
+const meta = ref<misskey.entities.LiteInstanceMetadata | null>(null);
 
 os.api("meta", {
 	detail: false,
diff --git a/packages/client/src/pages/about-firefish.vue b/packages/client/src/pages/about-firefish.vue
index 453d741876..9e5c2a3406 100644
--- a/packages/client/src/pages/about-firefish.vue
+++ b/packages/client/src/pages/about-firefish.vue
@@ -203,7 +203,7 @@
 </template>
 
 <script lang="ts" setup>
-import { nextTick, onBeforeUnmount, ref, computed } from "vue";
+import { computed, nextTick, onBeforeUnmount, ref } from "vue";
 import { version } from "@/config";
 import FormLink from "@/components/form/link.vue";
 import FormSection from "@/components/form/section.vue";
@@ -216,17 +216,17 @@ import { defaultStore } from "@/store";
 import * as os from "@/os";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let patrons = [];
-let sponsors = [];
+let patrons = [],
+	sponsors = [];
 const patronsResp = await os.api("patrons", { forceUpdate: true });
 patrons = patronsResp.patrons;
 sponsors = patronsResp.sponsors;
 
 patrons = patrons.filter((patron) => !sponsors.includes(patron));
 
-let easterEggReady = false;
-let easterEggEmojis = ref([]);
-let easterEggEngine = ref(null);
+let easterEggReady = false,
+	easterEggEmojis = ref([]),
+	easterEggEngine = ref(null);
 const containerEl = ref<HTMLElement>();
 
 function iconLoaded() {
diff --git a/packages/client/src/pages/about.emojis.vue b/packages/client/src/pages/about.emojis.vue
index 853a2bef2f..1b9b030769 100644
--- a/packages/client/src/pages/about.emojis.vue
+++ b/packages/client/src/pages/about.emojis.vue
@@ -47,14 +47,13 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, computed } from "vue";
+import { defineComponent } from "vue";
 import XEmoji from "./emojis.emoji.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
 import MkSelect from "@/components/form/select.vue";
 import MkFolder from "@/components/MkFolder.vue";
 import MkTab from "@/components/MkTab.vue";
-import * as os from "@/os";
 import { emojiCategories, emojiTags } from "@/instance";
 import { i18n } from "@/i18n";
 
diff --git a/packages/client/src/pages/about.federation.vue b/packages/client/src/pages/about.federation.vue
index 89073651a2..9ac4b469d8 100644
--- a/packages/client/src/pages/about.federation.vue
+++ b/packages/client/src/pages/about.federation.vue
@@ -113,9 +113,9 @@ import MkInstanceCardMini from "@/components/MkInstanceCardMini.vue";
 import FormSplit from "@/components/form/split.vue";
 import { i18n } from "@/i18n";
 
-let host = ref("");
-let state = ref("federating");
-let sort = ref("+pubSub");
+const host = ref("");
+const state = ref("federating");
+const sort = ref("+pubSub");
 const pagination = {
 	endpoint: "federation/instances" as const,
 	limit: 10,
diff --git a/packages/client/src/pages/about.vue b/packages/client/src/pages/about.vue
index 57d7b8b0e0..9461c147ef 100644
--- a/packages/client/src/pages/about.vue
+++ b/packages/client/src/pages/about.vue
@@ -11,7 +11,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -173,12 +173,12 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed, onMounted, watch } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import XEmojis from "./about.emojis.vue";
 import XFederation from "./about.federation.vue";
-import { version, instanceName, host } from "@/config";
+import { host, version } from "@/config";
 import FormLink from "@/components/form/link.vue";
 import FormSection from "@/components/form/section.vue";
 import FormSuspense from "@/components/form/suspense.vue";
@@ -205,13 +205,13 @@ withDefaults(
 	},
 );
 
-let stats = ref(null);
-let instanceIcon = ref<HTMLImageElement>();
-let iconClicks = 0;
-let iconSrc = ref(instance.iconUrl || instance.faviconUrl || "/favicon.ico");
-let instanceIconAnimation = ref("");
-let tabs = ["overview", "emojis", "charts"];
-let tab = ref(tabs[0]);
+const stats = ref(null);
+const instanceIcon = ref<HTMLImageElement>();
+let iconClicks = 0,
+	iconSrc = ref(instance.iconUrl || instance.faviconUrl || "/favicon.ico"),
+	instanceIconAnimation = ref(""),
+	tabs = ["overview", "emojis", "charts"],
+	tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
 if (iAmModerator) tabs.push("federation");
@@ -223,7 +223,7 @@ const initStats = () =>
 
 const headerActions = computed(() => []);
 
-let theTabs = [
+const theTabs = [
 	{
 		key: "overview",
 		title: i18n.ts.overview,
@@ -249,7 +249,7 @@ if (iAmModerator) {
 	});
 }
 
-let headerTabs = computed(() => theTabs);
+const headerTabs = computed(() => theTabs);
 
 definePageMetadata(
 	computed(() => ({
diff --git a/packages/client/src/pages/admin-file.vue b/packages/client/src/pages/admin-file.vue
index 60481fd38f..cd3473f29f 100644
--- a/packages/client/src/pages/admin-file.vue
+++ b/packages/client/src/pages/admin-file.vue
@@ -11,7 +11,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -156,7 +156,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import MkButton from "@/components/MkButton.vue";
@@ -172,21 +172,20 @@ import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 import { deviceKind } from "@/scripts/device-kind";
-import { acct } from "@/filters/user";
 import { iAmAdmin, iAmModerator } from "@/account";
 import { defaultStore } from "@/store";
 import "swiper/scss";
 import "swiper/scss/virtual";
 
-let tabs = ["overview"];
+const tabs = ["overview"];
 if (iAmModerator) tabs.push("ip");
 tabs.push("raw");
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
-let file: any = ref(null);
-let info: any = ref(null);
-let isSensitive: boolean = ref(false);
+const file: any = ref(null);
+const info: any = ref(null);
+const isSensitive: boolean = ref(false);
 
 const props = defineProps<{
 	fileId: string;
diff --git a/packages/client/src/pages/admin/_header_.vue b/packages/client/src/pages/admin/_header_.vue
index 360c81b611..16a94d871c 100644
--- a/packages/client/src/pages/admin/_header_.vue
+++ b/packages/client/src/pages/admin/_header_.vue
@@ -56,31 +56,21 @@
 </template>
 
 <script lang="ts" setup>
-import {
-	computed,
-	onMounted,
-	onUnmounted,
-	ref,
-	inject,
-	watch,
-	nextTick,
-} from "vue";
+import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
 import tinycolor from "tinycolor2";
 import { popupMenu } from "@/os";
-import { url } from "@/config";
 import { scrollToTop } from "@/scripts/scroll";
 import MkButton from "@/components/MkButton.vue";
-import { i18n } from "@/i18n";
 import { globalEvents } from "@/events";
 import { injectPageMetadata } from "@/scripts/page-metadata";
 
-type Tab = {
+interface Tab {
 	key?: string | null;
 	title: string;
 	icon?: string;
 	iconOnly?: boolean;
 	onClick?: (ev: MouseEvent) => void;
-};
+}
 
 const props = defineProps<{
 	tabs?: Tab[];
diff --git a/packages/client/src/pages/admin/abuses.vue b/packages/client/src/pages/admin/abuses.vue
index a3e62a0556..56a1c90173 100644
--- a/packages/client/src/pages/admin/abuses.vue
+++ b/packages/client/src/pages/admin/abuses.vue
@@ -93,21 +93,19 @@
 <script lang="ts" setup>
 import { computed, ref } from "vue";
 
-import MkInput from "@/components/form/input.vue";
 import MkSelect from "@/components/form/select.vue";
 import MkPagination from "@/components/MkPagination.vue";
 import XAbuseReport from "@/components/MkAbuseReport.vue";
-import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let reports = ref<InstanceType<typeof MkPagination>>();
+const reports = ref<InstanceType<typeof MkPagination>>();
 
-let state = ref("unresolved");
-let reporterOrigin = ref("combined");
-let targetUserOrigin = ref("combined");
-let searchUsername = ref("");
-let searchHost = ref("");
+const state = ref("unresolved");
+const reporterOrigin = ref("combined");
+const targetUserOrigin = ref("combined");
+const searchUsername = ref("");
+const searchHost = ref("");
 
 const pagination = {
 	endpoint: "admin/abuse-user-reports" as const,
diff --git a/packages/client/src/pages/admin/announcements.vue b/packages/client/src/pages/admin/announcements.vue
index 941b5b1913..5557da2ebe 100644
--- a/packages/client/src/pages/admin/announcements.vue
+++ b/packages/client/src/pages/admin/announcements.vue
@@ -65,9 +65,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
 import MkSwitch from "@/components/form/switch.vue";
@@ -76,7 +75,7 @@ import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let announcements: any[] = ref([]);
+const announcements: any[] = ref([]);
 
 os.api("admin/announcements/list").then((announcementResponse) => {
 	announcements.value = announcementResponse;
diff --git a/packages/client/src/pages/admin/bot-protection.vue b/packages/client/src/pages/admin/bot-protection.vue
index 79960e9d68..2bbe16dc33 100644
--- a/packages/client/src/pages/admin/bot-protection.vue
+++ b/packages/client/src/pages/admin/bot-protection.vue
@@ -88,11 +88,11 @@ const MkCaptcha = defineAsyncComponent(
 	() => import("@/components/MkCaptcha.vue"),
 );
 
-let provider = ref(null);
-let hcaptchaSiteKey: string | null = ref(null);
-let hcaptchaSecretKey: string | null = ref(null);
-let recaptchaSiteKey: string | null = ref(null);
-let recaptchaSecretKey: string | null = ref(null);
+const provider = ref(null);
+const hcaptchaSiteKey: string | null = ref(null);
+const hcaptchaSecretKey: string | null = ref(null);
+const recaptchaSiteKey: string | null = ref(null);
+const recaptchaSecretKey: string | null = ref(null);
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/custom-css.vue b/packages/client/src/pages/admin/custom-css.vue
index 8dfe3530c1..8eaf7f7f54 100644
--- a/packages/client/src/pages/admin/custom-css.vue
+++ b/packages/client/src/pages/admin/custom-css.vue
@@ -17,11 +17,9 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref } from "vue";
 import FormTextarea from "@/components/form/textarea.vue";
 import FormInfo from "@/components/MkInfo.vue";
-import * as os from "@/os";
-import { unisonReload } from "@/scripts/unison-reload";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
diff --git a/packages/client/src/pages/admin/database.vue b/packages/client/src/pages/admin/database.vue
index 94ef4d17e7..51b2bc6175 100644
--- a/packages/client/src/pages/admin/database.vue
+++ b/packages/client/src/pages/admin/database.vue
@@ -36,7 +36,6 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import {} from "vue";
 import FormSuspense from "@/components/form/suspense.vue";
 import FormButton from "@/components/MkButton.vue";
 import MkKeyValue from "@/components/MkKeyValue.vue";
diff --git a/packages/client/src/pages/admin/email-settings.vue b/packages/client/src/pages/admin/email-settings.vue
index ffdc1a665e..1747098e5b 100644
--- a/packages/client/src/pages/admin/email-settings.vue
+++ b/packages/client/src/pages/admin/email-settings.vue
@@ -91,9 +91,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormInput from "@/components/form/input.vue";
 import FormInfo from "@/components/MkInfo.vue";
@@ -105,13 +104,13 @@ import { fetchInstance, instance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let enableEmail: boolean = ref(false);
-let email: any = ref(null);
-let smtpSecure: boolean = ref(false);
-let smtpHost: string = ref("");
-let smtpPort: number = ref(0);
-let smtpUser: string = ref("");
-let smtpPass: string = ref("");
+const enableEmail: boolean = ref(false);
+const email: any = ref(null);
+const smtpSecure: boolean = ref(false);
+const smtpHost: string = ref("");
+const smtpPort: number = ref(0);
+const smtpUser: string = ref("");
+const smtpPass: string = ref("");
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/emoji-edit-dialog.vue b/packages/client/src/pages/admin/emoji-edit-dialog.vue
index cff9f4065c..f0ec4d368c 100644
--- a/packages/client/src/pages/admin/emoji-edit-dialog.vue
+++ b/packages/client/src/pages/admin/emoji-edit-dialog.vue
@@ -43,13 +43,11 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import XModalWindow from "@/components/MkModalWindow.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
 import MkTextarea from "@/components/form/textarea.vue";
 import * as os from "@/os";
-import { unique } from "@/scripts/array";
 import { i18n } from "@/i18n";
 import { emojiCategories } from "@/instance";
 
@@ -57,12 +55,12 @@ const props = defineProps<{
 	emoji: any;
 }>();
 
-let dialog = ref(null);
-let name: string = ref(props.emoji.name);
-let category: string = ref(props.emoji.category);
-let aliases: string = ref(props.emoji.aliases.join(" "));
-let categories: string[] = ref(emojiCategories);
-let license: string = ref(props.emoji.license ?? "");
+const dialog = ref(null);
+const name: string = ref(props.emoji.name);
+const category: string = ref(props.emoji.category);
+const aliases: string = ref(props.emoji.aliases.join(" "));
+const categories: string[] = ref(emojiCategories);
+const license: string = ref(props.emoji.license ?? "");
 
 const emit = defineEmits<{
 	(ev: "done", v: { deleted?: boolean; updated?: any }): void;
diff --git a/packages/client/src/pages/admin/emojis.vue b/packages/client/src/pages/admin/emojis.vue
index cb5b740d99..2a45be562b 100644
--- a/packages/client/src/pages/admin/emojis.vue
+++ b/packages/client/src/pages/admin/emojis.vue
@@ -154,17 +154,10 @@
 </template>
 
 <script lang="ts" setup>
-import {
-	computed,
-	defineAsyncComponent,
-	defineComponent,
-	ref,
-	toRef,
-} from "vue";
+import { computed, defineAsyncComponent, ref } from "vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
 import MkPagination from "@/components/MkPagination.vue";
-import MkTab from "@/components/MkTab.vue";
 import MkSwitch from "@/components/form/switch.vue";
 import FormSplit from "@/components/form/split.vue";
 import { selectFile, selectFiles } from "@/scripts/select-file";
@@ -241,7 +234,7 @@ const edit = (emoji) => {
 	os.popup(
 		defineAsyncComponent(() => import("./emoji-edit-dialog.vue")),
 		{
-			emoji: emoji,
+			emoji,
 		},
 		{
 			done: (result) => {
diff --git a/packages/client/src/pages/admin/experiments.vue b/packages/client/src/pages/admin/experiments.vue
index 9a0f39a28f..66ef6b6e83 100644
--- a/packages/client/src/pages/admin/experiments.vue
+++ b/packages/client/src/pages/admin/experiments.vue
@@ -10,8 +10,8 @@
 			<FormSuspense :p="init">
 				<FormSwitch
 					v-model="enablePostImports"
-					@update:modelValue="save"
 					class="_formBlock"
+					@update:modelValue="save"
 				>
 					<template #label>
 						<i class="ph-download-simple ph-bold ph-lg"></i>
@@ -27,9 +27,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkStickyContainer from "@/components/global/MkStickyContainer.vue";
 import FormSuspense from "@/components/form/suspense.vue";
 import FormSwitch from "@/components/form/switch.vue";
@@ -38,14 +37,14 @@ import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let enablePostImports = ref(false);
-let meta = ref<MetaExperiments | null>(null);
+const enablePostImports = ref(false);
+const meta = ref<MetaExperiments | null>(null);
 
-type MetaExperiments = {
+interface MetaExperiments {
 	experimentalFeatures?: {
 		postImports?: boolean;
 	};
-};
+}
 
 async function init() {
 	meta.value = (await os.api("admin/meta")) as MetaExperiments;
diff --git a/packages/client/src/pages/admin/files.vue b/packages/client/src/pages/admin/files.vue
index 2c160e761f..b13f1f408c 100644
--- a/packages/client/src/pages/admin/files.vue
+++ b/packages/client/src/pages/admin/files.vue
@@ -80,9 +80,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineAsyncComponent, ref } from "vue";
-import * as Acct from "firefish-js/built/acct";
-import MkButton from "@/components/MkButton.vue";
+import { computed, ref } from "vue";
 import MkInput from "@/components/form/input.vue";
 import MkSelect from "@/components/form/select.vue";
 import MkFileListForAdmin from "@/components/MkFileListForAdmin.vue";
@@ -91,11 +89,11 @@ import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let origin = ref("local");
-let type = ref(null);
-let searchHost = ref("");
-let userId = ref("");
-let viewMode = ref("grid");
+const origin = ref("local");
+const type = ref(null);
+const searchHost = ref("");
+const userId = ref("");
+const viewMode = ref("grid");
 const pagination = {
 	endpoint: "admin/drive/files" as const,
 	limit: 10,
diff --git a/packages/client/src/pages/admin/hashtags.vue b/packages/client/src/pages/admin/hashtags.vue
index 6ae71f5b1d..f2a10926c8 100644
--- a/packages/client/src/pages/admin/hashtags.vue
+++ b/packages/client/src/pages/admin/hashtags.vue
@@ -26,9 +26,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import FormButton from "@/components/MkButton.vue";
 import FormTextarea from "@/components/form/textarea.vue";
 import FormSuspense from "@/components/form/suspense.vue";
@@ -37,7 +36,7 @@ import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let hiddenTags: string = ref("");
+const hiddenTags: string = ref("");
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/index.vue b/packages/client/src/pages/admin/index.vue
index e1667fbf87..e288f16022 100644
--- a/packages/client/src/pages/admin/index.vue
+++ b/packages/client/src/pages/admin/index.vue
@@ -59,11 +59,18 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, inject, nextTick, onMounted, onUnmounted, onActivated, provide, watch, ref, computed } from 'vue';
+import {
+	computed,
+	onActivated,
+	onMounted,
+	onUnmounted,
+	provide,
+	ref,
+	watch,
+} from "vue";
 import { i18n } from "@/i18n";
 import MkSuperMenu from "@/components/MkSuperMenu.vue";
 import MkInfo from "@/components/MkInfo.vue";
-import { scroll } from "@/scripts/scroll";
 import { instance } from "@/instance";
 import { version } from "@/config";
 import { $i } from "@/account";
@@ -77,7 +84,6 @@ import { useRouter } from "@/router";
 import {
 	definePageMetadata,
 	provideMetadataReceiver,
-	setPageMetadata,
 } from "@/scripts/page-metadata";
 
 const isEmpty = (x: string | null) => x == null || x === "";
@@ -92,21 +98,21 @@ const indexInfo = {
 
 provide("shouldOmitHeaderTitle", false);
 
-let INFO = ref(indexInfo);
-let childInfo = ref(null);
-let narrow = ref(false);
-let view = ref(null);
-let pageProps = ref({});
-let noMaintainerInformation =
+const INFO = ref(indexInfo);
+const childInfo = ref(null);
+const narrow = ref(false);
+const view = ref(null);
+const pageProps = ref({});
+const noMaintainerInformation =
 	isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail);
-let noBotProtection =
+const noBotProtection =
 	!instance.disableRegistration &&
 	!instance.enableHcaptcha &&
 	!instance.enableRecaptcha;
-let noEmailServer = !instance.enableEmail;
-let thereIsUnresolvedAbuseReport = ref(false);
-let updateAvailable = ref(false);
-let currentPage = computed(() => router.currentRef.value.child);
+const noEmailServer = !instance.enableEmail;
+const thereIsUnresolvedAbuseReport = ref(false);
+const updateAvailable = ref(false);
+const currentPage = computed(() => router.currentRef.value.child);
 
 os.api("admin/abuse-user-reports", {
 	state: "unresolved",
@@ -231,27 +237,31 @@ const menuDef = computed(() => [
 							icon: "ph-gear-six ph-bold ph-lg",
 							text: i18n.ts.general,
 							to: "/admin/settings",
-							active: currentPage.value?.route.name === "settings",
+							active:
+								currentPage.value?.route.name === "settings",
 						},
 						{
 							icon: "ph-envelope-simple-open ph-bold ph-lg",
 							text: i18n.ts.emailServer,
 							to: "/admin/email-settings",
 							active:
-								currentPage.value?.route.name === "email-settings",
+								currentPage.value?.route.name ===
+								"email-settings",
 						},
 						{
 							icon: "ph-cloud ph-bold ph-lg",
 							text: i18n.ts.objectStorage,
 							to: "/admin/object-storage",
 							active:
-								currentPage.value?.route.name === "object-storage",
+								currentPage.value?.route.name ===
+								"object-storage",
 						},
 						{
 							icon: "ph-lock ph-bold ph-lg",
 							text: i18n.ts.security,
 							to: "/admin/security",
-							active: currentPage.value?.route.name === "security",
+							active:
+								currentPage.value?.route.name === "security",
 						},
 						{
 							icon: "ph-arrows-merge ph-bold ph-lg",
@@ -263,38 +273,46 @@ const menuDef = computed(() => [
 							icon: "ph-plug ph-bold ph-lg",
 							text: i18n.ts.integration,
 							to: "/admin/integrations",
-							active: currentPage.value?.route.name === "integrations",
+							active:
+								currentPage.value?.route.name ===
+								"integrations",
 						},
 						{
 							icon: "ph-prohibit ph-bold ph-lg",
 							text: i18n.ts.instanceBlocking,
 							to: "/admin/instance-block",
 							active:
-								currentPage.value?.route.name === "instance-block",
+								currentPage.value?.route.name ===
+								"instance-block",
 						},
 						{
 							icon: "ph-hash ph-bold ph-lg",
 							text: i18n.ts.hiddenTags,
 							to: "/admin/hashtags",
-							active: currentPage.value?.route.name === "hashtags",
+							active:
+								currentPage.value?.route.name === "hashtags",
 						},
 						{
 							icon: "ph-ghost ph-bold ph-lg",
 							text: i18n.ts.proxyAccount,
 							to: "/admin/proxy-account",
-							active: currentPage.value?.route.name === "proxy-account",
+							active:
+								currentPage.value?.route.name ===
+								"proxy-account",
 						},
 						{
 							icon: "ph-database ph-bold ph-lg",
 							text: i18n.ts.database,
 							to: "/admin/database",
-							active: currentPage.value?.route.name === "database",
+							active:
+								currentPage.value?.route.name === "database",
 						},
 						{
 							icon: "ph-flask ph-bold ph-lg",
 							text: i18n.ts._experiments.title,
 							to: "/admin/experiments",
-							active: currentPage.value?.route.name === "experiments",
+							active:
+								currentPage.value?.route.name === "experiments",
 						},
 					],
 				},
@@ -330,7 +348,11 @@ onUnmounted(() => {
 });
 
 watch(router.currentRef, (to) => {
-	if (to.route.path === "/admin" && to.child?.route.name == null && !narrow.value) {
+	if (
+		to.route.path === "/admin" &&
+		to.child?.route.name == null &&
+		!narrow.value
+	) {
 		router.replace("/admin/overview");
 	}
 });
diff --git a/packages/client/src/pages/admin/instance-block.vue b/packages/client/src/pages/admin/instance-block.vue
index bad9ae6f7e..88d00f5a29 100644
--- a/packages/client/src/pages/admin/instance-block.vue
+++ b/packages/client/src/pages/admin/instance-block.vue
@@ -43,9 +43,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import FormButton from "@/components/MkButton.vue";
 import FormTextarea from "@/components/form/textarea.vue";
 import FormSuspense from "@/components/form/suspense.vue";
@@ -55,9 +54,9 @@ import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let blockedHosts: string = ref("");
-let silencedHosts: string = ref("");
-let tab = ref("block");
+const blockedHosts: string = ref("");
+const silencedHosts: string = ref("");
+const tab = ref("block");
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/integrations.discord.vue b/packages/client/src/pages/admin/integrations.discord.vue
index ba81f316fa..70ccef1ed0 100644
--- a/packages/client/src/pages/admin/integrations.discord.vue
+++ b/packages/client/src/pages/admin/integrations.discord.vue
@@ -36,7 +36,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormInput from "@/components/form/input.vue";
 import FormButton from "@/components/MkButton.vue";
@@ -46,10 +45,10 @@ import * as os from "@/os";
 import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 
-let uri: string = ref("");
-let enableDiscordIntegration: boolean = ref(false);
-let discordClientId: string | null = ref(null);
-let discordClientSecret: string | null = ref(null);
+const uri: string = ref("");
+const enableDiscordIntegration: boolean = ref(false);
+const discordClientId: string | null = ref(null);
+const discordClientSecret: string | null = ref(null);
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/integrations.github.vue b/packages/client/src/pages/admin/integrations.github.vue
index a9bd2b8c4d..a2343de19d 100644
--- a/packages/client/src/pages/admin/integrations.github.vue
+++ b/packages/client/src/pages/admin/integrations.github.vue
@@ -36,7 +36,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormInput from "@/components/form/input.vue";
 import FormButton from "@/components/MkButton.vue";
@@ -46,10 +45,10 @@ import * as os from "@/os";
 import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 
-let uri: string = ref("");
-let enableGithubIntegration: boolean = ref(false);
-let githubClientId: string | null = ref(null);
-let githubClientSecret: string | null = ref(null);
+const uri: string = ref("");
+const enableGithubIntegration: boolean = ref(false);
+const githubClientId: string | null = ref(null);
+const githubClientSecret: string | null = ref(null);
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/integrations.vue b/packages/client/src/pages/admin/integrations.vue
index 516d439907..5539b9c03a 100644
--- a/packages/client/src/pages/admin/integrations.vue
+++ b/packages/client/src/pages/admin/integrations.vue
@@ -38,9 +38,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import XGithub from "./integrations.github.vue";
 import XDiscord from "./integrations.discord.vue";
 import FormSuspense from "@/components/form/suspense.vue";
@@ -49,9 +48,9 @@ import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let enableTwitterIntegration: boolean = ref(false);
-let enableGithubIntegration: boolean = ref(false);
-let enableDiscordIntegration: boolean = ref(false);
+const enableTwitterIntegration: boolean = ref(false);
+const enableGithubIntegration: boolean = ref(false);
+const enableDiscordIntegration: boolean = ref(false);
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/object-storage.vue b/packages/client/src/pages/admin/object-storage.vue
index 98eb103ba0..729b162c0c 100644
--- a/packages/client/src/pages/admin/object-storage.vue
+++ b/packages/client/src/pages/admin/object-storage.vue
@@ -149,9 +149,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormInput from "@/components/form/input.vue";
 import FormSuspense from "@/components/form/suspense.vue";
@@ -161,19 +160,19 @@ import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let useObjectStorage: boolean = ref(false);
-let objectStorageBaseUrl: string | null = ref(null);
-let objectStorageBucket: string | null = ref(null);
-let objectStoragePrefix: string | null = ref(null);
-let objectStorageEndpoint: string | null = ref(null);
-let objectStorageRegion: string | null = ref(null);
-let objectStoragePort: number | null = ref(null);
-let objectStorageAccessKey: string | null = ref(null);
-let objectStorageSecretKey: string | null = ref(null);
-let objectStorageUseSSL: boolean = ref(false);
-let objectStorageUseProxy: boolean = ref(false);
-let objectStorageSetPublicRead: boolean = ref(false);
-let objectStorageS3ForcePathStyle: boolean = ref(true);
+const useObjectStorage: boolean = ref(false);
+const objectStorageBaseUrl: string | null = ref(null);
+const objectStorageBucket: string | null = ref(null);
+const objectStoragePrefix: string | null = ref(null);
+const objectStorageEndpoint: string | null = ref(null);
+const objectStorageRegion: string | null = ref(null);
+const objectStoragePort: number | null = ref(null);
+const objectStorageAccessKey: string | null = ref(null);
+const objectStorageSecretKey: string | null = ref(null);
+const objectStorageUseSSL: boolean = ref(false);
+const objectStorageUseProxy: boolean = ref(false);
+const objectStorageSetPublicRead: boolean = ref(false);
+const objectStorageS3ForcePathStyle: boolean = ref(true);
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/other-settings.vue b/packages/client/src/pages/admin/other-settings.vue
index 55ec9021b4..523f05d6a3 100644
--- a/packages/client/src/pages/admin/other-settings.vue
+++ b/packages/client/src/pages/admin/other-settings.vue
@@ -15,7 +15,6 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import {} from "vue";
 import FormSuspense from "@/components/form/suspense.vue";
 import * as os from "@/os";
 import { fetchInstance } from "@/instance";
diff --git a/packages/client/src/pages/admin/overview.active-users.vue b/packages/client/src/pages/admin/overview.active-users.vue
index 0337c0acf9..45b3306807 100644
--- a/packages/client/src/pages/admin/overview.active-users.vue
+++ b/packages/client/src/pages/admin/overview.active-users.vue
@@ -8,15 +8,13 @@
 </template>
 
 <script lang="ts" setup>
-import { markRaw, version as vueVersion, onMounted, onBeforeUnmount, nextTick, shallowRef, ref } from 'vue';
+import { onMounted, ref, shallowRef } from "vue";
 import { Chart } from "chart.js";
-import tinycolor from "tinycolor2";
 import gradient from "chartjs-plugin-gradient";
 import * as os from "@/os";
 import { defaultStore } from "@/store";
 import { useChartTooltip } from "@/scripts/use-chart-tooltip";
 import { chartVLine } from "@/scripts/chart-vline";
-import { alpha } from "@/scripts/color";
 import { initChart } from "@/scripts/init-chart";
 
 initChart();
@@ -25,7 +23,7 @@ const chartEl = shallowRef<HTMLCanvasElement>(null);
 const now = new Date();
 let chartInstance: Chart = null;
 const chartLimit = 7;
-let fetching = ref(true);
+const fetching = ref(true);
 
 const { handler: externalTooltipHandler } = useChartTooltip();
 
@@ -134,7 +132,7 @@ async function renderChart() {
 					},
 					ticks: {
 						display: true,
-						//mirror: true,
+						// mirror: true,
 					},
 				},
 			},
diff --git a/packages/client/src/pages/admin/overview.ap-requests.vue b/packages/client/src/pages/admin/overview.ap-requests.vue
index 550684a886..65fff7ac8a 100644
--- a/packages/client/src/pages/admin/overview.ap-requests.vue
+++ b/packages/client/src/pages/admin/overview.ap-requests.vue
@@ -15,15 +15,10 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, shallowRef } from "vue";
+import { onMounted, ref, shallowRef } from "vue";
 import { Chart } from "chart.js";
 import gradient from "chartjs-plugin-gradient";
-import tinycolor from "tinycolor2";
-import MkMiniChart from "@/components/MkMiniChart.vue";
 import * as os from "@/os";
-import number from "@/filters/number";
-import MkNumberDiff from "@/components/MkNumberDiff.vue";
-import { i18n } from "@/i18n";
 import { useChartTooltip } from "@/scripts/use-chart-tooltip";
 import { chartVLine } from "@/scripts/chart-vline";
 import { defaultStore } from "@/store";
@@ -35,7 +30,7 @@ initChart();
 const chartLimit = 50;
 const chartEl = shallowRef<HTMLCanvasElement>();
 const chartEl2 = shallowRef<HTMLCanvasElement>();
-let fetching = ref(true);
+const fetching = ref(true);
 
 const { handler: externalTooltipHandler } = useChartTooltip();
 const { handler: externalTooltipHandler2 } = useChartTooltip();
@@ -153,7 +148,7 @@ onMounted(async () => {
 					},
 					ticks: {
 						display: true,
-						//mirror: true,
+						// mirror: true,
 						callback: (value, index, values) =>
 							value < 0 ? -value : value,
 					},
diff --git a/packages/client/src/pages/admin/overview.federation.vue b/packages/client/src/pages/admin/overview.federation.vue
index 28da787e6c..f643e784d5 100644
--- a/packages/client/src/pages/admin/overview.federation.vue
+++ b/packages/client/src/pages/admin/overview.federation.vue
@@ -56,22 +56,21 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { onMounted, ref } from "vue";
 import XPie from "./overview.pie.vue";
-import MkMiniChart from "@/components/MkMiniChart.vue";
 import * as os from "@/os";
 import number from "@/filters/number";
 import MkNumberDiff from "@/components/MkNumberDiff.vue";
 import { i18n } from "@/i18n";
 import { useChartTooltip } from "@/scripts/use-chart-tooltip";
 
-let topSubInstancesForPie: any = ref(null);
-let topPubInstancesForPie: any = ref(null);
-let federationPubActive = ref<number | null>(null);
-let federationPubActiveDiff = ref<number | null>(null);
-let federationSubActive = ref<number | null>(null);
-let federationSubActiveDiff = ref<number | null>(null);
-let fetching = ref(true);
+const topSubInstancesForPie: any = ref(null);
+const topPubInstancesForPie: any = ref(null);
+const federationPubActive = ref<number | null>(null);
+const federationPubActiveDiff = ref<number | null>(null);
+const federationSubActive = ref<number | null>(null);
+const federationSubActiveDiff = ref<number | null>(null);
+const fetching = ref(true);
 
 const { handler: externalTooltipHandler } = useChartTooltip();
 
diff --git a/packages/client/src/pages/admin/overview.heatmap.vue b/packages/client/src/pages/admin/overview.heatmap.vue
index e70cc739d1..886e433eee 100644
--- a/packages/client/src/pages/admin/overview.heatmap.vue
+++ b/packages/client/src/pages/admin/overview.heatmap.vue
@@ -23,7 +23,7 @@ import { ref } from "vue";
 import MkHeatmap from "@/components/MkHeatmap.vue";
 import MkSelect from "@/components/form/select.vue";
 
-let src = ref("notes");
+const src = ref("notes");
 </script>
 
 <style lang="scss" module>
diff --git a/packages/client/src/pages/admin/overview.instances.vue b/packages/client/src/pages/admin/overview.instances.vue
index e5d0d1d32c..0dce60f3c1 100644
--- a/packages/client/src/pages/admin/overview.instances.vue
+++ b/packages/client/src/pages/admin/overview.instances.vue
@@ -23,7 +23,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { ref } from "vue";
 import * as os from "@/os";
 import { useInterval } from "@/scripts/use-interval";
 import MkInstanceCardMini from "@/components/MkInstanceCardMini.vue";
diff --git a/packages/client/src/pages/admin/overview.metrics.vue b/packages/client/src/pages/admin/overview.metrics.vue
index b995c65a98..d9b2ae1204 100644
--- a/packages/client/src/pages/admin/overview.metrics.vue
+++ b/packages/client/src/pages/admin/overview.metrics.vue
@@ -54,7 +54,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, computed } from "vue";
+import { computed, onMounted, onUnmounted, ref } from "vue";
 import XPie from "../../widgets/server-metric/pie.vue";
 import bytes from "@/filters/bytes";
 import { stream } from "@/stream";
@@ -64,17 +64,17 @@ import { i18n } from "@/i18n";
 const meta = await os.api("server-info", {});
 const serverStats = await os.api("stats");
 
-let cpuUsage: number = ref(0);
+const cpuUsage: number = ref(0);
 
-let memUsage: number = ref(0);
-let memTotal: number = ref(0);
-let memUsed: number = ref(0);
-let memFree: number = ref(0);
+const memUsage: number = ref(0);
+const memTotal: number = ref(0);
+const memUsed: number = ref(0);
+const memFree: number = ref(0);
 
-let meiliProgress: number = ref(0);
-let meiliTotalSize: number = ref(0);
-let meiliIndexCount: number = ref(0);
-let meiliAvailable: string = ref("unavailable");
+const meiliProgress: number = ref(0);
+const meiliTotalSize: number = ref(0);
+const meiliIndexCount: number = ref(0);
+const meiliAvailable: string = ref("unavailable");
 
 const diskUsage = computed(() => meta.fs.used / meta.fs.total);
 const diskTotal = computed(() => meta.fs.total);
diff --git a/packages/client/src/pages/admin/overview.moderators.vue b/packages/client/src/pages/admin/overview.moderators.vue
index b1ebed6a57..38eecb1559 100644
--- a/packages/client/src/pages/admin/overview.moderators.vue
+++ b/packages/client/src/pages/admin/overview.moderators.vue
@@ -16,7 +16,7 @@
 						:user="user"
 						class="avatar"
 						indicator
-						disableLink
+						disable-link
 					/>
 				</MkA>
 			</div>
@@ -25,13 +25,11 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { onMounted, ref } from "vue";
 import * as os from "@/os";
-import number from "@/filters/number";
-import { i18n } from "@/i18n";
 
-let moderators: any = ref(null);
-let fetching = ref(true);
+const moderators: any = ref(null);
+const fetching = ref(true);
 
 onMounted(async () => {
 	moderators.value = await os.api("admin/show-users", {
diff --git a/packages/client/src/pages/admin/overview.pie.vue b/packages/client/src/pages/admin/overview.pie.vue
index 5317c6cdd8..c18b53e20f 100644
--- a/packages/client/src/pages/admin/overview.pie.vue
+++ b/packages/client/src/pages/admin/overview.pie.vue
@@ -3,10 +3,8 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, shallowRef } from "vue";
+import { onMounted, shallowRef } from "vue";
 import { Chart } from "chart.js";
-import number from "@/filters/number";
-import { defaultStore } from "@/store";
 import { useChartTooltip } from "@/scripts/use-chart-tooltip";
 import { initChart } from "@/scripts/init-chart";
 
diff --git a/packages/client/src/pages/admin/overview.queue-chart.vue b/packages/client/src/pages/admin/overview.queue-chart.vue
index 1348bde98e..06d3c47017 100644
--- a/packages/client/src/pages/admin/overview.queue-chart.vue
+++ b/packages/client/src/pages/admin/overview.queue-chart.vue
@@ -3,26 +3,24 @@
 </template>
 
 <script lang="ts" setup>
-import { defineComponent, onMounted, onUnmounted, ref } from "vue";
+import { onMounted, onUnmounted, ref } from "vue";
 import {
-	Chart,
 	ArcElement,
-	LineElement,
-	BarElement,
-	PointElement,
 	BarController,
-	LineController,
+	BarElement,
 	CategoryScale,
-	LinearScale,
-	TimeScale,
+	Chart,
+	Filler,
 	Legend,
+	LineController,
+	LineElement,
+	LinearScale,
+	PointElement,
+	SubTitle,
+	TimeScale,
 	Title,
 	Tooltip,
-	SubTitle,
-	Filler,
 } from "chart.js";
-import number from "@/filters/number";
-import * as os from "@/os";
 import { defaultStore } from "@/store";
 import { useChartTooltip } from "@/scripts/use-chart-tooltip";
 
diff --git a/packages/client/src/pages/admin/overview.queue.chart.vue b/packages/client/src/pages/admin/overview.queue.chart.vue
index 01a0d0ec07..5e64d1acf1 100644
--- a/packages/client/src/pages/admin/overview.queue.chart.vue
+++ b/packages/client/src/pages/admin/overview.queue.chart.vue
@@ -3,10 +3,8 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, onMounted, onUnmounted, ref, shallowRef } from "vue";
+import { onMounted, shallowRef } from "vue";
 import { Chart } from "chart.js";
-import number from "@/filters/number";
-import * as os from "@/os";
 import { defaultStore } from "@/store";
 import { useChartTooltip } from "@/scripts/use-chart-tooltip";
 import { chartVLine } from "@/scripts/chart-vline";
@@ -82,7 +80,7 @@ onMounted(() => {
 			labels: [],
 			datasets: [
 				{
-					label: label,
+					label,
 					pointRadius: 0,
 					tension: 0.3,
 					borderWidth: 2,
diff --git a/packages/client/src/pages/admin/overview.queue.vue b/packages/client/src/pages/admin/overview.queue.vue
index 1084f2e397..4900ca0a46 100644
--- a/packages/client/src/pages/admin/overview.queue.vue
+++ b/packages/client/src/pages/admin/overview.queue.vue
@@ -45,9 +45,7 @@
 import { markRaw, onMounted, onUnmounted, ref, shallowRef } from "vue";
 import XChart from "./overview.queue.chart.vue";
 import number from "@/filters/number";
-import * as os from "@/os";
 import { stream } from "@/stream";
-import { i18n } from "@/i18n";
 
 const connection = markRaw(stream.useChannel("queueStats"));
 
@@ -55,10 +53,10 @@ const activeSincePrevTick = ref(0);
 const active = ref(0);
 const delayed = ref(0);
 const waiting = ref(0);
-let chartProcess = shallowRef<InstanceType<typeof XChart>>();
-let chartActive = shallowRef<InstanceType<typeof XChart>>();
-let chartDelayed = shallowRef<InstanceType<typeof XChart>>();
-let chartWaiting = shallowRef<InstanceType<typeof XChart>>();
+const chartProcess = shallowRef<InstanceType<typeof XChart>>();
+const chartActive = shallowRef<InstanceType<typeof XChart>>();
+const chartDelayed = shallowRef<InstanceType<typeof XChart>>();
+const chartWaiting = shallowRef<InstanceType<typeof XChart>>();
 
 const props = defineProps<{
 	domain: string;
diff --git a/packages/client/src/pages/admin/overview.stats.vue b/packages/client/src/pages/admin/overview.stats.vue
index de301b0b9b..86ea74a479 100644
--- a/packages/client/src/pages/admin/overview.stats.vue
+++ b/packages/client/src/pages/admin/overview.stats.vue
@@ -94,20 +94,18 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
-import MkMiniChart from "@/components/MkMiniChart.vue";
+import { onMounted, ref } from "vue";
 import * as os from "@/os";
-import number from "@/filters/number";
 import MkNumberDiff from "@/components/MkNumberDiff.vue";
 import MkNumber from "@/components/MkNumber.vue";
 import { i18n } from "@/i18n";
 
-let stats: any = ref(null);
-let usersComparedToThePrevDay = ref<number>();
-let notesComparedToThePrevDay = ref<number>();
-let onlineUsersCount = ref(0);
-let emojiCount = ref(0);
-let fetching = ref(true);
+const stats: any = ref(null);
+const usersComparedToThePrevDay = ref<number>();
+const notesComparedToThePrevDay = ref<number>();
+const onlineUsersCount = ref(0);
+const emojiCount = ref(0);
+const fetching = ref(true);
 
 onMounted(async () => {
 	const [_stats, _onlineUsersCount] = await Promise.all([
diff --git a/packages/client/src/pages/admin/overview.user.vue b/packages/client/src/pages/admin/overview.user.vue
index 860044ea81..a2de5c85f4 100644
--- a/packages/client/src/pages/admin/overview.user.vue
+++ b/packages/client/src/pages/admin/overview.user.vue
@@ -19,7 +19,7 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkMiniChart from "@/components/MkMiniChart.vue";
 import * as os from "@/os";
 import { acct } from "@/filters/user";
@@ -28,7 +28,7 @@ const props = defineProps<{
 	user: misskey.entities.User;
 }>();
 
-let chart = ref(null);
+const chart = ref(null);
 
 os.apiGet("charts/user/notes", {
 	userId: props.user.id,
diff --git a/packages/client/src/pages/admin/overview.users.vue b/packages/client/src/pages/admin/overview.users.vue
index 30f60e7482..516fb7d18c 100644
--- a/packages/client/src/pages/admin/overview.users.vue
+++ b/packages/client/src/pages/admin/overview.users.vue
@@ -20,13 +20,13 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { ref } from "vue";
 import * as os from "@/os";
 import { useInterval } from "@/scripts/use-interval";
 import MkUserCardMini from "@/components/MkUserCardMini.vue";
 
-let newUsers = ref(null);
-let fetching = ref(true);
+const newUsers = ref(null);
+const fetching = ref(true);
 
 const fetch = async () => {
 	const _newUsers = await os.api("admin/show-users", {
diff --git a/packages/client/src/pages/admin/overview.vue b/packages/client/src/pages/admin/overview.vue
index a4f5c40703..9039724d7f 100644
--- a/packages/client/src/pages/admin/overview.vue
+++ b/packages/client/src/pages/admin/overview.vue
@@ -60,7 +60,15 @@
 </template>
 
 <script lang="ts" setup>
-import { markRaw, version as vueVersion, onMounted, onBeforeUnmount, nextTick, shallowRef, ref, computed } from 'vue';
+import {
+	computed,
+	markRaw,
+	nextTick,
+	onBeforeUnmount,
+	onMounted,
+	ref,
+	shallowRef,
+} from "vue";
 import XFederation from "./overview.federation.vue";
 import XInstances from "./overview.instances.vue";
 import XQueue from "./overview.queue.vue";
@@ -71,26 +79,22 @@ import XStats from "./overview.stats.vue";
 import XModerators from "./overview.moderators.vue";
 import XHeatmap from "./overview.heatmap.vue";
 // import XMetrics from "./overview.metrics.vue";
-import MkTagCloud from "@/components/MkTagCloud.vue";
-import { version, url } from "@/config";
 import * as os from "@/os";
 import { stream } from "@/stream";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
-import { defaultStore } from "@/store";
-import MkFileListForAdmin from "@/components/MkFileListForAdmin.vue";
 import MkFolder from "@/components/MkFolder.vue";
 
 const rootEl = shallowRef<HTMLElement>();
-let serverInfo: any = ref(null);
-let topSubInstancesForPie: any = ref(null);
-let topPubInstancesForPie: any = ref(null);
-let federationPubActive = ref<number | null>(null);
-let federationPubActiveDiff = ref<number | null>(null);
-let federationSubActive = ref<number | null>(null);
-let federationSubActiveDiff = ref<number | null>(null);
-let newUsers = ref(null);
-let activeInstances = shallowRef(null);
+const serverInfo: any = ref(null);
+const topSubInstancesForPie: any = ref(null);
+const topPubInstancesForPie: any = ref(null);
+const federationPubActive = ref<number | null>(null);
+const federationPubActiveDiff = ref<number | null>(null);
+const federationSubActive = ref<number | null>(null);
+const federationSubActiveDiff = ref<number | null>(null);
+const newUsers = ref(null);
+const activeInstances = shallowRef(null);
 const queueStatsConnection = markRaw(stream.useChannel("queueStats"));
 const now = new Date();
 const filesPagination = {
diff --git a/packages/client/src/pages/admin/promotions.vue b/packages/client/src/pages/admin/promotions.vue
index c8147bb8df..96eac3cdb3 100644
--- a/packages/client/src/pages/admin/promotions.vue
+++ b/packages/client/src/pages/admin/promotions.vue
@@ -24,8 +24,8 @@
 					</FormRadios>
 					<FormSplit>
 						<MkInput
-							:disabled="ad.place === 'widget'"
 							v-model="ad.ratio"
+							:disabled="ad.place === 'widget'"
 							type="number"
 						>
 							<template #label>{{ i18n.ts.ratio }}</template>
@@ -63,9 +63,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
 import MkTextarea from "@/components/form/textarea.vue";
@@ -76,12 +75,12 @@ import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 import { formatDateTimeString } from "@/scripts/format-time-string";
 
-let ads: any[] = ref([]);
+const ads: any[] = ref([]);
 
 os.api("admin/ad/list").then((adsResponse) => {
 	ads.value = adsResponse;
 	// The date format should be changed to yyyy-MM-dd in order to be properly displayed
-	for (let i in ads.value) {
+	for (const i in ads.value) {
 		ads.value[i].expiresAt = ads.value[i].expiresAt.substr(0, 10);
 	}
 });
diff --git a/packages/client/src/pages/admin/proxy-account.vue b/packages/client/src/pages/admin/proxy-account.vue
index ae0502d3cd..eb644acc30 100644
--- a/packages/client/src/pages/admin/proxy-account.vue
+++ b/packages/client/src/pages/admin/proxy-account.vue
@@ -35,9 +35,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkKeyValue from "@/components/MkKeyValue.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInfo from "@/components/MkInfo.vue";
@@ -47,8 +46,8 @@ import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let proxyAccount: any = ref(null);
-let proxyAccountId: any = ref(null);
+const proxyAccount: any = ref(null);
+const proxyAccountId: any = ref(null);
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/queue.chart.chart.vue b/packages/client/src/pages/admin/queue.chart.chart.vue
index 3335a7b896..513c06bbe5 100644
--- a/packages/client/src/pages/admin/queue.chart.chart.vue
+++ b/packages/client/src/pages/admin/queue.chart.chart.vue
@@ -3,26 +3,24 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, onMounted, onUnmounted, ref } from "vue";
+import { onMounted, ref } from "vue";
 import {
-	Chart,
 	ArcElement,
-	LineElement,
-	BarElement,
-	PointElement,
 	BarController,
-	LineController,
+	BarElement,
 	CategoryScale,
-	LinearScale,
-	TimeScale,
+	Chart,
+	Filler,
 	Legend,
+	LineController,
+	LineElement,
+	LinearScale,
+	PointElement,
+	SubTitle,
+	TimeScale,
 	Title,
 	Tooltip,
-	SubTitle,
-	Filler,
 } from "chart.js";
-import number from "@/filters/number";
-import * as os from "@/os";
 import { defaultStore } from "@/store";
 import { useChartTooltip } from "@/scripts/use-chart-tooltip";
 
@@ -123,7 +121,7 @@ onMounted(() => {
 			labels: [],
 			datasets: [
 				{
-					label: label,
+					label,
 					pointRadius: 0,
 					tension: 0.3,
 					borderWidth: 2,
diff --git a/packages/client/src/pages/admin/queue.chart.vue b/packages/client/src/pages/admin/queue.chart.vue
index b220201d3d..fad0deb6ca 100644
--- a/packages/client/src/pages/admin/queue.chart.vue
+++ b/packages/client/src/pages/admin/queue.chart.vue
@@ -42,8 +42,8 @@
 			<div v-if="jobs.length > 0">
 				<div v-for="job in jobs" :key="job[0]">
 					<a
-						@click.stop="os.pageWindow(`/instance-info/${job[0]}`)"
 						class="_link"
+						@click.stop="os.pageWindow(`/instance-info/${job[0]}`)"
 					>
 						{{ job[0] }}
 					</a>
@@ -72,10 +72,10 @@ const active = ref(0);
 const delayed = ref(0);
 const waiting = ref(0);
 const jobs = ref([]);
-let chartProcess = ref<InstanceType<typeof XChart>>();
-let chartActive = ref<InstanceType<typeof XChart>>();
-let chartDelayed = ref<InstanceType<typeof XChart>>();
-let chartWaiting = ref<InstanceType<typeof XChart>>();
+const chartProcess = ref<InstanceType<typeof XChart>>();
+const chartActive = ref<InstanceType<typeof XChart>>();
+const chartDelayed = ref<InstanceType<typeof XChart>>();
+const chartWaiting = ref<InstanceType<typeof XChart>>();
 
 const props = defineProps<{
 	domain: string;
diff --git a/packages/client/src/pages/admin/queue.vue b/packages/client/src/pages/admin/queue.vue
index 15a6bdcf02..39f79fd0c0 100644
--- a/packages/client/src/pages/admin/queue.vue
+++ b/packages/client/src/pages/admin/queue.vue
@@ -15,22 +15,14 @@
 </template>
 
 <script lang="ts" setup>
-import {
-	markRaw,
-	onMounted,
-	onBeforeUnmount,
-	nextTick,
-	ref,
-	computed,
-} from "vue";
+import { computed, ref } from "vue";
 import XQueue from "./queue.chart.vue";
-import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
 import * as config from "@/config";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let tab = ref("deliver");
+const tab = ref("deliver");
 
 function clear() {
 	os.confirm({
diff --git a/packages/client/src/pages/admin/relays.vue b/packages/client/src/pages/admin/relays.vue
index 948336eb2c..a9fb68a562 100644
--- a/packages/client/src/pages/admin/relays.vue
+++ b/packages/client/src/pages/admin/relays.vue
@@ -43,15 +43,14 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let relays: any[] = ref([]);
+const relays: any[] = ref([]);
 
 async function addRelay() {
 	const { canceled, result: inbox } = await os.inputText({
diff --git a/packages/client/src/pages/admin/security.vue b/packages/client/src/pages/admin/security.vue
index 1c3f2e5826..9cdc11bf09 100644
--- a/packages/client/src/pages/admin/security.vue
+++ b/packages/client/src/pages/admin/security.vue
@@ -255,14 +255,12 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import XBotProtection from "./bot-protection.vue";
 import FormFolder from "@/components/form/folder.vue";
 import FormRadios from "@/components/form/radios.vue";
 import FormSwitch from "@/components/form/switch.vue";
-import FormInfo from "@/components/MkInfo.vue";
 import FormSuspense from "@/components/form/suspense.vue";
 import FormRange from "@/components/form/range.vue";
 import FormInput from "@/components/form/input.vue";
@@ -273,19 +271,19 @@ import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let summalyProxy: string = ref("");
-let enableHcaptcha: boolean = ref(false);
-let enableRecaptcha: boolean = ref(false);
-let sensitiveMediaDetection: string = ref("none");
-let sensitiveMediaDetectionSensitivity: number = ref(0);
-let setSensitiveFlagAutomatically: boolean = ref(false);
-let enableSensitiveMediaDetectionForVideos: boolean = ref(false);
-let enableIpLogging: boolean = ref(false);
-let enableActiveEmailValidation: boolean = ref(false);
+const summalyProxy: string = ref("");
+const enableHcaptcha: boolean = ref(false);
+const enableRecaptcha: boolean = ref(false);
+const sensitiveMediaDetection: string = ref("none");
+const sensitiveMediaDetectionSensitivity: number = ref(0);
+const setSensitiveFlagAutomatically: boolean = ref(false);
+const enableSensitiveMediaDetectionForVideos: boolean = ref(false);
+const enableIpLogging: boolean = ref(false);
+const enableActiveEmailValidation: boolean = ref(false);
 
-let secureMode: boolean = ref(false);
-let privateMode: boolean = ref(false);
-let allowedHosts: string = ref("");
+const secureMode: boolean = ref(false);
+const privateMode: boolean = ref(false);
+const allowedHosts: string = ref("");
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/settings.vue b/packages/client/src/pages/admin/settings.vue
index 9b47214c0d..a3d4ca890e 100644
--- a/packages/client/src/pages/admin/settings.vue
+++ b/packages/client/src/pages/admin/settings.vue
@@ -428,7 +428,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormInput from "@/components/form/input.vue";
 import FormTextarea from "@/components/form/textarea.vue";
@@ -442,42 +442,42 @@ import { fetchInstance } from "@/instance";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let name: string | null = ref(null);
-let description: string | null = ref(null);
-let tosUrl: string | null = ref(null);
-let maintainerName: string | null = ref(null);
-let maintainerEmail: string | null = ref(null);
-let donationLink: string | null = ref(null);
-let iconUrl: string | null = ref(null);
-let bannerUrl: string | null = ref(null);
-let logoImageUrl: string | null = ref(null);
-let backgroundImageUrl: string | null = ref(null);
-let themeColor: any = ref(null);
-let defaultLightTheme: any = ref(null);
-let defaultDarkTheme: any = ref(null);
-let enableLocalTimeline: boolean = ref(false);
-let enableGlobalTimeline: boolean = ref(false);
-let enableRecommendedTimeline: boolean = ref(false);
-let pinnedUsers: string = ref("");
-let customMOTD: string = ref("");
-let recommendedInstances: string = ref("");
-let customSplashIcons: string = ref("");
-let cacheRemoteFiles: boolean = ref(false);
-let localDriveCapacityMb: any = ref(0);
-let remoteDriveCapacityMb: any = ref(0);
-let enableRegistration: boolean = ref(false);
-let emailRequiredForSignup: boolean = ref(false);
-let enableServiceWorker: boolean = ref(false);
-let swPublicKey: any = ref(null);
-let swPrivateKey: any = ref(null);
-let deeplAuthKey: string = ref("");
-let deeplIsPro: boolean = ref(false);
-let libreTranslateApiUrl: string = ref("");
-let libreTranslateApiKey: string = ref("");
-let defaultReaction: string = ref("");
-let defaultReactionCustom: string = ref("");
-let enableServerMachineStats: boolean = ref(false);
-let enableIdenticonGeneration: boolean = ref(false);
+const name: string | null = ref(null);
+const description: string | null = ref(null);
+const tosUrl: string | null = ref(null);
+const maintainerName: string | null = ref(null);
+const maintainerEmail: string | null = ref(null);
+const donationLink: string | null = ref(null);
+const iconUrl: string | null = ref(null);
+const bannerUrl: string | null = ref(null);
+const logoImageUrl: string | null = ref(null);
+const backgroundImageUrl: string | null = ref(null);
+const themeColor: any = ref(null);
+const defaultLightTheme: any = ref(null);
+const defaultDarkTheme: any = ref(null);
+const enableLocalTimeline: boolean = ref(false);
+const enableGlobalTimeline: boolean = ref(false);
+const enableRecommendedTimeline: boolean = ref(false);
+const pinnedUsers: string = ref("");
+const customMOTD: string = ref("");
+const recommendedInstances: string = ref("");
+const customSplashIcons: string = ref("");
+const cacheRemoteFiles: boolean = ref(false);
+const localDriveCapacityMb: any = ref(0);
+const remoteDriveCapacityMb: any = ref(0);
+const enableRegistration: boolean = ref(false);
+const emailRequiredForSignup: boolean = ref(false);
+const enableServiceWorker: boolean = ref(false);
+const swPublicKey: any = ref(null);
+const swPrivateKey: any = ref(null);
+const deeplAuthKey: string = ref("");
+const deeplIsPro: boolean = ref(false);
+const libreTranslateApiUrl: string = ref("");
+const libreTranslateApiKey: string = ref("");
+const defaultReaction: string = ref("");
+const defaultReactionCustom: string = ref("");
+const enableServerMachineStats: boolean = ref(false);
+const enableIdenticonGeneration: boolean = ref(false);
 
 async function init() {
 	const meta = await os.api("admin/meta");
diff --git a/packages/client/src/pages/admin/users.vue b/packages/client/src/pages/admin/users.vue
index f7afa558c8..07eebe946e 100644
--- a/packages/client/src/pages/admin/users.vue
+++ b/packages/client/src/pages/admin/users.vue
@@ -133,13 +133,13 @@ import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 import MkUserCardMini from "@/components/MkUserCardMini.vue";
 
-let paginationComponent = ref<InstanceType<typeof MkPagination>>();
+const paginationComponent = ref<InstanceType<typeof MkPagination>>();
 
-let sort = ref("+createdAt");
-let state = ref("all");
-let origin = ref("local");
-let searchUsername = ref("");
-let searchHost = ref("");
+const sort = ref("+createdAt");
+const state = ref("all");
+const origin = ref("local");
+const searchUsername = ref("");
+const searchHost = ref("");
 const pagination = {
 	endpoint: "admin/show-users" as const,
 	limit: 10,
@@ -172,8 +172,8 @@ async function addUser() {
 	if (canceled2) return;
 
 	os.apiWithDialog("admin/accounts/create", {
-		username: username,
-		password: password,
+		username,
+		password,
 	}).then((res) => {
 		paginationComponent.value.reload();
 	});
diff --git a/packages/client/src/pages/announcements.vue b/packages/client/src/pages/announcements.vue
index e60b56d8dc..1830613644 100644
--- a/packages/client/src/pages/announcements.vue
+++ b/packages/client/src/pages/announcements.vue
@@ -45,7 +45,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 import MkPagination from "@/components/MkPagination.vue";
 import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
diff --git a/packages/client/src/pages/antenna-timeline.vue b/packages/client/src/pages/antenna-timeline.vue
index 0fb93c7a0b..27ae3d8b53 100644
--- a/packages/client/src/pages/antenna-timeline.vue
+++ b/packages/client/src/pages/antenna-timeline.vue
@@ -24,7 +24,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, inject, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import XTimeline from "@/components/MkTimeline.vue";
 import * as os from "@/os";
 import { useRouter } from "@/router";
@@ -37,9 +37,9 @@ const props = defineProps<{
 	antennaId: string;
 }>();
 
-let antenna = ref(null);
-let rootEl = ref<HTMLElement>();
-let tlEl = ref<InstanceType<typeof XTimeline>>();
+const antenna = ref(null);
+const rootEl = ref<HTMLElement>();
+const tlEl = ref<InstanceType<typeof XTimeline>>();
 const keymap = computed(() => ({
 	t: focus,
 }));
diff --git a/packages/client/src/pages/api-console.vue b/packages/client/src/pages/api-console.vue
index f8b9ae38b0..b7a533c450 100644
--- a/packages/client/src/pages/api-console.vue
+++ b/packages/client/src/pages/api-console.vue
@@ -44,9 +44,9 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 import JSON5 from "json5";
-import { Endpoints } from "firefish-js";
+import type { Endpoints } from "firefish-js";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
 import MkTextarea from "@/components/form/textarea.vue";
diff --git a/packages/client/src/pages/auth.form.vue b/packages/client/src/pages/auth.form.vue
index 189650f30a..0a122144e5 100644
--- a/packages/client/src/pages/auth.form.vue
+++ b/packages/client/src/pages/auth.form.vue
@@ -26,7 +26,6 @@
 </template>
 
 <script lang="ts" setup>
-import { defineComponent } from "vue";
 import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/pages/auth.vue b/packages/client/src/pages/auth.vue
index ea404d1630..7fb2c84660 100644
--- a/packages/client/src/pages/auth.vue
+++ b/packages/client/src/pages/auth.vue
@@ -113,7 +113,7 @@ export default defineComponent({
 			if (this.session.app.callbackUrl && isMastodon) {
 				const callbackUrl = new URL(this.session.app.callbackUrl);
 				callbackUrl.searchParams.append("code", this.session.token);
-				if (!!getUrlParams().state)
+				if (getUrlParams().state)
 					callbackUrl.searchParams.append(
 						"state",
 						getUrlParams().state,
diff --git a/packages/client/src/pages/channel-editor.vue b/packages/client/src/pages/channel-editor.vue
index 5492dac296..256a5be5cf 100644
--- a/packages/client/src/pages/channel-editor.vue
+++ b/packages/client/src/pages/channel-editor.vue
@@ -40,7 +40,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, inject, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import MkTextarea from "@/components/form/textarea.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
@@ -56,11 +56,11 @@ const props = defineProps<{
 	channelId?: string;
 }>();
 
-let channel = ref(null);
-let name = ref(null);
-let description = ref(null);
-let bannerUrl = ref<string | null>(null);
-let bannerId = ref<string | null>(null);
+const channel = ref(null);
+const name = ref(null);
+const description = ref(null);
+const bannerUrl = ref<string | null>(null);
+const bannerId = ref<string | null>(null);
 
 watch(
 	() => bannerId.value,
diff --git a/packages/client/src/pages/channel.vue b/packages/client/src/pages/channel.vue
index 974c779320..6269f3eee8 100644
--- a/packages/client/src/pages/channel.vue
+++ b/packages/client/src/pages/channel.vue
@@ -101,8 +101,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, inject, watch, ref } from "vue";
-import MkContainer from "@/components/MkContainer.vue";
+import { computed, ref, watch } from "vue";
 import XPostForm from "@/components/MkPostForm.vue";
 import XTimeline from "@/components/MkTimeline.vue";
 import XChannelFollowButton from "@/components/MkChannelFollowButton.vue";
@@ -118,8 +117,8 @@ const props = defineProps<{
 	channelId: string;
 }>();
 
-let channel = ref(null);
-let showBanner = ref(true);
+const channel = ref(null);
+const showBanner = ref(true);
 
 watch(
 	() => props.channelId,
diff --git a/packages/client/src/pages/channels.vue b/packages/client/src/pages/channels.vue
index cc38ea304f..05e4817896 100644
--- a/packages/client/src/pages/channels.vue
+++ b/packages/client/src/pages/channels.vue
@@ -14,7 +14,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -42,8 +42,8 @@
 						</MkInput>
 						<MkRadios
 							v-model="searchType"
-							@update:model-value="search()"
 							class="_gap"
+							@update:model-value="search()"
 						>
 							<option value="nameAndDescription">
 								{{ i18n.ts._channel.nameAndDescription }}
@@ -52,7 +52,7 @@
 								{{ i18n.ts._channel.nameOnly }}
 							</option>
 						</MkRadios>
-						<MkButton large primary @click="search" class="_gap">{{
+						<MkButton large primary class="_gap" @click="search">{{
 							i18n.ts.search
 						}}</MkButton>
 						<MkFoldableSection v-if="channelPagination">
@@ -111,16 +111,13 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, onMounted, defineComponent, inject, watch, ref } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
-import MkChannelPreview from "@/components/MkChannelPreview.vue";
 import MkChannelList from "@/components/MkChannelList.vue";
-import MkPagination from "@/components/MkPagination.vue";
 import MkInput from "@/components/form/input.vue";
 import MkRadios from "@/components/form/radios.vue";
 import MkButton from "@/components/MkButton.vue";
-import MkFolder from "@/components/MkFolder.vue";
 import MkInfo from "@/components/MkInfo.vue";
 import { useRouter } from "@/router";
 import { definePageMetadata } from "@/scripts/page-metadata";
@@ -133,17 +130,17 @@ import "swiper/scss/virtual";
 const router = useRouter();
 
 const tabs = ["search", "featured", "following", "owned"];
-let tab = ref(tabs[1]);
+const tab = ref(tabs[1]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
 const props = defineProps<{
 	query: string;
 	type?: string;
 }>();
-let key = ref("");
-let searchQuery = ref("");
-let searchType = ref("nameAndDescription");
-let channelPagination = ref();
+const key = ref("");
+const searchQuery = ref("");
+const searchType = ref("nameAndDescription");
+const channelPagination = ref();
 onMounted(() => {
 	searchQuery.value = props.query ?? "";
 	searchType.value = props.type ?? "nameAndDescription";
@@ -172,7 +169,7 @@ async function search() {
 		limit: 10,
 		params: {
 			query: searchQuery.value,
-			type: type,
+			type,
 		},
 	};
 	key.value = query + type;
diff --git a/packages/client/src/pages/clip.vue b/packages/client/src/pages/clip.vue
index b630a91025..1b1bd8e267 100644
--- a/packages/client/src/pages/clip.vue
+++ b/packages/client/src/pages/clip.vue
@@ -28,7 +28,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, provide, ref } from "vue";
+import { computed, provide, ref, watch } from "vue";
 import type * as misskey from "firefish-js";
 import XNotes from "@/components/MkNotes.vue";
 import { $i } from "@/account";
@@ -40,7 +40,7 @@ const props = defineProps<{
 	clipId: string;
 }>();
 
-let clip: misskey.entities.Clip = ref<misskey.entities.Clip>();
+const clip: misskey.entities.Clip = ref<misskey.entities.Clip>();
 const pagination = {
 	endpoint: "clips/notes" as const,
 	limit: 10,
diff --git a/packages/client/src/pages/drive.vue b/packages/client/src/pages/drive.vue
index 1b3a1b965c..5ba0e2b86a 100644
--- a/packages/client/src/pages/drive.vue
+++ b/packages/client/src/pages/drive.vue
@@ -7,11 +7,10 @@
 <script lang="ts" setup>
 import { computed, ref } from "vue";
 import XDrive from "@/components/MkDrive.vue";
-import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let folder = ref(null);
+const folder = ref(null);
 
 const headerActions = computed(() => []);
 
diff --git a/packages/client/src/pages/explore.featured.vue b/packages/client/src/pages/explore.featured.vue
index 23cccc7552..bb09686183 100644
--- a/packages/client/src/pages/explore.featured.vue
+++ b/packages/client/src/pages/explore.featured.vue
@@ -45,5 +45,5 @@ const paginationForRemote = {
 // 	offsetMode: true,
 // };
 
-let tab = ref("local");
+const tab = ref("local");
 </script>
diff --git a/packages/client/src/pages/explore.users.vue b/packages/client/src/pages/explore.users.vue
index 07403a2ba9..74134fdbbb 100644
--- a/packages/client/src/pages/explore.users.vue
+++ b/packages/client/src/pages/explore.users.vue
@@ -141,24 +141,22 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import XUserList from "@/components/MkUserList.vue";
 import MkFolder from "@/components/MkFolder.vue";
 import MkTab from "@/components/MkTab.vue";
-import number from "@/filters/number";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { $i } from "@/account";
-import { instance } from "@/instance";
 
 const props = defineProps<{
 	tag?: string;
 }>();
 
-let origin = ref("local");
-let tagsEl = ref<InstanceType<typeof MkFolder>>();
-let tagsLocal = ref([]);
-let tagsRemote = ref([]);
+const origin = ref("local");
+const tagsEl = ref<InstanceType<typeof MkFolder>>();
+const tagsLocal = ref([]);
+const tagsRemote = ref([]);
 
 watch(
 	() => props.tag,
diff --git a/packages/client/src/pages/explore.vue b/packages/client/src/pages/explore.vue
index d68dd5d6ab..a6e9fc752b 100644
--- a/packages/client/src/pages/explore.vue
+++ b/packages/client/src/pages/explore.vue
@@ -12,7 +12,7 @@
 					:round-lengths="true"
 					:touch-angle="25"
 					:threshold="10"
-					:centeredSlides="true"
+					:centered-slides="true"
 					:modules="[Virtual]"
 					:space-between="20"
 					:virtual="true"
@@ -37,7 +37,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, onMounted, ref } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import XFeatured from "./explore.featured.vue";
@@ -50,7 +50,7 @@ import "swiper/scss";
 import "swiper/scss/virtual";
 
 const tabs = ["users", "featured"];
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
 const headerActions = computed(() => []);
diff --git a/packages/client/src/pages/follow-requests.vue b/packages/client/src/pages/follow-requests.vue
index dd323f7b0f..c8bc0c6678 100644
--- a/packages/client/src/pages/follow-requests.vue
+++ b/packages/client/src/pages/follow-requests.vue
@@ -27,7 +27,7 @@
 								class="avatar"
 								:user="req.follower"
 								:show-indicator="true"
-								disableLink
+								disable-link
 							/>
 							<div class="body">
 								<div class="name">
@@ -59,15 +59,15 @@
 								<div class="actions">
 									<button
 										class="_button"
-										@click="accept(req.follower)"
 										:aria-label="i18n.t('accept')"
+										@click="accept(req.follower)"
 									>
 										<i class="ph-check ph-bold ph-lg"></i>
 									</button>
 									<button
 										class="_button"
-										@click="reject(req.follower)"
 										:aria-label="i18n.t('reject')"
+										@click="reject(req.follower)"
 									>
 										<i class="ph-x ph-bold ph-lg"></i>
 									</button>
@@ -82,9 +82,9 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 import MkPagination from "@/components/MkPagination.vue";
-import { userPage, acct } from "@/filters/user";
+import { acct, userPage } from "@/filters/user";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
diff --git a/packages/client/src/pages/gallery/edit.vue b/packages/client/src/pages/gallery/edit.vue
index 39a308cebe..7b444c6247 100644
--- a/packages/client/src/pages/gallery/edit.vue
+++ b/packages/client/src/pages/gallery/edit.vue
@@ -28,8 +28,8 @@
 						<button
 							v-tooltip="i18n.ts.remove"
 							class="remove _button"
-							@click="remove(file)"
 							:aria-label="i18n.t('remove')"
+							@click="remove(file)"
 						>
 							<i class="ph-x ph-bold ph-lg"></i>
 						</button>
@@ -63,7 +63,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, inject, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import FormButton from "@/components/MkButton.vue";
 import FormInput from "@/components/form/input.vue";
 import FormTextarea from "@/components/form/textarea.vue";
@@ -81,11 +81,11 @@ const props = defineProps<{
 	postId?: string;
 }>();
 
-let init = ref(null);
-let files = ref([]);
-let description = ref(null);
-let title = ref(null);
-let isSensitive = ref(false);
+const init = ref(null);
+const files = ref([]);
+const description = ref(null);
+const title = ref(null);
+const isSensitive = ref(false);
 
 function selectFile(evt) {
 	selectFiles(evt.currentTarget ?? evt.target, null).then((selected) => {
diff --git a/packages/client/src/pages/gallery/index.vue b/packages/client/src/pages/gallery/index.vue
index 4cee4f953c..0c9755181f 100644
--- a/packages/client/src/pages/gallery/index.vue
+++ b/packages/client/src/pages/gallery/index.vue
@@ -12,7 +12,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -106,7 +106,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineComponent, watch, onMounted, ref } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import MkFolder from "@/components/MkFolder.vue";
@@ -127,10 +127,10 @@ const props = defineProps<{
 }>();
 
 const tabs = ["explore", "liked", "my"];
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
-let tagsRef = ref();
+const tagsRef = ref();
 
 const recentPostsPagination = {
 	endpoint: "gallery/posts" as const,
diff --git a/packages/client/src/pages/gallery/post.vue b/packages/client/src/pages/gallery/post.vue
index 98a544f607..3f3266c634 100644
--- a/packages/client/src/pages/gallery/post.vue
+++ b/packages/client/src/pages/gallery/post.vue
@@ -145,7 +145,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineComponent, inject, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
 import MkContainer from "@/components/MkContainer.vue";
@@ -164,8 +164,8 @@ const props = defineProps<{
 	postId: string;
 }>();
 
-let post = ref(null);
-let error = ref(null);
+const post = ref(null);
+const error = ref(null);
 const otherPostsPagination = {
 	endpoint: "users/gallery/posts" as const,
 	limit: 6,
diff --git a/packages/client/src/pages/instance-info.vue b/packages/client/src/pages/instance-info.vue
index 6cac8b4e8c..6a5e8c6e96 100644
--- a/packages/client/src/pages/instance-info.vue
+++ b/packages/client/src/pages/instance-info.vue
@@ -16,7 +16,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -337,7 +337,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import type * as firefish from "firefish-js";
@@ -376,18 +376,18 @@ const props = defineProps<{
 	host: string;
 }>();
 
-let tabs = ["overview"];
+const tabs = ["overview"];
 if (iAmAdmin) tabs.push("chart", "users", "raw");
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
-let chartSrc = ref("instance-requests");
-let meta = ref<AugmentedInstanceMetadata | null>(null);
-let instance = ref<AugmentedInstance | null>(null);
-let suspended = ref(false);
-let isBlocked = ref(false);
-let isSilenced = ref(false);
-let faviconUrl = ref(null);
+const chartSrc = ref("instance-requests");
+const meta = ref<AugmentedInstanceMetadata | null>(null);
+const instance = ref<AugmentedInstance | null>(null);
+const suspended = ref(false);
+const isBlocked = ref(false);
+const isSilenced = ref(false);
+const faviconUrl = ref(null);
 
 const usersPagination = {
 	endpoint: iAmAdmin ? "admin/show-users" : ("users" as const),
@@ -478,7 +478,7 @@ const headerActions = computed(() => [
 	},
 ]);
 
-let theTabs = [
+const theTabs = [
 	{
 		key: "overview",
 		title: i18n.ts.overview,
@@ -506,7 +506,7 @@ if (iAmAdmin) {
 	);
 }
 
-let headerTabs = computed(() => theTabs);
+const headerTabs = computed(() => theTabs);
 
 definePageMetadata({
 	title: props.host,
diff --git a/packages/client/src/pages/messaging/index.vue b/packages/client/src/pages/messaging/index.vue
index 48e34a1be9..cb5320affa 100644
--- a/packages/client/src/pages/messaging/index.vue
+++ b/packages/client/src/pages/messaging/index.vue
@@ -12,7 +12,7 @@
 					:round-lengths="true"
 					:touch-angle="25"
 					:threshold="10"
-					:centeredSlides="true"
+					:centered-slides="true"
 					:modules="[Virtual]"
 					:space-between="20"
 					:virtual="true"
@@ -27,9 +27,9 @@
 					<swiper-slide>
 						<div class="_content yweeujhr dms">
 							<MkButton
+								v-if="!isMobile"
 								primary
 								class="start"
-								v-if="!isMobile"
 								@click="startUser"
 								><i class="ph-plus ph-bold ph-lg"></i>
 								{{ i18n.ts.startMessaging }}</MkButton
@@ -88,7 +88,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, markRaw, onMounted, onUnmounted, watch, computed } from "vue";
+import { computed, markRaw, onMounted, onUnmounted, ref, watch } from "vue";
 import * as Acct from "firefish-js/built/acct";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
@@ -108,11 +108,11 @@ import "swiper/scss/virtual";
 
 const router = useRouter();
 
-let messages = ref([]);
-let connection = ref(null);
+const messages = ref([]);
+const connection = ref(null);
 
 const tabs = ["dms", "groups"];
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
 const MOBILE_THRESHOLD = 500;
diff --git a/packages/client/src/pages/messaging/messaging-room.form.vue b/packages/client/src/pages/messaging/messaging-room.form.vue
index 0d318013ca..6ca305ddc4 100644
--- a/packages/client/src/pages/messaging/messaging-room.form.vue
+++ b/packages/client/src/pages/messaging/messaging-room.form.vue
@@ -19,15 +19,15 @@
 			<div class="buttons">
 				<button
 					class="_button"
-					@click="chooseFile"
 					:aria-label="i18n.t('attachFile')"
+					@click="chooseFile"
 				>
 					<i class="ph-upload ph-bold ph-lg"></i>
 				</button>
 				<button
 					class="_button"
-					@click="insertEmoji"
 					:aria-label="i18n.t('chooseEmoji')"
+					@click="insertEmoji"
 				>
 					<i class="ph-smiley ph-bold ph-lg"></i>
 				</button>
@@ -55,10 +55,10 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, watch, ref, computed } from "vue";
-import * as Misskey from "firefish-js";
+import { computed, onMounted, ref, watch } from "vue";
+import type * as Misskey from "firefish-js";
 import autosize from "autosize";
-//import insertTextAtCursor from 'insert-text-at-cursor';
+// import insertTextAtCursor from 'insert-text-at-cursor';
 import { throttle } from "throttle-debounce";
 import { Autocomplete } from "@/scripts/autocomplete";
 import { formatTimeString } from "@/scripts/format-time-string";
@@ -74,12 +74,12 @@ const props = defineProps<{
 	group?: Misskey.entities.UserGroup | null;
 }>();
 
-let textEl = ref<HTMLTextAreaElement>();
-let fileEl = ref<HTMLInputElement>();
+const textEl = ref<HTMLTextAreaElement>();
+const fileEl = ref<HTMLInputElement>();
 
-let text = ref<string>("");
-let file = ref<Misskey.entities.DriveFile | null>(null);
-let sending = ref(false);
+const text = ref<string>("");
+const file = ref<Misskey.entities.DriveFile | null>(null);
+const sending = ref(false);
 const typing = throttle(3000, () => {
 	stream.send(
 		"typingOnMessaging",
@@ -87,10 +87,10 @@ const typing = throttle(3000, () => {
 	);
 });
 
-let draftKey = computed(() =>
+const draftKey = computed(() =>
 	props.user ? "user:" + props.user.id : "group:" + props.group?.id,
 );
-let canSend = computed(
+const canSend = computed(
 	() =>
 		(text.value != null && text.value.trim() !== "") || file.value != null,
 );
@@ -155,18 +155,18 @@ function onDrop(ev: DragEvent): void {
 		return;
 	}
 
-	//#region ドライブのファイル
+	// #region ドライブのファイル
 	const driveFile = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 	if (driveFile != null && driveFile !== "") {
 		file.value = JSON.parse(driveFile);
 		ev.preventDefault();
 	}
-	//#endregion
+	// #endregion
 }
 
 function onKeydown(ev: KeyboardEvent) {
 	typing();
-	let sendOnEnter =
+	const sendOnEnter =
 		localStorage.getItem("enterSendsMessage") === "true" ||
 		defaultStore.state.enterSendsMessage;
 	if (sendOnEnter) {
diff --git a/packages/client/src/pages/messaging/messaging-room.message.vue b/packages/client/src/pages/messaging/messaging-room.message.vue
index 7c9a337da9..a23e8621c0 100644
--- a/packages/client/src/pages/messaging/messaging-room.message.vue
+++ b/packages/client/src/pages/messaging/messaging-room.message.vue
@@ -84,7 +84,6 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import {} from "vue";
 import * as mfm from "mfm-js";
 import type * as Misskey from "firefish-js";
 import XMediaList from "@/components/MkMediaList.vue";
diff --git a/packages/client/src/pages/messaging/messaging-room.vue b/packages/client/src/pages/messaging/messaging-room.vue
index 95cbea6885..07df8d435d 100644
--- a/packages/client/src/pages/messaging/messaging-room.vue
+++ b/packages/client/src/pages/messaging/messaging-room.vue
@@ -28,9 +28,9 @@
 							#default="{ items: messages, fetching: pFetching }"
 						>
 							<XList
-								aria-live="polite"
 								v-if="messages.length > 0"
 								v-slot="{ item: message }"
+								aria-live="polite"
 								:class="{
 									messages: true,
 									'deny-move-transition': pFetching,
@@ -99,18 +99,19 @@
 <script lang="ts" setup>
 import {
 	computed,
-	watch,
-	onMounted,
 	nextTick,
 	onBeforeUnmount,
+	onMounted,
 	ref,
+	watch,
 } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import * as Acct from "firefish-js/built/acct";
 import XMessage from "./messaging-room.message.vue";
 import XForm from "./messaging-room.form.vue";
 import XList from "@/components/MkDateSeparatedList.vue";
-import MkPagination, { Paging } from "@/components/MkPagination.vue";
+import type { Paging } from "@/components/MkPagination.vue";
+import MkPagination from "@/components/MkPagination.vue";
 import {
 	isBottomVisible,
 	onScrollBottom,
@@ -129,21 +130,21 @@ const props = defineProps<{
 	groupId?: string;
 }>();
 
-let rootEl = ref<HTMLDivElement>();
-let formEl = ref<InstanceType<typeof XForm>>();
-let pagingComponent = ref<InstanceType<typeof MkPagination>>();
+const rootEl = ref<HTMLDivElement>();
+const formEl = ref<InstanceType<typeof XForm>>();
+const pagingComponent = ref<InstanceType<typeof MkPagination>>();
 
-let fetching = ref(true);
-let user: Misskey.entities.UserDetailed | null = ref(null);
-let group: Misskey.entities.UserGroup | null = ref(null);
-let typers: Misskey.entities.User[] = ref([]);
-let connection: Misskey.ChannelConnection<
+const fetching = ref(true);
+const user: Misskey.entities.UserDetailed | null = ref(null);
+const group: Misskey.entities.UserGroup | null = ref(null);
+const typers: Misskey.entities.User[] = ref([]);
+const connection: Misskey.ChannelConnection<
 	Misskey.Channels["messaging"]
 > | null = ref(null);
-let showIndicator = ref(false);
+const showIndicator = ref(false);
 const { animation } = defaultStore.reactiveState;
 
-let pagination: Paging | null = ref(null);
+const pagination: Paging | null = ref(null);
 
 watch([() => props.userAcct, () => props.groupId], () => {
 	if (connection.value) connection.value.dispose();
@@ -239,13 +240,13 @@ function onDrop(ev: DragEvent): void {
 		return;
 	}
 
-	//#region ドライブのファイル
+	// #region ドライブのファイル
 	const driveFile = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 	if (driveFile != null && driveFile !== "") {
 		const file = JSON.parse(driveFile);
 		formEl.value.file = file;
 	}
-	//#endregion
+	// #endregion
 }
 
 function onMessage(message) {
@@ -323,7 +324,7 @@ function onIndicatorClick() {
 	thisScrollToBottom();
 }
 
-let scrollRemove: (() => void) | null = ref(null);
+const scrollRemove: (() => void) | null = ref(null);
 
 function notifyNewMessage() {
 	showIndicator.value = true;
diff --git a/packages/client/src/pages/mfm-cheat-sheet.vue b/packages/client/src/pages/mfm-cheat-sheet.vue
index 54c6c60c25..b1c676443f 100644
--- a/packages/client/src/pages/mfm-cheat-sheet.vue
+++ b/packages/client/src/pages/mfm-cheat-sheet.vue
@@ -443,7 +443,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineComponent, ref } from "vue";
+import { ref } from "vue";
 import MkTextarea from "@/components/form/textarea.vue";
 import { definePageMetadata } from "@/scripts/page-metadata";
 import { i18n } from "@/i18n";
@@ -453,80 +453,82 @@ defineProps<{
 	popup?: boolean;
 }>();
 
-let preview_mention = ref("@example");
-let preview_hashtag = ref("#test");
-let preview_link = ref(`[${i18n.ts._mfm.dummy}](https://joinfirefish.org)`);
-let preview_emoji = ref(
+const preview_mention = ref("@example");
+const preview_hashtag = ref("#test");
+const preview_link = ref(`[${i18n.ts._mfm.dummy}](https://joinfirefish.org)`);
+const preview_emoji = ref(
 	instance.emojis.length ? `:${instance.emojis[0].name}:` : ":emojiname:",
 );
-let preview_bold = ref(`**${i18n.ts._mfm.dummy}**`);
-let preview_small = ref(
+const preview_bold = ref(`**${i18n.ts._mfm.dummy}**`);
+const preview_small = ref(
 	`<small>${i18n.ts._mfm.dummy}</small> $[small ${i18n.ts._mfm.dummy}]`,
 );
-let preview_center = ref(
+const preview_center = ref(
 	`<center>${i18n.ts._mfm.dummy}</center> $[center ${i18n.ts._mfm.dummy}]`,
 );
-let preview_inlineCode = ref('`<: "Hello, world!"`');
-let preview_blockCode = ref(
+const preview_inlineCode = ref('`<: "Hello, world!"`');
+const preview_blockCode = ref(
 	'```\n~ (#i, 100) {\n\t<: ? ((i % 15) = 0) "FizzBuzz"\n\t\t.? ((i % 3) = 0) "Fizz"\n\t\t.? ((i % 5) = 0) "Buzz"\n\t\t. i\n}\n```',
 );
-let preview_inlineMath = ref("\\(x= \\frac{-b' \\pm \\sqrt{(b')^2-ac}}{a}\\)");
-let preview_blockMath = ref("\\[x= \\frac{-b' \\pm \\sqrt{(b')^2-ac}}{a}\\]");
-let preview_quote = ref(`> ${i18n.ts._mfm.dummy}`);
-let preview_search = ref(
+const preview_inlineMath = ref(
+	"\\(x= \\frac{-b' \\pm \\sqrt{(b')^2-ac}}{a}\\)",
+);
+const preview_blockMath = ref("\\[x= \\frac{-b' \\pm \\sqrt{(b')^2-ac}}{a}\\]");
+const preview_quote = ref(`> ${i18n.ts._mfm.dummy}`);
+const preview_search = ref(
 	`${i18n.ts._mfm.dummy} [search]\n${i18n.ts._mfm.dummy} [検索]\n${i18n.ts._mfm.dummy} 検索`,
 );
-let preview_jelly = ref(
+const preview_jelly = ref(
 	"$[jelly 🍮] $[jelly.speed=3s 🍮] $[jelly.delay=3s 🍮] $[jelly.loop=3 🍮]",
 );
-let preview_tada = ref(
+const preview_tada = ref(
 	"$[tada 🍮] $[tada.speed=3s 🍮] $[tada.delay=3s 🍮] $[tada.loop=3 🍮]",
 );
-let preview_jump = ref(
+const preview_jump = ref(
 	"$[jump 🍮] $[jump.speed=3s 🍮] $[jump.delay=3s 🍮] $[jump.loop=3 🍮]",
 );
-let preview_bounce = ref(
+const preview_bounce = ref(
 	"$[bounce 🍮] $[bounce.speed=3s 🍮] $[bounce.delay=3s 🍮] $[bounce.loop=3 🍮]",
 );
-let preview_shake = ref(
+const preview_shake = ref(
 	"$[shake 🍮] $[shake.speed=3s 🍮] $[shake.delay=3s 🍮] $[shake.loop=3 🍮]",
 );
-let preview_twitch = ref(
+const preview_twitch = ref(
 	"$[twitch 🍮] $[twitch.speed=3s 🍮] $[twitch.delay=3s 🍮] $[twitch.loop=3 🍮]",
 );
-let preview_spin = ref(
+const preview_spin = ref(
 	"$[spin 🍮] $[spin.left 🍮] $[spin.alternate 🍮]\n$[spin.x 🍮] $[spin.x,left 🍮] $[spin.x,alternate 🍮]\n$[spin.y 🍮] $[spin.y,left 🍮] $[spin.y,alternate 🍮]\n\n$[spin.speed=3s 🍮] $[spin.delay=3s 🍮] $[spin.loop=3 🍮]",
 );
-let preview_flip = ref(
+const preview_flip = ref(
 	`$[flip ${i18n.ts._mfm.dummy}]\n$[flip.v ${i18n.ts._mfm.dummy}]\n$[flip.h,v ${i18n.ts._mfm.dummy}]`,
 );
-let preview_font = ref(
+const preview_font = ref(
 	`$[font.serif ${i18n.ts._mfm.dummy}]\n$[font.monospace ${i18n.ts._mfm.dummy}]\n$[font.cursive ${i18n.ts._mfm.dummy}]\n$[font.fantasy ${i18n.ts._mfm.dummy}]`,
 );
-let preview_x2 = ref("$[x2 🍮]");
-let preview_x3 = ref("$[x3 🍮]");
-let preview_x4 = ref("$[x4 🍮]");
-let preview_blur = ref(`$[blur ${i18n.ts._mfm.dummy}]`);
-let preview_rainbow = ref(
+const preview_x2 = ref("$[x2 🍮]");
+const preview_x3 = ref("$[x3 🍮]");
+const preview_x4 = ref("$[x4 🍮]");
+const preview_blur = ref(`$[blur ${i18n.ts._mfm.dummy}]`);
+const preview_rainbow = ref(
 	"$[rainbow 🍮] $[rainbow.speed=3s 🍮] $[rainbow.delay=3s 🍮] $[rainbow.loop=3 🍮]",
 );
-let preview_sparkle = ref("$[sparkle 🍮]");
-let preview_rotate = ref(
+const preview_sparkle = ref("$[sparkle 🍮]");
+const preview_rotate = ref(
 	"$[rotate 🍮]\n$[rotate.deg=45 🍮]\n$[rotate.x,deg=45 Hello, world!]",
 );
-let preview_position = ref("$[position.y=-1 🍮]\n$[position.x=-1 🍮]");
-let preview_crop = ref(
+const preview_position = ref("$[position.y=-1 🍮]\n$[position.x=-1 🍮]");
+const preview_crop = ref(
 	"$[crop.top=50 🍮] $[crop.right=50 🍮] $[crop.bottom=50 🍮] $[crop.left=50 🍮]",
 );
-let preview_scale = ref(
+const preview_scale = ref(
 	"$[scale.x=1.3 🍮]\n$[scale.x=1.5,y=3 🍮]\n$[scale.y=0.3 🍮]",
 );
-let preview_fg = ref("$[fg.color=eb6f92 Text color]");
-let preview_bg = ref("$[bg.color=31748f Background color]");
-let preview_plain = ref(
+const preview_fg = ref("$[fg.color=eb6f92 Text color]");
+const preview_bg = ref("$[bg.color=31748f Background color]");
+const preview_plain = ref(
 	"<plain>**bold** @mention #hashtag `code` $[x2 🍮]</plain>",
 );
-let preview_fade = ref(
+const preview_fade = ref(
 	"$[fade 🍮] $[fade.out 🍮] $[fade.speed=3s 🍮] $[fade.delay=3s 🍮]",
 );
 
diff --git a/packages/client/src/pages/miauth.vue b/packages/client/src/pages/miauth.vue
index 4e85d71b26..a03fce16e9 100644
--- a/packages/client/src/pages/miauth.vue
+++ b/packages/client/src/pages/miauth.vue
@@ -80,7 +80,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import MkSignin from "@/components/MkSignin.vue";
 import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
@@ -98,7 +97,7 @@ const props = defineProps<{
 
 const _permissions = props.permission.split(",");
 
-let state = ref<string | null>(null);
+const state = ref<string | null>(null);
 
 function getIcon(p: string) {
 	return p.includes("write") ? "pencil-simple" : "eye";
diff --git a/packages/client/src/pages/my-antennas/create.vue b/packages/client/src/pages/my-antennas/create.vue
index 250633dede..9f755805c7 100644
--- a/packages/client/src/pages/my-antennas/create.vue
+++ b/packages/client/src/pages/my-antennas/create.vue
@@ -16,7 +16,7 @@ import { useRouter } from "@/router";
 
 const router = useRouter();
 
-let draft = ref({
+const draft = ref({
 	name: "",
 	src: "all",
 	userListId: null,
diff --git a/packages/client/src/pages/my-antennas/edit.vue b/packages/client/src/pages/my-antennas/edit.vue
index 3b64f3f7aa..6218f30fbd 100644
--- a/packages/client/src/pages/my-antennas/edit.vue
+++ b/packages/client/src/pages/my-antennas/edit.vue
@@ -9,7 +9,7 @@
 </template>
 
 <script lang="ts" setup>
-import { inject, watch, ref, computed } from "vue";
+import { computed, ref } from "vue";
 import XAntenna from "./editor.vue";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
@@ -18,7 +18,7 @@ import { definePageMetadata } from "@/scripts/page-metadata";
 
 const router = useRouter();
 
-let antenna: any = ref(null);
+const antenna: any = ref(null);
 
 const props = defineProps<{
 	antennaId: string;
diff --git a/packages/client/src/pages/my-antennas/editor.vue b/packages/client/src/pages/my-antennas/editor.vue
index a9e58807c3..0f0102f89e 100644
--- a/packages/client/src/pages/my-antennas/editor.vue
+++ b/packages/client/src/pages/my-antennas/editor.vue
@@ -114,7 +114,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref } from "vue";
+import { ref, watch } from "vue";
 import * as Acct from "firefish-js/built/acct";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
@@ -134,24 +134,24 @@ const emit = defineEmits<{
 	(ev: "deleted"): void;
 }>();
 
-let name: string = ref(props.antenna.name);
-let src: string = ref(props.antenna.src);
-let userListId: any = ref(props.antenna.userListId);
-let userGroupId: any = ref(props.antenna.userGroupId);
-let users: string = ref(props.antenna.users.join("\n"));
-let instances: string = ref(props.antenna.instances.join("\n"));
-let keywords: string = ref(
+const name: string = ref(props.antenna.name);
+const src: string = ref(props.antenna.src);
+const userListId: any = ref(props.antenna.userListId);
+const userGroupId: any = ref(props.antenna.userGroupId);
+const users: string = ref(props.antenna.users.join("\n"));
+const instances: string = ref(props.antenna.instances.join("\n"));
+const keywords: string = ref(
 	props.antenna.keywords.map((x) => x.join(" ")).join("\n"),
 );
-let excludeKeywords: string = ref(
+const excludeKeywords: string = ref(
 	props.antenna.excludeKeywords.map((x) => x.join(" ")).join("\n"),
 );
-let caseSensitive: boolean = ref(props.antenna.caseSensitive);
-let withReplies: boolean = ref(props.antenna.withReplies);
-let withFile: boolean = ref(props.antenna.withFile);
-let notify: boolean = ref(props.antenna.notify);
-let userLists: any = ref(null);
-let userGroups: any = ref(null);
+const caseSensitive: boolean = ref(props.antenna.caseSensitive);
+const withReplies: boolean = ref(props.antenna.withReplies);
+const withFile: boolean = ref(props.antenna.withFile);
+const notify: boolean = ref(props.antenna.notify);
+const userLists: any = ref(null);
+const userGroups: any = ref(null);
 
 watch(
 	() => src.value,
@@ -201,7 +201,7 @@ async function saveAntenna() {
 		await os.apiWithDialog("antennas/create", antennaData);
 		emit("created");
 	} else {
-		antennaData["antennaId"] = props.antenna.id;
+		antennaData.antennaId = props.antenna.id;
 		await os.apiWithDialog("antennas/update", antennaData);
 		emit("updated");
 	}
diff --git a/packages/client/src/pages/my-antennas/index.vue b/packages/client/src/pages/my-antennas/index.vue
index 3a722dcefb..d1185cedab 100644
--- a/packages/client/src/pages/my-antennas/index.vue
+++ b/packages/client/src/pages/my-antennas/index.vue
@@ -55,7 +55,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onActivated, onDeactivated, ref, computed } from "vue";
+import { computed, onActivated, onDeactivated, ref } from "vue";
 import MkPagination from "@/components/MkPagination.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInfo from "@/components/MkInfo.vue";
@@ -73,8 +73,8 @@ const headerTabs = computed(() => []);
 
 const list = ref<typeof MkPagination | null>(null);
 
-let isCached: boolean = false;
-let refreshTimer: number | null = null;
+let isCached = false,
+	refreshTimer: number | null = null;
 
 const refresh = () => {
 	if (isCached) {
diff --git a/packages/client/src/pages/my-clips/index.vue b/packages/client/src/pages/my-clips/index.vue
index fdfaf509d1..e8e9e6bd96 100644
--- a/packages/client/src/pages/my-clips/index.vue
+++ b/packages/client/src/pages/my-clips/index.vue
@@ -38,11 +38,9 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkPagination from "@/components/MkPagination.vue";
-import MkButton from "@/components/MkButton.vue";
 import MkInfo from "@/components/MkInfo.vue";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/pages/my-groups/group.vue b/packages/client/src/pages/my-groups/group.vue
index 0868efcfff..ec687247ef 100644
--- a/packages/client/src/pages/my-groups/group.vue
+++ b/packages/client/src/pages/my-groups/group.vue
@@ -22,8 +22,8 @@
 							<div class="action">
 								<button
 									class="_button"
-									@click="removeUser(user)"
 									:aria-label="i18n.t('removeMember')"
+									@click="removeUser(user)"
 								>
 									<i class="ph-x ph-bold ph-lg"></i>
 								</button>
@@ -104,7 +104,7 @@ async function renameGroup() {
 
 	await os.api("users/groups/update", {
 		groupId: group.value.id,
-		name: name,
+		name,
 	});
 
 	group.value.name = name;
diff --git a/packages/client/src/pages/my-groups/index.vue b/packages/client/src/pages/my-groups/index.vue
index 719d717cae..a976bee4eb 100644
--- a/packages/client/src/pages/my-groups/index.vue
+++ b/packages/client/src/pages/my-groups/index.vue
@@ -91,7 +91,7 @@ async function create() {
 		title: i18n.ts.groupName,
 	});
 	if (canceled) return;
-	await os.api("users/groups/create", { name: name });
+	await os.api("users/groups/create", { name });
 	owned.value.reload();
 	os.success();
 }
diff --git a/packages/client/src/pages/my-lists/index.vue b/packages/client/src/pages/my-lists/index.vue
index 09b4469a6a..9fb5bb8b19 100644
--- a/packages/client/src/pages/my-lists/index.vue
+++ b/packages/client/src/pages/my-lists/index.vue
@@ -42,9 +42,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkPagination from "@/components/MkPagination.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkAvatars from "@/components/MkAvatars.vue";
@@ -65,7 +64,7 @@ async function create() {
 		title: i18n.ts.enterListName,
 	});
 	if (canceled) return;
-	await os.apiWithDialog("users/lists/create", { name: name });
+	await os.apiWithDialog("users/lists/create", { name });
 	pagingComponent.value.reload();
 }
 
diff --git a/packages/client/src/pages/my-lists/list.vue b/packages/client/src/pages/my-lists/list.vue
index 850e363dfb..40895e5a03 100644
--- a/packages/client/src/pages/my-lists/list.vue
+++ b/packages/client/src/pages/my-lists/list.vue
@@ -49,8 +49,8 @@
 									<div class="action">
 										<button
 											class="_button"
-											@click="removeUser(user)"
 											:aria-label="i18n.t('removeMember')"
+											@click="removeUser(user)"
 										>
 											<i class="ph-x ph-bold ph-lg"></i>
 										</button>
@@ -66,7 +66,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
 import { mainRouter } from "@/router";
@@ -77,8 +77,8 @@ const props = defineProps<{
 	listId: string;
 }>();
 
-let list = ref(null);
-let users = ref([]);
+const list = ref(null);
+const users = ref([]);
 
 function fetchList() {
 	os.api("users/lists/show", {
@@ -122,7 +122,7 @@ async function renameList() {
 
 	await os.api("users/lists/update", {
 		listId: list.value.id,
-		name: name,
+		name,
 	});
 
 	list.value.name = name;
diff --git a/packages/client/src/pages/note.vue b/packages/client/src/pages/note.vue
index 005759586c..1eccecf802 100644
--- a/packages/client/src/pages/note.vue
+++ b/packages/client/src/pages/note.vue
@@ -7,7 +7,7 @@
 				:display-back-button="true"
 				:to="`#${noteId}`"
 		/></template>
-		<MkSpacer :content-max="800" :marginMin="6">
+		<MkSpacer :content-max="800" :margin-min="6">
 			<div class="fcuexfpr">
 				<transition
 					:name="$store.state.animation ? 'fade' : ''"
@@ -69,8 +69,8 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineComponent, watch, ref } from "vue";
-import * as misskey from "firefish-js";
+import { computed, ref, watch } from "vue";
+import type * as misskey from "firefish-js";
 import XNoteDetailed from "@/components/MkNoteDetailed.vue";
 import XNotes from "@/components/MkNotes.vue";
 import MkRemoteCaution from "@/components/MkRemoteCaution.vue";
@@ -83,14 +83,14 @@ const props = defineProps<{
 	noteId: string;
 }>();
 
-let note = ref<null | misskey.entities.Note>();
-let hasPrev = ref(false);
-let hasNext = ref(false);
-let showPrev = ref(false);
-let showNext = ref(false);
-let error = ref();
-let isRenote = ref(false);
-let appearNote = ref<null | misskey.entities.Note>();
+const note = ref<null | misskey.entities.Note>();
+const hasPrev = ref(false);
+const hasNext = ref(false);
+const showPrev = ref(false);
+const showNext = ref(false);
+const error = ref();
+const isRenote = ref(false);
+const appearNote = ref<null | misskey.entities.Note>();
 
 const prevPagination = {
 	endpoint: "users/notes" as const,
diff --git a/packages/client/src/pages/notifications.vue b/packages/client/src/pages/notifications.vue
index ed318f4b40..de739f92de 100644
--- a/packages/client/src/pages/notifications.vue
+++ b/packages/client/src/pages/notifications.vue
@@ -13,7 +13,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -66,11 +66,11 @@ import "swiper/scss";
 import "swiper/scss/virtual";
 
 const tabs = ["all", "unread", "mentions", "directNotes"];
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
-let includeTypes = ref<string[] | null>(null);
-let unreadOnly = computed(() => tab.value === "unread");
+const includeTypes = ref<string[] | null>(null);
+const unreadOnly = computed(() => tab.value === "unread");
 os.api("notifications/mark-all-as-read");
 
 const MOBILE_THRESHOLD = 500;
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.image.vue b/packages/client/src/pages/page-editor/els/page-editor.el.image.vue
index 114f111b47..63594311ef 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.image.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.image.vue
@@ -40,7 +40,7 @@ const props = withDefaults(
 	},
 );
 
-let file: any = ref(null);
+const file: any = ref(null);
 
 async function choose() {
 	os.selectDriveFile(false).then((fileResponse: any) => {
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.note.vue b/packages/client/src/pages/page-editor/els/page-editor.el.note.vue
index 6b9a389fb4..cd3e980a4e 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.note.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.note.vue
@@ -35,7 +35,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref } from "vue";
+import { ref, watch } from "vue";
 import XContainer from "../page-editor.container.vue";
 import MkInput from "@/components/form/input.vue";
 import MkSwitch from "@/components/form/switch.vue";
@@ -56,8 +56,8 @@ const props = withDefaults(
 	},
 );
 
-let id: any = ref(props.value.note);
-let note: any = ref(null);
+const id: any = ref(props.value.note);
+const note: any = ref(null);
 
 watch(
 	id.value,
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
index e00e66e65a..5fc0ff1687 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
@@ -33,7 +33,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref } from "vue";
+import { ref, watch } from "vue";
 import XContainer from "../page-editor.container.vue";
 import MkTextarea from "@/components/form/textarea.vue";
 import MkInput from "@/components/form/input.vue";
@@ -52,7 +52,7 @@ const props = withDefaults(
 	},
 );
 
-let values: string = ref(props.value.values.join("\n"));
+const values: string = ref(props.value.values.join("\n"));
 
 watch(
 	values.value,
diff --git a/packages/client/src/pages/page-editor/page-editor.blocks.vue b/packages/client/src/pages/page-editor/page-editor.blocks.vue
index 25e35a4877..9db45aebdb 100644
--- a/packages/client/src/pages/page-editor/page-editor.blocks.vue
+++ b/packages/client/src/pages/page-editor/page-editor.blocks.vue
@@ -8,9 +8,9 @@
 		swap-threshold="0.5"
 	>
 		<component
+			:is="'x-' + element.type"
 			v-for="element in blocks"
 			:key="element"
-			:is="'x-' + element.type"
 			:value="element"
 			:hpml="hpml"
 			@update:value="updateItem"
@@ -20,7 +20,7 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, defineAsyncComponent } from "vue";
+import { defineComponent } from "vue";
 import { VueDraggable } from "vue-draggable-plus";
 import XSection from "./els/page-editor.el.section.vue";
 import XText from "./els/page-editor.el.text.vue";
@@ -37,7 +37,6 @@ import XCounter from "./els/page-editor.el.counter.vue";
 import XRadioButton from "./els/page-editor.el.radio-button.vue";
 import XCanvas from "./els/page-editor.el.canvas.vue";
 import XNote from "./els/page-editor.el.note.vue";
-import * as os from "@/os";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/pages/page-editor/page-editor.vue b/packages/client/src/pages/page-editor/page-editor.vue
index d4e9f379cf..627c1993dd 100644
--- a/packages/client/src/pages/page-editor/page-editor.vue
+++ b/packages/client/src/pages/page-editor/page-editor.vue
@@ -160,8 +160,9 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, computed, provide, watch, ref } from "vue";
+import { computed, provide, ref, watch } from "vue";
 import { v4 as uuid } from "uuid";
+import { VueDraggable } from "vue-draggable-plus";
 import XVariable from "./page-editor.script-block.vue";
 import XBlocks from "./page-editor.blocks.vue";
 import MkTextarea from "@/components/form/textarea.vue";
@@ -173,7 +174,6 @@ import { blockDefs } from "@/scripts/hpml/index";
 import { HpmlTypeChecker } from "@/scripts/hpml/type-checker";
 import { url } from "@/config";
 import { collectPageVars } from "@/scripts/collect-page-vars";
-import { VueDraggable } from "vue-draggable-plus";
 import * as os from "@/os";
 import { selectFile } from "@/scripts/select-file";
 import { mainRouter } from "@/router";
@@ -187,25 +187,25 @@ const props = defineProps<{
 	initUser?: string;
 }>();
 
-let tab = ref("settings");
-let author = ref($i);
-let readonly = ref(false);
-let page = ref(null);
-let pageId = ref(null);
-let currentName = ref(null);
-let title = ref("");
-let summary = ref(null);
-let name = ref(Date.now().toString());
-let eyeCatchingImage = ref(null);
-let eyeCatchingImageId = ref(null);
-let font = ref("sans-serif");
-let content = ref([]);
-let alignCenter = ref(false);
-let isPublic = ref(true);
-let hideTitleWhenPinned = ref(false);
-let variables = ref([]);
-let hpml = ref(null);
-let script = ref("");
+const tab = ref("settings");
+const author = ref($i);
+const readonly = ref(false);
+const page = ref(null);
+const pageId = ref(null);
+const currentName = ref(null);
+const title = ref("");
+const summary = ref(null);
+const name = ref(Date.now().toString());
+const eyeCatchingImage = ref(null);
+const eyeCatchingImageId = ref(null);
+const font = ref("sans-serif");
+const content = ref([]);
+const alignCenter = ref(false);
+const isPublic = ref(true);
+const hideTitleWhenPinned = ref(false);
+const variables = ref([]);
+const hpml = ref(null);
+const script = ref("");
 
 provide("readonly", readonly.value);
 provide("getScriptBlockList", getScriptBlockList);
@@ -545,7 +545,7 @@ definePageMetadata(
 			title = i18n.ts._pages.readPage;
 		}
 		return {
-			title: title,
+			title,
 			icon: "ph-pencil ph-bold ph-lg",
 		};
 	}),
diff --git a/packages/client/src/pages/page.vue b/packages/client/src/pages/page.vue
index b89bed94d6..e33fffa648 100644
--- a/packages/client/src/pages/page.vue
+++ b/packages/client/src/pages/page.vue
@@ -38,8 +38,8 @@
 								<div class="menu-actions">
 									<button
 										v-tooltip="i18n.ts.copyUrl"
-										@click="copyUrl"
 										class="menu _button"
+										@click="copyUrl"
 									>
 										<i
 											class="ph-link-simple ph-bold ph-lg"
@@ -200,7 +200,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import XPage from "@/components/page/page.vue";
 import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
@@ -219,9 +219,9 @@ const props = defineProps<{
 	username: string;
 }>();
 
-let page = ref(null);
-let bgImg = ref(null);
-let error = ref(null);
+const page = ref(null);
+const bgImg = ref(null);
+const error = ref(null);
 const otherPostsPagination = {
 	endpoint: "users/pages" as const,
 	limit: 6,
diff --git a/packages/client/src/pages/pages.vue b/packages/client/src/pages/pages.vue
index 50130bfa79..3308730d06 100644
--- a/packages/client/src/pages/pages.vue
+++ b/packages/client/src/pages/pages.vue
@@ -11,7 +11,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -80,7 +80,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, onMounted, ref } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import MkPagePreview from "@/components/MkPagePreview.vue";
@@ -96,7 +96,7 @@ import "swiper/scss/virtual";
 
 const router = useRouter();
 
-let tab = ref("featured");
+const tab = ref("featured");
 const tabs = ["featured", "liked", "my"];
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
diff --git a/packages/client/src/pages/registry.keys.vue b/packages/client/src/pages/registry.keys.vue
index f4d706ee1a..54fc9fe193 100644
--- a/packages/client/src/pages/registry.keys.vue
+++ b/packages/client/src/pages/registry.keys.vue
@@ -40,7 +40,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import JSON5 from "json5";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
@@ -57,7 +57,7 @@ const props = defineProps<{
 
 const scope = computed(() => props.path.split("/"));
 
-let keys = ref(null);
+const keys = ref(null);
 
 function fetchKeys() {
 	os.api("i/registry/keys-with-type", {
diff --git a/packages/client/src/pages/registry.value.vue b/packages/client/src/pages/registry.value.vue
index c63a73e82d..63377bd052 100644
--- a/packages/client/src/pages/registry.value.vue
+++ b/packages/client/src/pages/registry.value.vue
@@ -54,13 +54,11 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import JSON5 from "json5";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
-import FormLink from "@/components/form/link.vue";
-import FormSection from "@/components/form/section.vue";
 import MkButton from "@/components/MkButton.vue";
 import MkKeyValue from "@/components/MkKeyValue.vue";
 import FormTextarea from "@/components/form/textarea.vue";
@@ -74,8 +72,8 @@ const props = defineProps<{
 const scope = computed(() => props.path.split("/").slice(0, -1));
 const key = computed(() => props.path.split("/").at(-1));
 
-let value = ref(null);
-let valueForEditor = ref(null);
+const value = ref(null);
+const valueForEditor = ref(null);
 
 function fetchValue() {
 	os.api("i/registry/get-detail", {
diff --git a/packages/client/src/pages/registry.vue b/packages/client/src/pages/registry.vue
index 1da5a56a7e..d613fe3150 100644
--- a/packages/client/src/pages/registry.vue
+++ b/packages/client/src/pages/registry.vue
@@ -24,7 +24,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref } from "vue";
 import JSON5 from "json5";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
@@ -33,7 +33,7 @@ import FormLink from "@/components/form/link.vue";
 import FormSection from "@/components/form/section.vue";
 import MkButton from "@/components/MkButton.vue";
 
-let scopes = ref(null);
+const scopes = ref(null);
 
 function fetchScopes() {
 	os.api("i/registry/scopes").then((res) => {
diff --git a/packages/client/src/pages/reset-password.vue b/packages/client/src/pages/reset-password.vue
index 4c8de5cd70..d1c1f9ed24 100644
--- a/packages/client/src/pages/reset-password.vue
+++ b/packages/client/src/pages/reset-password.vue
@@ -30,7 +30,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, onMounted, ref, computed } from "vue";
+import { computed, defineAsyncComponent, onMounted, ref } from "vue";
 import FormInput from "@/components/form/input.vue";
 import FormButton from "@/components/MkButton.vue";
 import * as os from "@/os";
@@ -42,7 +42,7 @@ const props = defineProps<{
 	token?: string;
 }>();
 
-let password = ref("");
+const password = ref("");
 
 async function save() {
 	await os.apiWithDialog("reset-password", {
diff --git a/packages/client/src/pages/scratchpad.vue b/packages/client/src/pages/scratchpad.vue
index 91a43f1501..c3e9757dea 100644
--- a/packages/client/src/pages/scratchpad.vue
+++ b/packages/client/src/pages/scratchpad.vue
@@ -37,7 +37,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import "prismjs";
 import { highlight, languages } from "prismjs/components/prism-core";
 import "prismjs/components/prism-clike";
diff --git a/packages/client/src/pages/search.vue b/packages/client/src/pages/search.vue
index de78c5f7cb..161d0e6dc1 100644
--- a/packages/client/src/pages/search.vue
+++ b/packages/client/src/pages/search.vue
@@ -12,7 +12,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="30"
 				:virtual="true"
@@ -40,7 +40,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, onMounted, ref } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import XNotes from "@/components/MkNotes.vue";
@@ -76,7 +76,7 @@ const usersPagination = {
 };
 
 const tabs = ["notes", "users"];
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
 const headerActions = computed(() => []);
diff --git a/packages/client/src/pages/settings/2fa.vue b/packages/client/src/pages/settings/2fa.vue
index ae57809960..bd788177da 100644
--- a/packages/client/src/pages/settings/2fa.vue
+++ b/packages/client/src/pages/settings/2fa.vue
@@ -103,7 +103,7 @@
 				:disabled="
 					!$i.twoFactorEnabled || $i.securityKeysList.length === 0
 				"
-				:modelValue="usePasswordLessLogin"
+				:model-value="usePasswordLessLogin"
 				@update:modelValue="(v) => updatePasswordLessLogin(v)"
 			>
 				<template #label>{{ i18n.ts.passwordLessLogin }}</template>
@@ -116,7 +116,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, defineAsyncComponent, computed } from "vue";
+import { computed, defineAsyncComponent, ref } from "vue";
 import { hostname } from "@/config";
 import { byteify, hexify, stringify } from "@/scripts/2fa";
 import MkButton from "@/components/MkButton.vue";
@@ -196,7 +196,7 @@ function unregisterTOTP() {
 	}).then(({ canceled, result: password }) => {
 		if (canceled) return;
 		os.apiWithDialog("i/2fa/unregister", {
-			password: password,
+			password,
 		}).catch((error) => {
 			os.alert({
 				type: "error",
diff --git a/packages/client/src/pages/settings/account-info.vue b/packages/client/src/pages/settings/account-info.vue
index d4c61b0d27..00ea980d72 100644
--- a/packages/client/src/pages/settings/account-info.vue
+++ b/packages/client/src/pages/settings/account-info.vue
@@ -173,7 +173,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, ref, computed } from "vue";
+import { computed, onMounted, ref } from "vue";
 import FormSection from "@/components/form/section.vue";
 import MkKeyValue from "@/components/MkKeyValue.vue";
 import * as os from "@/os";
diff --git a/packages/client/src/pages/settings/accounts.vue b/packages/client/src/pages/settings/accounts.vue
index 83c3866b41..9a9c78b5f2 100644
--- a/packages/client/src/pages/settings/accounts.vue
+++ b/packages/client/src/pages/settings/accounts.vue
@@ -13,7 +13,7 @@
 				@click="menu(account, $event)"
 			>
 				<div class="avatar">
-					<MkAvatar :user="account" class="avatar" disableLink />
+					<MkAvatar :user="account" class="avatar" disable-link />
 				</div>
 				<div class="body">
 					<div class="name">
@@ -29,16 +29,16 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, ref, computed } from "vue";
+import { computed, defineAsyncComponent, ref } from "vue";
 import FormSuspense from "@/components/form/suspense.vue";
 import FormButton from "@/components/MkButton.vue";
 import * as os from "@/os";
 import {
-	getAccounts,
-	addAccount as addAccounts,
-	removeAccount as _removeAccount,
-	login,
 	$i,
+	removeAccount as _removeAccount,
+	addAccount as addAccounts,
+	getAccounts,
+	login,
 } from "@/account";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
diff --git a/packages/client/src/pages/settings/api.vue b/packages/client/src/pages/settings/api.vue
index fb85acf0ca..4e1e5bfbb0 100644
--- a/packages/client/src/pages/settings/api.vue
+++ b/packages/client/src/pages/settings/api.vue
@@ -16,7 +16,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, ref, computed } from "vue";
+import { computed, defineAsyncComponent, ref } from "vue";
 import FormLink from "@/components/form/link.vue";
 import FormButton from "@/components/MkButton.vue";
 import * as os from "@/os";
@@ -36,7 +36,7 @@ function generateToken() {
 				const { name, permissions } = result;
 				const { token } = await os.api("miauth/gen-token", {
 					session: null,
-					name: name,
+					name,
 					permission: permissions,
 				});
 
diff --git a/packages/client/src/pages/settings/apps.vue b/packages/client/src/pages/settings/apps.vue
index 687d1dae95..13cfadc9eb 100644
--- a/packages/client/src/pages/settings/apps.vue
+++ b/packages/client/src/pages/settings/apps.vue
@@ -55,7 +55,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 import FormPagination from "@/components/MkPagination.vue";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/pages/settings/custom-css.vue b/packages/client/src/pages/settings/custom-css.vue
index d6fd68ad26..dea1ceadd2 100644
--- a/packages/client/src/pages/settings/custom-css.vue
+++ b/packages/client/src/pages/settings/custom-css.vue
@@ -15,7 +15,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import FormTextarea from "@/components/form/textarea.vue";
 import FormInfo from "@/components/MkInfo.vue";
 import * as os from "@/os";
diff --git a/packages/client/src/pages/settings/custom-katex-macro.vue b/packages/client/src/pages/settings/custom-katex-macro.vue
index 24869b1bc6..ac6ab93bf5 100644
--- a/packages/client/src/pages/settings/custom-katex-macro.vue
+++ b/packages/client/src/pages/settings/custom-katex-macro.vue
@@ -21,7 +21,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import FormTextarea from "@/components/form/textarea.vue";
 import FormInfo from "@/components/MkInfo.vue";
 import FormSwitch from "@/components/form/switch.vue";
diff --git a/packages/client/src/pages/settings/deck.vue b/packages/client/src/pages/settings/deck.vue
index cb0c5f8e13..dfd4af9236 100644
--- a/packages/client/src/pages/settings/deck.vue
+++ b/packages/client/src/pages/settings/deck.vue
@@ -18,14 +18,10 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch } from "vue";
+import { computed } from "vue";
 import FormSwitch from "@/components/form/switch.vue";
-import FormLink from "@/components/form/link.vue";
 import FormRadios from "@/components/form/radios.vue";
-import FormInput from "@/components/form/input.vue";
 import { deckStore } from "@/ui/deck/deck-store";
-import * as os from "@/os";
-import { unisonReload } from "@/scripts/unison-reload";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
diff --git a/packages/client/src/pages/settings/delete-account.vue b/packages/client/src/pages/settings/delete-account.vue
index ba604dfc84..f802d48ea3 100644
--- a/packages/client/src/pages/settings/delete-account.vue
+++ b/packages/client/src/pages/settings/delete-account.vue
@@ -45,7 +45,7 @@ async function deleteAccount() {
 	if (canceled) return;
 
 	await os.apiWithDialog("i/delete-account", {
-		password: password,
+		password,
 	});
 
 	await os.alert({
diff --git a/packages/client/src/pages/settings/drive.vue b/packages/client/src/pages/settings/drive.vue
index f8d567dbf5..044ad0a07c 100644
--- a/packages/client/src/pages/settings/drive.vue
+++ b/packages/client/src/pages/settings/drive.vue
@@ -74,7 +74,6 @@
 <script lang="ts" setup>
 import { computed, ref } from "vue";
 import tinycolor from "tinycolor2";
-import FormLink from "@/components/form/link.vue";
 import FormButton from "@/components/MkButton.vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormSection from "@/components/form/section.vue";
@@ -92,8 +91,8 @@ const fetching = ref(true);
 const usage = ref<any>(null);
 const capacity = ref<any>(null);
 const uploadFolder = ref<any>(null);
-let alwaysMarkNsfw = ref($i.alwaysMarkNsfw);
-let autoSensitive = ref($i.autoSensitive);
+const alwaysMarkNsfw = ref($i.alwaysMarkNsfw);
+const autoSensitive = ref($i.autoSensitive);
 
 const meterStyle = computed(() => {
 	return {
diff --git a/packages/client/src/pages/settings/email.vue b/packages/client/src/pages/settings/email.vue
index 4a9480027a..53a3f8058d 100644
--- a/packages/client/src/pages/settings/email.vue
+++ b/packages/client/src/pages/settings/email.vue
@@ -61,7 +61,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, ref, watch, computed } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import FormSection from "@/components/form/section.vue";
 import FormInput from "@/components/form/input.vue";
 import FormSwitch from "@/components/form/switch.vue";
@@ -85,7 +85,7 @@ const saveEmailAddress = () => {
 	}).then(({ canceled, result: password }) => {
 		if (canceled) return;
 		os.apiWithDialog("i/update-email", {
-			password: password,
+			password,
 			email: emailAddress.value,
 		});
 	});
diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue
index fd8df7cdb1..b6508bc3eb 100644
--- a/packages/client/src/pages/settings/general.vue
+++ b/packages/client/src/pages/settings/general.vue
@@ -248,7 +248,7 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, computed, ref, watch } from "vue";
+import { computed, ref, watch } from "vue";
 import { $i } from "@/account";
 import FormSwitch from "@/components/form/switch.vue";
 import FormSelect from "@/components/form/select.vue";
diff --git a/packages/client/src/pages/settings/import-export.vue b/packages/client/src/pages/settings/import-export.vue
index 8b35d5d99a..829688d01f 100644
--- a/packages/client/src/pages/settings/import-export.vue
+++ b/packages/client/src/pages/settings/import-export.vue
@@ -176,7 +176,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 import MkButton from "@/components/MkButton.vue";
 import FormSection from "@/components/form/section.vue";
 import FormFolder from "@/components/form/folder.vue";
diff --git a/packages/client/src/pages/settings/index.vue b/packages/client/src/pages/settings/index.vue
index bf58c74435..84cbc79535 100644
--- a/packages/client/src/pages/settings/index.vue
+++ b/packages/client/src/pages/settings/index.vue
@@ -41,30 +41,17 @@
 </template>
 
 <script setup lang="ts">
-import {
-	computed,
-	defineAsyncComponent,
-	inject,
-	nextTick,
-	onActivated,
-	onMounted,
-	onUnmounted,
-	provide,
-	ref,
-	watch,
-} from "vue";
+import { computed, onActivated, onMounted, onUnmounted, ref, watch } from "vue";
 import { i18n } from "@/i18n";
 import MkInfo from "@/components/MkInfo.vue";
 import MkSuperMenu from "@/components/MkSuperMenu.vue";
-import { scroll } from "@/scripts/scroll";
-import { signout, $i } from "@/account";
+import { $i, signout } from "@/account";
 import { unisonReload } from "@/scripts/unison-reload";
 import { instance } from "@/instance";
 import { useRouter } from "@/router";
 import {
 	definePageMetadata,
 	provideMetadataReceiver,
-	setPageMetadata,
 } from "@/scripts/page-metadata";
 import * as os from "@/os";
 
@@ -79,10 +66,10 @@ const childInfo = ref(null);
 
 const router = useRouter();
 
-let narrow = ref(false);
+const narrow = ref(false);
 const NARROW_THRESHOLD = 600;
 
-let currentPage = computed(() => router.currentRef.value.child);
+const currentPage = computed(() => router.currentRef.value.child);
 
 const ro = new ResizeObserver((entries, observer) => {
 	if (entries.length === 0) return;
diff --git a/packages/client/src/pages/settings/instance-mute.vue b/packages/client/src/pages/settings/instance-mute.vue
index 8a8f376072..6c099c216d 100644
--- a/packages/client/src/pages/settings/instance-mute.vue
+++ b/packages/client/src/pages/settings/instance-mute.vue
@@ -21,7 +21,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import FormTextarea from "@/components/form/textarea.vue";
 import MkInfo from "@/components/MkInfo.vue";
 import MkButton from "@/components/MkButton.vue";
@@ -34,7 +34,7 @@ const instanceMutes = ref($i!.mutedInstances.join("\n"));
 const changed = ref(false);
 
 async function save() {
-	let mutes = instanceMutes.value
+	const mutes = instanceMutes.value
 		.trim()
 		.split("\n")
 		.map((el) => el.trim())
diff --git a/packages/client/src/pages/settings/migration.vue b/packages/client/src/pages/settings/migration.vue
index f747ca29f3..02ef7b37f0 100644
--- a/packages/client/src/pages/settings/migration.vue
+++ b/packages/client/src/pages/settings/migration.vue
@@ -53,6 +53,7 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
+import { toString } from "firefish-js/built/acct";
 import FormSection from "@/components/form/section.vue";
 import FormInput from "@/components/form/input.vue";
 import FormButton from "@/components/MkButton.vue";
@@ -61,10 +62,9 @@ import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 import { $i } from "@/account";
-import { toString } from "firefish-js/built/acct";
 
-let moveToAccount = ref("");
-let accountAlias = ref([""]);
+const moveToAccount = ref("");
+const accountAlias = ref([""]);
 
 await init();
 
diff --git a/packages/client/src/pages/settings/mute-block.vue b/packages/client/src/pages/settings/mute-block.vue
index 08e1a1797e..27f2d1c088 100644
--- a/packages/client/src/pages/settings/mute-block.vue
+++ b/packages/client/src/pages/settings/mute-block.vue
@@ -40,19 +40,17 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import MkPagination from "@/components/MkPagination.vue";
 import MkTab from "@/components/MkTab.vue";
 import FormInfo from "@/components/MkInfo.vue";
 import FormLink from "@/components/form/link.vue";
 import { userPage } from "@/filters/user";
-import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let tab = ref("mute");
+const tab = ref("mute");
 
 const mutingPagination = {
 	endpoint: "mute/list" as const,
diff --git a/packages/client/src/pages/settings/navbar.vue b/packages/client/src/pages/settings/navbar.vue
index 58bf607aad..7ec5b3d574 100644
--- a/packages/client/src/pages/settings/navbar.vue
+++ b/packages/client/src/pages/settings/navbar.vue
@@ -62,6 +62,7 @@
 
 <script lang="ts" setup>
 import { computed, ref, watch } from "vue";
+import { VueDraggable } from "vue-draggable-plus";
 import FormSlot from "@/components/form/slot.vue";
 import FormRadios from "@/components/form/radios.vue";
 import FormButton from "@/components/MkButton.vue";
@@ -71,7 +72,6 @@ import { navbarItemDef } from "@/navbar";
 import { defaultStore } from "@/store";
 import { unisonReload } from "@/scripts/unison-reload";
 import { i18n } from "@/i18n";
-import { VueDraggable } from "vue-draggable-plus";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
 const items = ref(defaultStore.state.menu);
diff --git a/packages/client/src/pages/settings/notifications.vue b/packages/client/src/pages/settings/notifications.vue
index 9f020a3abf..c0635e4995 100644
--- a/packages/client/src/pages/settings/notifications.vue
+++ b/packages/client/src/pages/settings/notifications.vue
@@ -49,10 +49,9 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, shallowRef, computed } from "vue";
+import { computed, defineAsyncComponent, shallowRef } from "vue";
 import { notificationTypes } from "firefish-js";
 import FormButton from "@/components/MkButton.vue";
-import FormLink from "@/components/form/link.vue";
 import FormSection from "@/components/form/section.vue";
 import * as os from "@/os";
 import { $i } from "@/account";
@@ -60,12 +59,12 @@ import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 import MkPushNotificationAllowButton from "@/components/MkPushNotificationAllowButton.vue";
 
-let allowButton =
+const allowButton =
 	shallowRef<InstanceType<typeof MkPushNotificationAllowButton>>();
-let pushRegistrationInServer = computed(
+const pushRegistrationInServer = computed(
 	() => allowButton.value?.pushRegistrationInServer,
 );
-let sendReadMessage = computed(
+const sendReadMessage = computed(
 	() => pushRegistrationInServer.value?.sendReadMessage || false,
 );
 
diff --git a/packages/client/src/pages/settings/other.vue b/packages/client/src/pages/settings/other.vue
index 60dedadecc..0781771d4d 100644
--- a/packages/client/src/pages/settings/other.vue
+++ b/packages/client/src/pages/settings/other.vue
@@ -29,12 +29,10 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineAsyncComponent } from "vue";
+import { computed } from "vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormLink from "@/components/form/link.vue";
-import MkButton from "@/components/MkButton.vue";
 import * as os from "@/os";
-import { popup } from "@/os";
 import { defaultStore } from "@/store";
 import { $i } from "@/account";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/pages/settings/plugin.install.vue b/packages/client/src/pages/settings/plugin.install.vue
index 00b07a9b3d..92746a0600 100644
--- a/packages/client/src/pages/settings/plugin.install.vue
+++ b/packages/client/src/pages/settings/plugin.install.vue
@@ -18,7 +18,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, nextTick, ref, computed } from "vue";
+import { computed, defineAsyncComponent, nextTick, ref } from "vue";
 import { AiScript, parse } from "@syuilo/aiscript";
 import { serialize } from "@syuilo/aiscript/built/serializer";
 import { v4 as uuid } from "uuid";
@@ -41,8 +41,8 @@ function installPlugin({ id, meta, ast, token }) {
 			id,
 			active: true,
 			configData: {},
-			token: token,
-			ast: ast,
+			token,
+			ast,
 		}),
 	);
 }
@@ -112,7 +112,7 @@ async function install() {
 									"miauth/gen-token",
 									{
 										session: null,
-										name: name,
+										name,
 										permission: permissions,
 									},
 								);
diff --git a/packages/client/src/pages/settings/plugin.vue b/packages/client/src/pages/settings/plugin.vue
index 06f1938648..bce5f1ffc1 100644
--- a/packages/client/src/pages/settings/plugin.vue
+++ b/packages/client/src/pages/settings/plugin.vue
@@ -60,7 +60,7 @@
 </template>
 
 <script lang="ts" setup>
-import { nextTick, ref, computed } from "vue";
+import { computed, nextTick, ref } from "vue";
 import FormLink from "@/components/form/link.vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormSection from "@/components/form/section.vue";
diff --git a/packages/client/src/pages/settings/preferences-backups.vue b/packages/client/src/pages/settings/preferences-backups.vue
index bb37e9aa5f..3452a96e61 100644
--- a/packages/client/src/pages/settings/preferences-backups.vue
+++ b/packages/client/src/pages/settings/preferences-backups.vue
@@ -56,7 +56,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, onMounted, onUnmounted, useCssModule, ref } from "vue";
+import { computed, onMounted, onUnmounted, ref, useCssModule } from "vue";
 import { v4 as uuid } from "uuid";
 import FormSection from "@/components/form/section.vue";
 import MkButton from "@/components/MkButton.vue";
@@ -67,7 +67,7 @@ import { unisonReload } from "@/scripts/unison-reload";
 import { stream } from "@/stream";
 import { $i } from "@/account";
 import { i18n } from "@/i18n";
-import { version, host } from "@/config";
+import { host, version } from "@/config";
 import { definePageMetadata } from "@/scripts/page-metadata";
 const { t, ts } = i18n;
 
@@ -144,7 +144,7 @@ const profileProps = [
 	"settings",
 ];
 
-type Profile = {
+interface Profile {
 	name: string;
 	createdAt: string;
 	updatedAt: string | null;
@@ -157,11 +157,11 @@ type Profile = {
 		useSystemFont: "t" | null;
 		wallpaper: string | null;
 	};
-};
+}
 
 const connection = $i && stream.useChannel("main");
 
-let profiles = ref<Record<string, Profile> | null>(null);
+const profiles = ref<Record<string, Profile> | null>(null);
 
 os.api("i/registry/get-all", { scope }).then((res) => {
 	profiles.value = res || {};
@@ -195,7 +195,7 @@ function validate(profile: unknown): void {
 		throw new Error("createdAt is falsy or not Date");
 	if (profile.updatedAt) {
 		if (Number.isNaN(new Date(profile.updatedAt).getTime())) {
-			throw new Error("updatedAt is not Date");
+			throw new TypeError("updatedAt is not Date");
 		}
 	} else if (profile.updatedAt !== null) {
 		throw new Error("updatedAt is not null");
diff --git a/packages/client/src/pages/settings/privacy.vue b/packages/client/src/pages/settings/privacy.vue
index 0d13923559..d70e25e1c2 100644
--- a/packages/client/src/pages/settings/privacy.vue
+++ b/packages/client/src/pages/settings/privacy.vue
@@ -140,9 +140,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import FormSwitch from "@/components/form/switch.vue";
 import FormSelect from "@/components/form/select.vue";
 import FormSection from "@/components/form/section.vue";
@@ -153,26 +152,26 @@ import { i18n } from "@/i18n";
 import { $i } from "@/account";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let isLocked = ref($i.isLocked);
-let autoAcceptFollowed = ref($i.autoAcceptFollowed);
-let noCrawle = ref($i.noCrawle);
-let isExplorable = ref($i.isExplorable);
-let hideOnlineStatus = ref($i.hideOnlineStatus);
-let publicReactions = ref($i.publicReactions);
-let ffVisibility = ref($i.ffVisibility);
-let preventAiLearning = ref($i.preventAiLearning);
+const isLocked = ref($i.isLocked);
+const autoAcceptFollowed = ref($i.autoAcceptFollowed);
+const noCrawle = ref($i.noCrawle);
+const isExplorable = ref($i.isExplorable);
+const hideOnlineStatus = ref($i.hideOnlineStatus);
+const publicReactions = ref($i.publicReactions);
+const ffVisibility = ref($i.ffVisibility);
+const preventAiLearning = ref($i.preventAiLearning);
 
-let defaultNoteVisibility = computed(
+const defaultNoteVisibility = computed(
 	defaultStore.makeGetterSetter("defaultNoteVisibility"),
 );
-let defaultNoteLocalOnly = computed(
+const defaultNoteLocalOnly = computed(
 	defaultStore.makeGetterSetter("defaultNoteLocalOnly"),
 );
-let rememberNoteVisibility = computed(
+const rememberNoteVisibility = computed(
 	defaultStore.makeGetterSetter("rememberNoteVisibility"),
 );
-let keepCw = computed(defaultStore.makeGetterSetter("keepCw"));
-let addRe = computed(defaultStore.makeGetterSetter("addRe"));
+const keepCw = computed(defaultStore.makeGetterSetter("keepCw"));
+const addRe = computed(defaultStore.makeGetterSetter("addRe"));
 
 function save() {
 	os.api("i/update", {
diff --git a/packages/client/src/pages/settings/profile.vue b/packages/client/src/pages/settings/profile.vue
index a5c299f4da..34c7a7410d 100644
--- a/packages/client/src/pages/settings/profile.vue
+++ b/packages/client/src/pages/settings/profile.vue
@@ -162,7 +162,7 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, watch, ref, computed } from "vue";
+import { computed, reactive, ref, watch } from "vue";
 import MkButton from "@/components/MkButton.vue";
 import FormInput from "@/components/form/input.vue";
 import FormTextarea from "@/components/form/textarea.vue";
@@ -197,7 +197,7 @@ const props = withDefaults(
 	{},
 );
 
-let saveButton = ref(props.saveButton ?? false);
+const saveButton = ref(props.saveButton ?? false);
 
 watch(
 	() => profile,
diff --git a/packages/client/src/pages/settings/reaction.vue b/packages/client/src/pages/settings/reaction.vue
index 9dfe619eec..868cc07d19 100644
--- a/packages/client/src/pages/settings/reaction.vue
+++ b/packages/client/src/pages/settings/reaction.vue
@@ -15,8 +15,8 @@
 						class="zoaiodol"
 						animation="150"
 						delay="100"
-						@end="save"
 						delay-on-touch-only="true"
+						@end="save"
 					>
 						<div
 							v-for="item in reactions"
@@ -121,7 +121,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, watch, ref, computed } from "vue";
+import { computed, defineAsyncComponent, ref, watch } from "vue";
 import { VueDraggable } from "vue-draggable-plus";
 import FormRadios from "@/components/form/radios.vue";
 import FromSlot from "@/components/form/slot.vue";
@@ -146,7 +146,7 @@ async function reloadAsk() {
 	unisonReload();
 }
 
-let reactions = ref(deepClone(defaultStore.state.reactions));
+const reactions = ref(deepClone(defaultStore.state.reactions));
 
 const reactionPickerSkinTone = computed(
 	defaultStore.makeGetterSetter("reactionPickerSkinTone"),
diff --git a/packages/client/src/pages/settings/security.vue b/packages/client/src/pages/settings/security.vue
index d62a44f44f..1a36c98b3f 100644
--- a/packages/client/src/pages/settings/security.vue
+++ b/packages/client/src/pages/settings/security.vue
@@ -114,7 +114,7 @@ function regenerateToken() {
 	}).then(({ canceled, result: password }) => {
 		if (canceled) return;
 		os.api("i/regenerate-token", {
-			password: password,
+			password,
 		});
 	});
 }
diff --git a/packages/client/src/pages/settings/statusbar.statusbar.vue b/packages/client/src/pages/settings/statusbar.statusbar.vue
index b070c0c7de..24bc7e8859 100644
--- a/packages/client/src/pages/settings/statusbar.statusbar.vue
+++ b/packages/client/src/pages/settings/statusbar.statusbar.vue
@@ -142,14 +142,13 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, reactive, ref, watch } from "vue";
+import { reactive, watch } from "vue";
 import FormSelect from "@/components/form/select.vue";
 import MkInput from "@/components/form/input.vue";
 import MkSwitch from "@/components/form/switch.vue";
 import FormRadios from "@/components/form/radios.vue";
 import FormButton from "@/components/MkButton.vue";
 import FormRange from "@/components/form/range.vue";
-import * as os from "@/os";
 import { defaultStore } from "@/store";
 import { i18n } from "@/i18n";
 import { deepClone } from "@/scripts/clone";
diff --git a/packages/client/src/pages/settings/statusbar.vue b/packages/client/src/pages/settings/statusbar.vue
index d79d965f1d..c03883e102 100644
--- a/packages/client/src/pages/settings/statusbar.vue
+++ b/packages/client/src/pages/settings/statusbar.vue
@@ -10,21 +10,19 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, onMounted, ref, watch } from "vue";
+import { computed, onMounted, ref } from "vue";
 import { v4 as uuid } from "uuid";
 import XStatusbar from "./statusbar.statusbar.vue";
-import FormRadios from "@/components/form/radios.vue";
 import FormFolder from "@/components/form/folder.vue";
 import FormButton from "@/components/MkButton.vue";
 import * as os from "@/os";
 import { defaultStore } from "@/store";
-import { unisonReload } from "@/scripts/unison-reload";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
 const statusbars = defaultStore.reactiveState.statusbars;
 
-let userLists = ref();
+const userLists = ref();
 
 onMounted(() => {
 	os.api("users/lists/list").then((res) => {
diff --git a/packages/client/src/pages/settings/theme.install.vue b/packages/client/src/pages/settings/theme.install.vue
index 10423faefd..5955d96958 100644
--- a/packages/client/src/pages/settings/theme.install.vue
+++ b/packages/client/src/pages/settings/theme.install.vue
@@ -28,9 +28,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import JSON5 from "json5";
 import FormTextarea from "@/components/form/textarea.vue";
 import FormButton from "@/components/MkButton.vue";
@@ -40,7 +39,7 @@ import { addTheme, getThemes } from "@/theme-store";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let installThemeCode = ref(null);
+const installThemeCode = ref(null);
 
 function parseThemeCode(code: string) {
 	let theme;
diff --git a/packages/client/src/pages/settings/theme.manage.vue b/packages/client/src/pages/settings/theme.manage.vue
index d075ff57c7..db84ab2601 100644
--- a/packages/client/src/pages/settings/theme.manage.vue
+++ b/packages/client/src/pages/settings/theme.manage.vue
@@ -61,7 +61,8 @@ import FormTextarea from "@/components/form/textarea.vue";
 import FormSelect from "@/components/form/select.vue";
 import FormInput from "@/components/form/input.vue";
 import FormButton from "@/components/MkButton.vue";
-import { Theme, getBuiltinThemesRef } from "@/scripts/theme";
+import type { Theme } from "@/scripts/theme";
+import { getBuiltinThemesRef } from "@/scripts/theme";
 import copyToClipboard from "@/scripts/copy-to-clipboard";
 import * as os from "@/os";
 import { getThemes, removeTheme } from "@/theme-store";
diff --git a/packages/client/src/pages/settings/webhook.edit.vue b/packages/client/src/pages/settings/webhook.edit.vue
index 58eadb6b7a..b302c30c87 100644
--- a/packages/client/src/pages/settings/webhook.edit.vue
+++ b/packages/client/src/pages/settings/webhook.edit.vue
@@ -54,9 +54,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import FormInput from "@/components/form/input.vue";
 import FormSection from "@/components/form/section.vue";
 import FormSwitch from "@/components/form/switch.vue";
@@ -73,18 +72,18 @@ const webhook = await os.api("i/webhooks/show", {
 	webhookId: props.webhookId,
 });
 
-let name = ref(webhook.name);
-let url = ref(webhook.url);
-let secret = ref(webhook.secret);
-let active = ref(webhook.active);
+const name = ref(webhook.name);
+const url = ref(webhook.url);
+const secret = ref(webhook.secret);
+const active = ref(webhook.active);
 
-let event_follow = ref(webhook.on.includes("follow"));
-let event_followed = ref(webhook.on.includes("followed"));
-let event_note = ref(webhook.on.includes("note"));
-let event_reply = ref(webhook.on.includes("reply"));
-let event_renote = ref(webhook.on.includes("renote"));
-let event_reaction = ref(webhook.on.includes("reaction"));
-let event_mention = ref(webhook.on.includes("mention"));
+const event_follow = ref(webhook.on.includes("follow"));
+const event_followed = ref(webhook.on.includes("followed"));
+const event_note = ref(webhook.on.includes("note"));
+const event_reply = ref(webhook.on.includes("reply"));
+const event_renote = ref(webhook.on.includes("renote"));
+const event_reaction = ref(webhook.on.includes("reaction"));
+const event_mention = ref(webhook.on.includes("mention"));
 
 async function save(): Promise<void> {
 	const events = [];
diff --git a/packages/client/src/pages/settings/webhook.new.vue b/packages/client/src/pages/settings/webhook.new.vue
index 348923f110..f2650efeea 100644
--- a/packages/client/src/pages/settings/webhook.new.vue
+++ b/packages/client/src/pages/settings/webhook.new.vue
@@ -52,9 +52,8 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
-import {} from "vue";
 import FormInput from "@/components/form/input.vue";
 import FormSection from "@/components/form/section.vue";
 import FormSwitch from "@/components/form/switch.vue";
@@ -63,17 +62,17 @@ import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let name = ref("");
-let url = ref("");
-let secret = ref("");
+const name = ref("");
+const url = ref("");
+const secret = ref("");
 
-let event_follow = ref(true);
-let event_followed = ref(true);
-let event_note = ref(true);
-let event_reply = ref(true);
-let event_renote = ref(true);
-let event_reaction = ref(true);
-let event_mention = ref(true);
+const event_follow = ref(true);
+const event_followed = ref(true);
+const event_note = ref(true);
+const event_reply = ref(true);
+const event_renote = ref(true);
+const event_reaction = ref(true);
+const event_mention = ref(true);
 
 async function create(): Promise<void> {
 	const events = [];
diff --git a/packages/client/src/pages/settings/webhook.vue b/packages/client/src/pages/settings/webhook.vue
index 86a14783e1..f769c22800 100644
--- a/packages/client/src/pages/settings/webhook.vue
+++ b/packages/client/src/pages/settings/webhook.vue
@@ -54,13 +54,9 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import {} from "vue";
 import MkPagination from "@/components/MkPagination.vue";
 import FormSection from "@/components/form/section.vue";
 import FormLink from "@/components/form/link.vue";
-import { userPage } from "@/filters/user";
-import * as os from "@/os";
-import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
 const pagination = {
diff --git a/packages/client/src/pages/settings/word-mute.vue b/packages/client/src/pages/settings/word-mute.vue
index 7429b34914..0d80f77108 100644
--- a/packages/client/src/pages/settings/word-mute.vue
+++ b/packages/client/src/pages/settings/word-mute.vue
@@ -50,7 +50,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import FormTextarea from "@/components/form/textarea.vue";
 import MkKeyValue from "@/components/MkKeyValue.vue";
 import MkButton from "@/components/MkButton.vue";
@@ -95,7 +95,7 @@ watch(hardMutedWords, () => {
 async function save() {
 	const parseMutes = (mutes, tab) => {
 		// split into lines, remove empty lines and unnecessary whitespace
-		let lines = mutes
+		const lines = mutes
 			.trim()
 			.split("\n")
 			.map((line) => line.trim())
diff --git a/packages/client/src/pages/share.vue b/packages/client/src/pages/share.vue
index e764f04765..7d1fd581e9 100644
--- a/packages/client/src/pages/share.vue
+++ b/packages/client/src/pages/share.vue
@@ -30,14 +30,13 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
+import { computed, ref } from "vue";
 
 // SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html
 
-import {} from "vue";
 import { noteVisibilities } from "firefish-js";
 import * as Acct from "firefish-js/built/acct";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import MkButton from "@/components/MkButton.vue";
 import XPostForm from "@/components/MkPostForm.vue";
 import * as os from "@/os";
@@ -49,21 +48,21 @@ const urlParams = new URLSearchParams(window.location.search);
 const localOnlyQuery = urlParams.get("localOnly");
 const visibilityQuery = urlParams.get("visibility");
 
-let state = ref("fetching" as "fetching" | "writing" | "posted");
-let title = ref(urlParams.get("title"));
+const state = ref("fetching" as "fetching" | "writing" | "posted");
+const title = ref(urlParams.get("title"));
 const text = urlParams.get("text");
 const url = urlParams.get("url");
-let initialText = ref(null as string | null);
-let reply = ref(null as Misskey.entities.Note | null);
-let renote = ref(null as Misskey.entities.Note | null);
-let visibility = ref(
+const initialText = ref(null as string | null);
+const reply = ref(null as Misskey.entities.Note | null);
+const renote = ref(null as Misskey.entities.Note | null);
+const visibility = ref(
 	noteVisibilities.includes(visibilityQuery) ? visibilityQuery : null,
 );
-let localOnly = ref(
+const localOnly = ref(
 	localOnlyQuery === "0" ? false : localOnlyQuery === "1" ? true : null,
 );
-let files = ref([] as Misskey.entities.DriveFile[]);
-let visibleUsers = ref([] as Misskey.entities.User[]);
+const files = ref([] as Misskey.entities.DriveFile[]);
+const visibleUsers = ref([] as Misskey.entities.User[]);
 
 async function init() {
 	let noteText = "";
@@ -112,7 +111,7 @@ async function init() {
 	}
 
 	try {
-		//#region Reply
+		// #region Reply
 		const replyId = urlParams.get("replyId");
 		const replyUri = urlParams.get("replyUri");
 		if (replyId) {
@@ -127,9 +126,9 @@ async function init() {
 				reply.value = obj.object;
 			}
 		}
-		//#endregion
+		// #endregion
 
-		//#region Renote
+		// #region Renote
 		const renoteId = urlParams.get("renoteId");
 		const renoteUri = urlParams.get("renoteUri");
 		if (renoteId) {
@@ -144,9 +143,9 @@ async function init() {
 				renote.value = obj.object;
 			}
 		}
-		//#endregion
+		// #endregion
 
-		//#region Drive files
+		// #region Drive files
 		const fileIds = urlParams.get("fileIds");
 		if (fileIds) {
 			await Promise.all(
@@ -162,7 +161,7 @@ async function init() {
 				),
 			);
 		}
-		//#endregion
+		// #endregion
 	} catch (err) {
 		os.alert({
 			type: "error",
diff --git a/packages/client/src/pages/signup-complete.vue b/packages/client/src/pages/signup-complete.vue
index 9e8d03f282..d1cb273c15 100644
--- a/packages/client/src/pages/signup-complete.vue
+++ b/packages/client/src/pages/signup-complete.vue
@@ -5,7 +5,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, computed } from "vue";
+import { computed, onMounted } from "vue";
 import * as os from "@/os";
 import { login } from "@/account";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/pages/tag.vue b/packages/client/src/pages/tag.vue
index b4816b967c..1e285ad857 100644
--- a/packages/client/src/pages/tag.vue
+++ b/packages/client/src/pages/tag.vue
@@ -12,7 +12,7 @@
 				:round-lengths="true"
 				:touch-angle="25"
 				:threshold="10"
-				:centeredSlides="true"
+				:centered-slides="true"
 				:modules="[Virtual]"
 				:space-between="20"
 				:virtual="true"
@@ -40,7 +40,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, onMounted, ref } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import XNotes from "@/components/MkNotes.vue";
@@ -74,7 +74,7 @@ const usersPagination = {
 };
 
 const tabs = ["notes", "users"];
-let tab = ref(tabs[0]);
+const tab = ref(tabs[0]);
 watch(tab, () => syncSlide(tabs.indexOf(tab.value)));
 
 const headerActions = computed(() => []);
diff --git a/packages/client/src/pages/theme-editor.vue b/packages/client/src/pages/theme-editor.vue
index d30c769627..58a95633a6 100644
--- a/packages/client/src/pages/theme-editor.vue
+++ b/packages/client/src/pages/theme-editor.vue
@@ -143,7 +143,7 @@
 </template>
 
 <script lang="ts" setup>
-import { watch, ref, computed } from "vue";
+import { computed, ref, watch } from "vue";
 import { toUnicode } from "punycode/";
 import tinycolor from "tinycolor2";
 import { v4 as uuid } from "uuid";
@@ -154,7 +154,8 @@ import FormTextarea from "@/components/form/textarea.vue";
 import FormFolder from "@/components/form/folder.vue";
 
 import { $i } from "@/account";
-import { Theme, applyTheme } from "@/scripts/theme";
+import type { Theme } from "@/scripts/theme";
+import { applyTheme } from "@/scripts/theme";
 import lightTheme from "@/themes/_light.json5";
 import darkTheme from "@/themes/_dark.json5";
 import { host } from "@/config";
@@ -238,13 +239,13 @@ const fgColors = [
 	},
 ];
 
-let theme = ref<Partial<Theme>>({
+const theme = ref<Partial<Theme>>({
 	base: "light",
 	props: lightTheme.props,
 });
-let description = ref<string | null>(null);
-let themeCode = ref<string | null>(null);
-let changed = ref(false);
+const description = ref<string | null>(null);
+const themeCode = ref<string | null>(null);
+const changed = ref(false);
 
 useLeaveGuard(changed);
 
diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue
index bcf8853600..9606c8c06b 100644
--- a/packages/client/src/pages/timeline.vue
+++ b/packages/client/src/pages/timeline.vue
@@ -30,7 +30,7 @@
 						:round-lengths="true"
 						:touch-angle="25"
 						:threshold="10"
-						:centeredSlides="true"
+						:centered-slides="true"
 						:modules="[Virtual]"
 						:space-between="20"
 						:virtual="true"
@@ -64,7 +64,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, ref, onMounted } from "vue";
+import { computed, onMounted, ref } from "vue";
 import { Virtual } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/vue";
 import XTutorial from "@/components/MkTutorialDialog.vue";
@@ -95,7 +95,7 @@ const keymap = {
 	t: focus,
 };
 
-let timelines = ["home"];
+const timelines = ["home"];
 
 if (isLocalTimelineAvailable) {
 	timelines.push("local");
@@ -219,7 +219,7 @@ const headerActions = computed(() => [
 	title: i18n.ts.jumpToSpecifiedDate,
 	iconOnly: true,
 	handler: timetravel,
-}*/,
+} */,
 ]);
 
 const headerTabs = computed(() => [
diff --git a/packages/client/src/pages/user-info.vue b/packages/client/src/pages/user-info.vue
index fb6c601ba5..04c52083f4 100644
--- a/packages/client/src/pages/user-info.vue
+++ b/packages/client/src/pages/user-info.vue
@@ -206,8 +206,8 @@
 						<FormButton
 							v-if="user.host == null && iAmModerator"
 							inline
-							@click="resetPassword"
 							style="margin-bottom: 0.4rem"
+							@click="resetPassword"
 							><i class="ph-password ph-bold ph-lg"></i>
 							{{ i18n.ts.resetPassword }}</FormButton
 						>
@@ -357,8 +357,8 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, ref } from "vue";
-import * as misskey from "firefish-js";
+import { computed, ref, watch } from "vue";
+import type * as misskey from "firefish-js";
 import MkChart from "@/components/MkChart.vue";
 import MkObjectView from "@/components/MkObjectView.vue";
 import FormTextarea from "@/components/form/textarea.vue";
@@ -367,7 +367,6 @@ import FormLink from "@/components/form/link.vue";
 import FormSection from "@/components/form/section.vue";
 import FormButton from "@/components/MkButton.vue";
 import FormInput from "@/components/form/input.vue";
-import FormSplit from "@/components/form/split.vue";
 import FormFolder from "@/components/form/folder.vue";
 import MkKeyValue from "@/components/MkKeyValue.vue";
 import MkSelect from "@/components/form/select.vue";
@@ -375,10 +374,8 @@ import FormSuspense from "@/components/form/suspense.vue";
 import MkFileListForAdmin from "@/components/MkFileListForAdmin.vue";
 import MkInfo from "@/components/MkInfo.vue";
 import * as os from "@/os";
-import number from "@/filters/number";
-import bytes from "@/filters/bytes";
 import { url } from "@/config";
-import { userPage, acct } from "@/filters/user";
+import { acct, userPage } from "@/filters/user";
 import { definePageMetadata } from "@/scripts/page-metadata";
 import { i18n } from "@/i18n";
 import { iAmAdmin, iAmModerator } from "@/account";
@@ -388,18 +385,18 @@ const props = defineProps<{
 	userId: string;
 }>();
 
-let tab = ref("overview");
-let chartSrc = ref("per-user-notes");
-let user = ref<null | misskey.entities.UserDetailed>();
-let init = ref<ReturnType<typeof createFetcher>>();
-let info = ref();
-let ips = ref(null);
-let ap = ref(null);
-let moderator = ref(false);
-let silenced = ref(false);
-let suspended = ref(false);
-let driveCapacityOverrideMb: number | null = ref(0);
-let moderationNote = ref("");
+const tab = ref("overview");
+const chartSrc = ref("per-user-notes");
+const user = ref<null | misskey.entities.UserDetailed>();
+const init = ref<ReturnType<typeof createFetcher>>();
+const info = ref();
+const ips = ref(null);
+const ap = ref(null);
+const moderator = ref(false);
+const silenced = ref(false);
+const suspended = ref(false);
+const driveCapacityOverrideMb: number | null = ref(0);
+const moderationNote = ref("");
 const filesPagination = {
 	endpoint: "admin/drive/files" as const,
 	limit: 10,
diff --git a/packages/client/src/pages/user-list-timeline.vue b/packages/client/src/pages/user-list-timeline.vue
index 5a31e342a7..e46210d854 100644
--- a/packages/client/src/pages/user-list-timeline.vue
+++ b/packages/client/src/pages/user-list-timeline.vue
@@ -19,7 +19,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, inject, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import XTimeline from "@/components/MkTimeline.vue";
 import * as os from "@/os";
 import { useRouter } from "@/router";
@@ -32,9 +32,9 @@ const props = defineProps<{
 	listId: string;
 }>();
 
-let list = ref(null);
-let tlEl = ref<InstanceType<typeof XTimeline>>();
-let rootEl = ref<HTMLElement>();
+const list = ref(null);
+const tlEl = ref<InstanceType<typeof XTimeline>>();
+const rootEl = ref<HTMLElement>();
 
 watch(
 	() => props.listId,
diff --git a/packages/client/src/pages/user/clips.vue b/packages/client/src/pages/user/clips.vue
index 3195ee57ba..a4bfd34de6 100644
--- a/packages/client/src/pages/user/clips.vue
+++ b/packages/client/src/pages/user/clips.vue
@@ -25,7 +25,7 @@
 
 <script lang="ts" setup>
 import { computed } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkPagination from "@/components/MkPagination.vue";
 
 const props = defineProps<{
diff --git a/packages/client/src/pages/user/follow-list.vue b/packages/client/src/pages/user/follow-list.vue
index 559c85bfd4..07cef1126b 100644
--- a/packages/client/src/pages/user/follow-list.vue
+++ b/packages/client/src/pages/user/follow-list.vue
@@ -24,7 +24,7 @@
 
 <script lang="ts" setup>
 import { computed } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkUserInfo from "@/components/MkUserInfo.vue";
 import MkPagination from "@/components/MkPagination.vue";
 
diff --git a/packages/client/src/pages/user/followers.vue b/packages/client/src/pages/user/followers.vue
index dd6b9eeed2..2dadcd2b0a 100644
--- a/packages/client/src/pages/user/followers.vue
+++ b/packages/client/src/pages/user/followers.vue
@@ -16,9 +16,9 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, computed, inject, onMounted, onUnmounted, watch, ref } from 'vue';
+import { computed, ref, watch } from "vue";
 import * as Acct from "firefish-js/built/acct";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import XFollowList from "./follow-list.vue";
 import * as os from "@/os";
 import { definePageMetadata } from "@/scripts/page-metadata";
@@ -31,8 +31,8 @@ const props = withDefaults(
 	{},
 );
 
-let user = ref<null | misskey.entities.UserDetailed>(null);
-let error = ref(null);
+const user = ref<null | misskey.entities.UserDetailed>(null);
+const error = ref(null);
 
 function fetchUser(): void {
 	if (props.acct == null) return;
diff --git a/packages/client/src/pages/user/following.vue b/packages/client/src/pages/user/following.vue
index 120a72c809..96ac8087e3 100644
--- a/packages/client/src/pages/user/following.vue
+++ b/packages/client/src/pages/user/following.vue
@@ -16,9 +16,9 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, computed, inject, onMounted, onUnmounted, watch, ref } from 'vue';
+import { computed, ref, watch } from "vue";
 import * as Acct from "firefish-js/built/acct";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import XFollowList from "./follow-list.vue";
 import * as os from "@/os";
 import { definePageMetadata } from "@/scripts/page-metadata";
@@ -31,8 +31,8 @@ const props = withDefaults(
 	{},
 );
 
-let user = ref<null | misskey.entities.UserDetailed>(null);
-let error = ref(null);
+const user = ref<null | misskey.entities.UserDetailed>(null);
+const error = ref(null);
 
 function fetchUser(): void {
 	if (props.acct == null) return;
diff --git a/packages/client/src/pages/user/gallery.vue b/packages/client/src/pages/user/gallery.vue
index f7a4b6f368..62381be146 100644
--- a/packages/client/src/pages/user/gallery.vue
+++ b/packages/client/src/pages/user/gallery.vue
@@ -15,7 +15,7 @@
 
 <script lang="ts" setup>
 import { computed } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkGalleryPostPreview from "@/components/MkGalleryPostPreview.vue";
 import MkPagination from "@/components/MkPagination.vue";
 
diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue
index 5aaa886fa8..c0359a3dfe 100644
--- a/packages/client/src/pages/user/home.vue
+++ b/packages/client/src/pages/user/home.vue
@@ -211,11 +211,11 @@
 							<div class="actions">
 								<MkFollowButton
 									:user="user"
-									@refresh="emit('refresh')"
 									:inline="true"
 									:transparent="false"
 									:full="true"
 									class="koudoku"
+									@refresh="emit('refresh')"
 								/>
 							</div>
 						</div>
@@ -280,16 +280,16 @@
 						<div v-if="user.fields.length > 0" class="fields">
 							<dl
 								v-for="(field, i) in user.fields"
-								:class="field.verified ? 'verified' : ''"
 								:key="i"
+								:class="field.verified ? 'verified' : ''"
 								class="field"
 							>
 								<dt class="name">
 									<i
 										v-if="field.verified"
+										v-tooltip="i18n.ts.verifiedLink"
 										class="ph-bold ph-seal-check ph-lg ph-fw"
 										style="padding: 5px"
-										v-tooltip="i18n.ts.verifiedLink"
 									></i>
 									<Mfm
 										:text="field.name"
@@ -380,16 +380,16 @@
 
 <script lang="ts" setup>
 import {
-	ref,
+	computed,
 	defineAsyncComponent,
 	onMounted,
 	onUnmounted,
-	computed,
+	ref,
 } from "vue";
 import calcAge from "s-age";
 import cityTimezones from "city-timezones";
-import XUserTimeline from "./index.timeline.vue";
 import type * as misskey from "firefish-js";
+import XUserTimeline from "./index.timeline.vue";
 import XNote from "@/components/MkNote.vue";
 import MkFollowButton from "@/components/MkFollowButton.vue";
 import MkRemoteCaution from "@/components/MkRemoteCaution.vue";
@@ -416,11 +416,11 @@ const props = withDefaults(
 	{},
 );
 
-let parallaxAnimationId = ref<null | number>(null);
-let narrow = ref<null | boolean>(null);
-let rootEl = ref<null | HTMLElement>(null);
-let bannerEl = ref<null | HTMLElement>(null);
-let patrons = ref([]);
+const parallaxAnimationId = ref<null | number>(null);
+const narrow = ref<null | boolean>(null);
+const rootEl = ref<null | HTMLElement>(null);
+const bannerEl = ref<null | HTMLElement>(null);
+const patrons = ref([]);
 
 const age = computed(() => {
 	return calcAge(props.user.birthday);
@@ -446,8 +446,8 @@ const timeForThem = computed(() => {
 	];
 
 	for (const city of maybeCityNames) {
-		let tzInfo = cityTimezones.lookupViaCity(city);
-		if (tzInfo.length == 0) continue;
+		const tzInfo = cityTimezones.lookupViaCity(city);
+		if (tzInfo.length === 0) continue;
 
 		const tz = tzInfo[0].timezone;
 		if (!tz) continue;
diff --git a/packages/client/src/pages/user/index.activity.vue b/packages/client/src/pages/user/index.activity.vue
index 48af5d82e7..fc68d3db81 100644
--- a/packages/client/src/pages/user/index.activity.vue
+++ b/packages/client/src/pages/user/index.activity.vue
@@ -31,8 +31,7 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkContainer from "@/components/MkContainer.vue";
 import MkChart from "@/components/MkChart.vue";
 import * as os from "@/os";
@@ -48,7 +47,7 @@ const props = withDefaults(
 	},
 );
 
-let chartSrc = ref("per-user-notes");
+const chartSrc = ref("per-user-notes");
 
 function showMenu(ev: MouseEvent) {
 	os.popupMenu(
@@ -69,7 +68,7 @@ function showMenu(ev: MouseEvent) {
 		action: () => {
 			chartSrc = 'per-user-followers';
 		}
-	}*/,
+	} */,
 		],
 		ev.currentTarget ?? ev.target,
 	);
diff --git a/packages/client/src/pages/user/index.photos.vue b/packages/client/src/pages/user/index.photos.vue
index 4f66962c47..e545ba4d78 100644
--- a/packages/client/src/pages/user/index.photos.vue
+++ b/packages/client/src/pages/user/index.photos.vue
@@ -29,7 +29,7 @@
 
 <script lang="ts" setup>
 import { onMounted, ref } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import { getStaticImageUrl } from "@/scripts/get-static-image-url";
 import { notePage } from "@/filters/note";
 import * as os from "@/os";
@@ -42,8 +42,8 @@ const props = defineProps<{
 	user: misskey.entities.UserDetailed;
 }>();
 
-let fetching = ref(true);
-let images = ref<
+const fetching = ref(true);
+const images = ref<
 	{
 		note: misskey.entities.Note;
 		file: misskey.entities.DriveFile;
diff --git a/packages/client/src/pages/user/index.timeline.vue b/packages/client/src/pages/user/index.timeline.vue
index 1fff13f27c..fc4306a09b 100644
--- a/packages/client/src/pages/user/index.timeline.vue
+++ b/packages/client/src/pages/user/index.timeline.vue
@@ -12,11 +12,10 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from "vue";
-import * as misskey from "firefish-js";
+import { computed, ref } from "vue";
+import type * as misskey from "firefish-js";
 import XNotes from "@/components/MkNotes.vue";
 import MkTab from "@/components/MkTab.vue";
-import * as os from "@/os";
 import { i18n } from "@/i18n";
 
 const props = defineProps<{
diff --git a/packages/client/src/pages/user/index.vue b/packages/client/src/pages/user/index.vue
index 3f9a1657c1..586723c0fd 100644
--- a/packages/client/src/pages/user/index.vue
+++ b/packages/client/src/pages/user/index.vue
@@ -29,13 +29,10 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, computed, watch, ref } from "vue";
-import calcAge from "s-age";
+import { computed, defineAsyncComponent, ref, watch } from "vue";
 import * as Acct from "firefish-js/built/acct";
 import type * as misskey from "firefish-js";
-import { getScrollPosition } from "@/scripts/scroll";
-import number from "@/filters/number";
-import { userPage, acct as getAcct } from "@/filters/user";
+import { acct as getAcct } from "@/filters/user";
 import * as os from "@/os";
 import { useRouter } from "@/router";
 import { definePageMetadata } from "@/scripts/page-metadata";
@@ -60,9 +57,9 @@ const props = withDefaults(
 
 const router = useRouter();
 
-let tab = ref(props.page);
-let user = ref<null | misskey.entities.UserDetailed>(null);
-let error = ref(null);
+const tab = ref(props.page);
+const user = ref<null | misskey.entities.UserDetailed>(null);
+const error = ref(null);
 
 function fetchUser(): void {
 	if (props.acct == null) return;
diff --git a/packages/client/src/pages/user/pages.vue b/packages/client/src/pages/user/pages.vue
index c0b8e14f1f..526663a28a 100644
--- a/packages/client/src/pages/user/pages.vue
+++ b/packages/client/src/pages/user/pages.vue
@@ -13,7 +13,7 @@
 
 <script lang="ts" setup>
 import { computed } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkPagePreview from "@/components/MkPagePreview.vue";
 import MkPagination from "@/components/MkPagination.vue";
 
diff --git a/packages/client/src/pages/user/reactions.vue b/packages/client/src/pages/user/reactions.vue
index f000ee179e..3e9f24b0e8 100644
--- a/packages/client/src/pages/user/reactions.vue
+++ b/packages/client/src/pages/user/reactions.vue
@@ -25,7 +25,7 @@
 
 <script lang="ts" setup>
 import { computed } from "vue";
-import * as misskey from "firefish-js";
+import type * as misskey from "firefish-js";
 import MkPagination from "@/components/MkPagination.vue";
 import MkNote from "@/components/MkNote.vue";
 import MkReactionIcon from "@/components/MkReactionIcon.vue";
diff --git a/packages/client/src/pages/verify-email.vue b/packages/client/src/pages/verify-email.vue
index 0b9f256083..f8488f6ca1 100644
--- a/packages/client/src/pages/verify-email.vue
+++ b/packages/client/src/pages/verify-email.vue
@@ -5,7 +5,7 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, computed } from "vue";
+import { computed, onMounted } from "vue";
 import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { definePageMetadata } from "@/scripts/page-metadata";
diff --git a/packages/client/src/pages/welcome.entrance.a.vue b/packages/client/src/pages/welcome.entrance.a.vue
index 0fbfd064b1..325305355d 100644
--- a/packages/client/src/pages/welcome.entrance.a.vue
+++ b/packages/client/src/pages/welcome.entrance.a.vue
@@ -35,8 +35,8 @@
 				<div class="fg">
 					<h1>
 						<img
-							class="logo"
 							v-if="meta.logoImageUrl"
+							class="logo"
 							:src="meta.logoImageUrl"
 							alt="logo"
 						/>
@@ -102,25 +102,21 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
-import { toUnicode } from "punycode/";
 import XTimeline from "./welcome.timeline.vue";
 import MarqueeText from "@/components/MkMarquee.vue";
 import XSigninDialog from "@/components/MkSigninDialog.vue";
 import XSignupDialog from "@/components/MkSignupDialog.vue";
 import MkButton from "@/components/MkButton.vue";
-import XNote from "@/components/MkNote.vue";
 import MkFeaturedPhotos from "@/components/MkFeaturedPhotos.vue";
-import { host, instanceName } from "@/config";
+import { instanceName } from "@/config";
 import * as os from "@/os";
-import number from "@/filters/number";
 import { i18n } from "@/i18n";
 
-let meta = ref();
-let stats = ref();
-let tags = ref();
-let onlineUsersCount = ref();
-let instances = ref();
+const meta = ref();
+const stats = ref();
+const tags = ref();
+const onlineUsersCount = ref();
+const instances = ref();
 
 os.api("meta", { detail: true }).then((_meta) => {
 	meta.value = _meta;
diff --git a/packages/client/src/pages/welcome.entrance.b.vue b/packages/client/src/pages/welcome.entrance.b.vue
index 91880c3e06..30aed2327f 100644
--- a/packages/client/src/pages/welcome.entrance.b.vue
+++ b/packages/client/src/pages/welcome.entrance.b.vue
@@ -70,12 +70,12 @@
 <script lang="ts">
 import { defineComponent } from "vue";
 import { toUnicode } from "punycode/";
+import XTimeline from "./welcome.timeline.vue";
 import XSigninDialog from "@/components/MkSigninDialog.vue";
 import XSignupDialog from "@/components/MkSignupDialog.vue";
 import MkButton from "@/components/MkButton.vue";
 import XNote from "@/components/MkNote.vue";
 import MkFeaturedPhotos from "@/components/MkFeaturedPhotos.vue";
-import XTimeline from "./welcome.timeline.vue";
 import { host, instanceName } from "@/config";
 import * as os from "@/os";
 import number from "@/filters/number";
diff --git a/packages/client/src/pages/welcome.setup.vue b/packages/client/src/pages/welcome.setup.vue
index ce8601c7d1..040558519e 100644
--- a/packages/client/src/pages/welcome.setup.vue
+++ b/packages/client/src/pages/welcome.setup.vue
@@ -44,7 +44,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import MkButton from "@/components/MkButton.vue";
 import MkInput from "@/components/form/input.vue";
 import { host } from "@/config";
@@ -52,9 +51,9 @@ import * as os from "@/os";
 import { login } from "@/account";
 import { i18n } from "@/i18n";
 
-let username = ref("");
-let password = ref("");
-let submitting = ref(false);
+const username = ref("");
+const password = ref("");
+const submitting = ref(false);
 
 function submit() {
 	if (submitting.value) return;
diff --git a/packages/client/src/pages/welcome.timeline.vue b/packages/client/src/pages/welcome.timeline.vue
index 26f5fa4b08..7c541bca3b 100644
--- a/packages/client/src/pages/welcome.timeline.vue
+++ b/packages/client/src/pages/welcome.timeline.vue
@@ -1,12 +1,8 @@
 <template>
 	<div class="civpbkhh">
-		<div
-			ref="scroll"
-			class="scrollbox"
-			v-bind:class="{ scroll: isScrolling }"
-		>
+		<div ref="scroll" class="scrollbox" :class="{ scroll: isScrolling }">
 			<div v-for="note in notes" class="note">
-				<div class="content _panel" v-if="note.cw == null">
+				<div v-if="note.cw == null" class="content _panel">
 					<div class="body">
 						<MkA
 							v-if="note.replyId"
@@ -27,7 +23,7 @@
 						<XMediaList :media-list="note.files" />
 					</div>
 					<div v-if="note.poll">
-						<XPoll :note="note" :readOnly="true" />
+						<XPoll :note="note" :read-only="true" />
 					</div>
 				</div>
 				<XReactionsViewer ref="reactionsViewer" :note="note" />
diff --git a/packages/client/src/pages/welcome.vue b/packages/client/src/pages/welcome.vue
index 976b6c0376..67e0678689 100644
--- a/packages/client/src/pages/welcome.vue
+++ b/packages/client/src/pages/welcome.vue
@@ -13,7 +13,7 @@ import { instanceName } from "@/config";
 import * as os from "@/os";
 import { definePageMetadata } from "@/scripts/page-metadata";
 
-let meta = ref(null);
+const meta = ref(null);
 
 os.api("meta", { detail: true }).then((res) => {
 	meta.value = res;
diff --git a/packages/client/src/pizzax.ts b/packages/client/src/pizzax.ts
index 1c3817dbad..1155158067 100644
--- a/packages/client/src/pizzax.ts
+++ b/packages/client/src/pizzax.ts
@@ -1,6 +1,7 @@
 // PIZZAX --- A lightweight store
 
-import { onUnmounted, Ref, ref, watch } from "vue";
+import type { Ref } from "vue";
+import { onUnmounted, ref, watch } from "vue";
 import { $i } from "./account";
 import { api } from "./os";
 import { stream } from "./stream";
@@ -27,6 +28,7 @@ export class Storage<T extends StateDef> {
 	public readonly state: {
 		[K in keyof T]: T[K]["default"];
 	};
+
 	public readonly reactiveState: {
 		[K in keyof T]: Ref<T[K]["default"]>;
 	};
@@ -190,8 +192,8 @@ export class Storage<T extends StateDef> {
 				);
 				api("i/registry/set", {
 					scope: ["client", this.key],
-					key: key,
-					value: value,
+					key,
+					value,
 				});
 				break;
 			}
diff --git a/packages/client/src/plugin.ts b/packages/client/src/plugin.ts
index 2e1297a0b6..8e964ab3a2 100644
--- a/packages/client/src/plugin.ts
+++ b/packages/client/src/plugin.ts
@@ -18,7 +18,7 @@ export function install(plugin) {
 
 	const aiscript = new AiScript(
 		createPluginEnv({
-			plugin: plugin,
+			plugin,
 			storageKey: `plugins:${plugin.id}`,
 		}),
 		{
@@ -58,7 +58,7 @@ function createPluginEnv(opts) {
 
 	return {
 		...createAiScriptEnv({ ...opts, token: opts.plugin.token }),
-		//#region Deprecated
+		// #region Deprecated
 		"Mk:register_post_form_action": values.FN_NATIVE(([title, handler]) => {
 			registerPostFormAction({
 				pluginId: opts.plugin.id,
@@ -80,7 +80,7 @@ function createPluginEnv(opts) {
 				handler,
 			});
 		}),
-		//#endregion
+		// #endregion
 		"Plugin:register_post_form_action": values.FN_NATIVE(([title, handler]) => {
 			registerPostFormAction({
 				pluginId: opts.plugin.id,
@@ -103,10 +103,16 @@ function createPluginEnv(opts) {
 			});
 		}),
 		"Plugin:register_note_view_interruptor": values.FN_NATIVE(([handler]) => {
-			registerNoteViewInterruptor({ pluginId: opts.plugin.id, handler });
+			registerNoteViewInterruptor({
+				pluginId: opts.plugin.id,
+				handler,
+			});
 		}),
 		"Plugin:register_note_post_interruptor": values.FN_NATIVE(([handler]) => {
-			registerNotePostInterruptor({ pluginId: opts.plugin.id, handler });
+			registerNotePostInterruptor({
+				pluginId: opts.plugin.id,
+				handler,
+			});
 		}),
 		"Plugin:open_url": values.FN_NATIVE(([url]) => {
 			window.open(url.value, "_blank");
diff --git a/packages/client/src/router.ts b/packages/client/src/router.ts
index 687c11e8c3..c26ce41f1b 100644
--- a/packages/client/src/router.ts
+++ b/packages/client/src/router.ts
@@ -1,10 +1,10 @@
-import { AsyncComponentLoader, defineAsyncComponent, inject } from "vue";
+import type { AsyncComponentLoader } from "vue";
+import { defineAsyncComponent, inject } from "vue";
 import { Router } from "@/nirax";
 import { $i, iAmModerator } from "@/account";
 import MkLoading from "@/pages/_loading_.vue";
 import MkError from "@/pages/_error_.vue";
 import { api } from "@/os";
-import { ui } from "@/config";
 
 function getGuestTimelineStatus() {
 	api("meta", {
@@ -18,7 +18,7 @@ const guestTimeline = getGuestTimelineStatus();
 
 const page = (loader: AsyncComponentLoader<any>) =>
 	defineAsyncComponent({
-		loader: loader,
+		loader,
 		loadingComponent: MkLoading,
 		errorComponent: MkError,
 	});
diff --git a/packages/client/src/scripts/array.ts b/packages/client/src/scripts/array.ts
index bc6f4d4b3f..ef3dfb298e 100644
--- a/packages/client/src/scripts/array.ts
+++ b/packages/client/src/scripts/array.ts
@@ -1,4 +1,4 @@
-import { EndoRelation, Predicate } from "./relation";
+import type { EndoRelation, Predicate } from "./relation";
 
 /**
  * Count the number of elements that satisfy the predicate
diff --git a/packages/client/src/scripts/autocomplete.ts b/packages/client/src/scripts/autocomplete.ts
index 352b9b035a..0d5d16f180 100644
--- a/packages/client/src/scripts/autocomplete.ts
+++ b/packages/client/src/scripts/autocomplete.ts
@@ -1,4 +1,5 @@
-import { nextTick, Ref, ref, defineAsyncComponent } from "vue";
+import type { Ref } from "vue";
+import { defineAsyncComponent, nextTick, ref } from "vue";
 import getCaretCoordinates from "textarea-caret";
 import { toASCII } from "punycode/";
 import { popup } from "@/os";
@@ -10,6 +11,7 @@ export class Autocomplete {
 		q: Ref<string | null>;
 		close: () => void;
 	} | null;
+
 	private textarea: HTMLInputElement | HTMLTextAreaElement;
 	private currentType: string;
 	private textRef: Ref<string>;
@@ -34,11 +36,11 @@ export class Autocomplete {
 		textarea: HTMLInputElement | HTMLTextAreaElement,
 		textRef: Ref<string>,
 	) {
-		//#region BIND
+		// #region BIND
 		this.onInput = this.onInput.bind(this);
 		this.complete = this.complete.bind(this);
 		this.close = this.close.bind(this);
-		//#endregion
+		// #endregion
 
 		this.suggestion = null;
 		this.textarea = textarea;
@@ -141,7 +143,7 @@ export class Autocomplete {
 		this.opening = true;
 		this.currentType = type;
 
-		//#region サジェストを表示すべき位置を計算
+		// #region サジェストを表示すべき位置を計算
 		const caretPosition = getCaretCoordinates(
 			this.textarea,
 			this.textarea.selectionStart,
@@ -151,7 +153,7 @@ export class Autocomplete {
 
 		const x = rect.left + caretPosition.left - this.textarea.scrollLeft;
 		const y = rect.top + caretPosition.top - this.textarea.scrollTop;
-		//#endregion
+		// #endregion
 
 		if (this.suggestion) {
 			this.suggestion.x.value = x;
@@ -169,7 +171,7 @@ export class Autocomplete {
 				{
 					textarea: this.textarea,
 					close: this.close,
-					type: type,
+					type,
 					q: _q,
 					x: _x,
 					y: _y,
diff --git a/packages/client/src/scripts/chart-vline.ts b/packages/client/src/scripts/chart-vline.ts
index 94ba0abd39..abc707d471 100644
--- a/packages/client/src/scripts/chart-vline.ts
+++ b/packages/client/src/scripts/chart-vline.ts
@@ -1,4 +1,4 @@
-import { Plugin } from "chart.js";
+import type { Plugin } from "chart.js";
 
 export const chartVLine = (vLineColor: string) =>
 	({
diff --git a/packages/client/src/scripts/check-word-mute.ts b/packages/client/src/scripts/check-word-mute.ts
index f789d0cd12..50188a83ba 100644
--- a/packages/client/src/scripts/check-word-mute.ts
+++ b/packages/client/src/scripts/check-word-mute.ts
@@ -1,8 +1,8 @@
-export type Muted = {
+export interface Muted {
 	muted: boolean;
 	matched: string[];
 	what?: string; // "note" || "reply" || "renote" || "quote"
-};
+}
 
 const NotMuted = { muted: false, matched: [] };
 
@@ -17,7 +17,7 @@ function checkWordMute(
 
 	if (text === "") return NotMuted;
 
-	let result = { muted: false, matched: [] };
+	const result = { muted: false, matched: [] };
 
 	for (const mutePattern of mutedWords) {
 		if (Array.isArray(mutePattern)) {
@@ -67,14 +67,14 @@ export function getWordSoftMute(
 	}
 
 	if (mutedWords.length > 0) {
-		let noteMuted = checkWordMute(note, mutedWords);
+		const noteMuted = checkWordMute(note, mutedWords);
 		if (noteMuted.muted) {
 			noteMuted.what = "note";
 			return noteMuted;
 		}
 
 		if (note.renote) {
-			let renoteMuted = checkWordMute(note.renote, mutedWords);
+			const renoteMuted = checkWordMute(note.renote, mutedWords);
 			if (renoteMuted.muted) {
 				renoteMuted.what = note.text == null ? "renote" : "quote";
 				return renoteMuted;
@@ -82,7 +82,7 @@ export function getWordSoftMute(
 		}
 
 		if (note.reply) {
-			let replyMuted = checkWordMute(note.reply, mutedWords);
+			const replyMuted = checkWordMute(note.reply, mutedWords);
 			if (replyMuted.muted) {
 				replyMuted.what = "reply";
 				return replyMuted;
diff --git a/packages/client/src/scripts/emojilist.ts b/packages/client/src/scripts/emojilist.ts
index b042c26662..8a2ade12a4 100644
--- a/packages/client/src/scripts/emojilist.ts
+++ b/packages/client/src/scripts/emojilist.ts
@@ -4,13 +4,13 @@ import individualData from "unicode-emoji-json/data-by-emoji.json";
 import keywordSet from "emojilib";
 import { defaultStore } from "@/store";
 
-export type UnicodeEmojiDef = {
+export interface UnicodeEmojiDef {
 	emoji: string;
 	category: typeof unicodeEmojiCategories[number];
 	skin_tone_support: boolean;
 	slug: string;
 	keywords?: string[];
-};
+}
 
 export const unicodeEmojiCategories = [
 	"emotion",
diff --git a/packages/client/src/scripts/extract-mfm.ts b/packages/client/src/scripts/extract-mfm.ts
index c62547cdbc..b02557b341 100644
--- a/packages/client/src/scripts/extract-mfm.ts
+++ b/packages/client/src/scripts/extract-mfm.ts
@@ -14,7 +14,7 @@ const animatedMfm = [
 
 export function extractMfmWithAnimation(nodes: mfm.MfmNode[]): string[] {
 	const mfmNodes = mfm.extract(nodes, (node) => {
-		return node.type === "fn" && animatedMfm.indexOf(node.props.name) > -1;
+		return node.type === "fn" && animatedMfm.includes(node.props.name);
 	});
 	const mfms = mfmNodes.map((x) => x.props.fn);
 
diff --git a/packages/client/src/scripts/format-time-string.ts b/packages/client/src/scripts/format-time-string.ts
index f2f0d70eea..5a840bc78f 100644
--- a/packages/client/src/scripts/format-time-string.ts
+++ b/packages/client/src/scripts/format-time-string.ts
@@ -1,4 +1,4 @@
-const defaultLocaleStringFormats: { [index: string]: string } = {
+const defaultLocaleStringFormats: Record<string, string> = {
 	weekday: "narrow",
 	era: "narrow",
 	year: "numeric",
@@ -28,7 +28,7 @@ function formatLocaleString(date: Date, format: string): string {
 				].includes(kind)
 			) {
 				return date.toLocaleString(window.navigator.language, {
-					[kind]: option ? option : defaultLocaleStringFormats[kind],
+					[kind]: option || defaultLocaleStringFormats[kind],
 				});
 			} else {
 				return match;
diff --git a/packages/client/src/scripts/gen-search-query.ts b/packages/client/src/scripts/gen-search-query.ts
index 2fdd54fc3b..21870e6911 100644
--- a/packages/client/src/scripts/gen-search-query.ts
+++ b/packages/client/src/scripts/gen-search-query.ts
@@ -2,8 +2,7 @@ import * as Acct from "firefish-js/built/acct";
 import { host as localHost } from "@/config";
 
 export async function genSearchQuery(v: any, q: string) {
-	let host: string;
-	let userId: string;
+	let host: string, userId: string;
 	if (q.split(" ").some((x) => x.startsWith("@"))) {
 		for (const at of q
 			.split(" ")
@@ -32,7 +31,7 @@ export async function genSearchQuery(v: any, q: string) {
 			.split(" ")
 			.filter((x) => !(x.startsWith("/") || x.startsWith("@")))
 			.join(" "),
-		host: host,
-		userId: userId,
+		host,
+		userId,
 	};
 }
diff --git a/packages/client/src/scripts/get-note-menu.ts b/packages/client/src/scripts/get-note-menu.ts
index a5565a9ba7..6b3082db77 100644
--- a/packages/client/src/scripts/get-note-menu.ts
+++ b/packages/client/src/scripts/get-note-menu.ts
@@ -1,5 +1,6 @@
-import { defineAsyncComponent, Ref, inject } from "vue";
-import * as misskey from "firefish-js";
+import type { Ref } from "vue";
+import { defineAsyncComponent } from "vue";
+import type * as misskey from "firefish-js";
 import { $i } from "@/account";
 import { i18n } from "@/i18n";
 import { instance } from "@/instance";
@@ -383,7 +384,7 @@ export function getNoteMenu(props: {
 				action: promote
 			}]
 			: []
-		),*/
+		), */
 			null,
 			!isAppearAuthor
 				? {
diff --git a/packages/client/src/scripts/get-note-summary.ts b/packages/client/src/scripts/get-note-summary.ts
index a2bc0a2fd4..5b28f4dda4 100644
--- a/packages/client/src/scripts/get-note-summary.ts
+++ b/packages/client/src/scripts/get-note-summary.ts
@@ -1,5 +1,4 @@
-import * as misskey from "firefish-js";
-import { i18n } from "@/i18n";
+import type * as misskey from "firefish-js";
 
 /**
  * 投稿を表す文字列を取得します。
diff --git a/packages/client/src/scripts/get-user-menu.ts b/packages/client/src/scripts/get-user-menu.ts
index 26112379cc..a11ba3c5e3 100644
--- a/packages/client/src/scripts/get-user-menu.ts
+++ b/packages/client/src/scripts/get-user-menu.ts
@@ -7,7 +7,7 @@ import * as os from "@/os";
 import { userActions } from "@/store";
 import { $i, iAmModerator } from "@/account";
 import { mainRouter } from "@/router";
-import { Router } from "@/nirax";
+import type { Router } from "@/nirax";
 
 export function getUserMenu(user, router: Router = mainRouter) {
 	const meId = $i ? $i.id : null;
@@ -31,7 +31,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
 		});
 		if (canceled) return;
 		os.apiWithDialog("users/lists/push", {
-			listId: listId,
+			listId,
 			userId: user.id,
 		});
 	}
@@ -54,7 +54,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
 		});
 		if (canceled) return;
 		os.apiWithDialog("users/groups/invite", {
-			groupId: groupId,
+			groupId,
 			userId: user.id,
 		});
 	}
@@ -197,7 +197,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
 				() => import("@/components/MkAbuseReportWindow.vue"),
 			),
 			{
-				user: user,
+				user,
 			},
 			{},
 			"closed",
diff --git a/packages/client/src/scripts/helpMenu.ts b/packages/client/src/scripts/helpMenu.ts
index 55848541e5..508053d05d 100644
--- a/packages/client/src/scripts/helpMenu.ts
+++ b/packages/client/src/scripts/helpMenu.ts
@@ -1,8 +1,8 @@
+import XTutorial from "../components/MkTutorialDialog.vue";
 import { defaultStore } from "@/store";
 import { instance } from "@/instance";
 import { host } from "@/config";
 import * as os from "@/os";
-import XTutorial from "../components/MkTutorialDialog.vue";
 import { i18n } from "@/i18n";
 
 export function openHelpMenu_(ev: MouseEvent) {
diff --git a/packages/client/src/scripts/hotkey.ts b/packages/client/src/scripts/hotkey.ts
index 02d41575cc..4aa6f1b009 100644
--- a/packages/client/src/scripts/hotkey.ts
+++ b/packages/client/src/scripts/hotkey.ts
@@ -4,18 +4,18 @@ type Callback = (ev: KeyboardEvent) => void;
 
 type Keymap = Record<string, Callback>;
 
-type Pattern = {
+interface Pattern {
 	which: string[];
 	ctrl?: boolean;
 	shift?: boolean;
 	alt?: boolean;
-};
+}
 
-type Action = {
+interface Action {
 	patterns: Pattern[];
 	callback: Callback;
 	allowRepeat: boolean;
-};
+}
 
 const parseKeymap = (keymap: Keymap) =>
 	Object.entries(keymap).map(([patterns, callback]): Action => {
@@ -85,7 +85,7 @@ export const makeHotkey = (keymap: Keymap) => {
 		if (document.activeElement) {
 			if (ignoreElemens.some((el) => document.activeElement!.matches(el)))
 				return;
-			if (document.activeElement.attributes["contenteditable"]) return;
+			if (document.activeElement.attributes.contenteditable) return;
 		}
 
 		for (const action of actions) {
diff --git a/packages/client/src/scripts/hpml/block.ts b/packages/client/src/scripts/hpml/block.ts
index 1cdb50b889..dd16258f14 100644
--- a/packages/client/src/scripts/hpml/block.ts
+++ b/packages/client/src/scripts/hpml/block.ts
@@ -1,9 +1,9 @@
 // blocks
 
-export type BlockBase = {
+export interface BlockBase {
 	id: string;
 	type: string;
-};
+}
 
 export type TextBlock = BlockBase & {
 	type: "text";
diff --git a/packages/client/src/scripts/hpml/evaluator.ts b/packages/client/src/scripts/hpml/evaluator.ts
index 6bd795c62d..f9a08079a9 100644
--- a/packages/client/src/scripts/hpml/evaluator.ts
+++ b/packages/client/src/scripts/hpml/evaluator.ts
@@ -1,13 +1,16 @@
 import autobind from "autobind-decorator";
-import { PageVar, envVarsDef, Fn, HpmlScope, HpmlError } from ".";
-import { version } from "@/config";
 import { AiScript, utils, values } from "@syuilo/aiscript";
-import { createAiScriptEnv } from "../aiscript/api";
+import type { Ref } from "vue";
+import { markRaw, ref, unref } from "vue";
 import { collectPageVars } from "../collect-page-vars";
-import { initHpmlLib, initAiLib } from "./lib";
+import { createAiScriptEnv } from "../aiscript/api";
+import { initAiLib, initHpmlLib } from "./lib";
+import type { Expr, Variable } from "./expr";
+import { isLiteralValue } from "./expr";
+import { HpmlError, HpmlScope } from ".";
+import type { Fn, PageVar, envVarsDef } from ".";
 import * as os from "@/os";
-import { markRaw, ref, Ref, unref } from "vue";
-import { Expr, isLiteralValue, Variable } from "./expr";
+import { version } from "@/config";
 
 /**
  * Hpml evaluator
@@ -97,7 +100,7 @@ export class Hpml {
 		try {
 			this.vars.value = this.evaluateVars();
 		} catch (err) {
-			//this.onError(e);
+			// this.onError(e);
 		}
 	}
 
diff --git a/packages/client/src/scripts/hpml/expr.ts b/packages/client/src/scripts/hpml/expr.ts
index a39ae4a236..ad235b5c45 100644
--- a/packages/client/src/scripts/hpml/expr.ts
+++ b/packages/client/src/scripts/hpml/expr.ts
@@ -1,8 +1,9 @@
-import { literalDefs, Type } from ".";
+import type { Type } from ".";
+import { literalDefs } from ".";
 
-export type ExprBase = {
+export interface ExprBase {
 	id: string;
-};
+}
 
 // value
 
@@ -45,13 +46,13 @@ export type UserFnValue = ExprBase & {
 	type: "fn";
 	value: UserFnInnerValue;
 };
-type UserFnInnerValue = {
+interface UserFnInnerValue {
 	slots: {
 		name: string;
 		type: Type;
 	}[];
 	expression: Expr;
-};
+}
 
 export type Value =
 	| EmptyValue
diff --git a/packages/client/src/scripts/hpml/index.ts b/packages/client/src/scripts/hpml/index.ts
index 914d714a5c..57fe0e96d3 100644
--- a/packages/client/src/scripts/hpml/index.ts
+++ b/packages/client/src/scripts/hpml/index.ts
@@ -3,13 +3,13 @@
  */
 
 import autobind from "autobind-decorator";
-import { Hpml } from "./evaluator";
+import type { Hpml } from "./evaluator";
 import { funcDefs } from "./lib";
 
-export type Fn = {
+export interface Fn {
 	slots: string[];
 	exec: (args: Record<string, any>) => ReturnType<Hpml["evaluate"]>;
-};
+}
 
 export type Type = "string" | "number" | "boolean" | "stringArray" | null;
 
@@ -39,7 +39,11 @@ export const literalDefs: Record<
 		category: "value",
 		icon: "ph-magic-wand ph-bold ph-lg",
 	},
-	fn: { out: "function", category: "value", icon: "ph-radical ph-bold ph-lg" },
+	fn: {
+		out: "function",
+		category: "value",
+		icon: "ph-radical ph-bold ph-lg",
+	},
 };
 
 export const blockDefs = [
@@ -57,7 +61,11 @@ export const blockDefs = [
 	})),
 ];
 
-export type PageVar = { name: string; value: any; type: Type };
+export interface PageVar {
+	name: string;
+	value: any;
+	type: Type;
+}
 
 export const envVarsDef: Record<string, Type> = {
 	AI: "string",
diff --git a/packages/client/src/scripts/hpml/lib.ts b/packages/client/src/scripts/hpml/lib.ts
index d0f774e36d..4da05b4b0d 100644
--- a/packages/client/src/scripts/hpml/lib.ts
+++ b/packages/client/src/scripts/hpml/lib.ts
@@ -1,9 +1,8 @@
-import tinycolor from "tinycolor2";
-import { Hpml } from "./evaluator";
-import { values, utils } from "@syuilo/aiscript";
-import { Fn, HpmlScope } from ".";
-import { Expr } from "./expr";
+import { utils, values } from "@syuilo/aiscript";
 import seedrandom from "seedrandom";
+import type { Hpml } from "./evaluator";
+import type { Expr } from "./expr";
+import type { Fn, HpmlScope } from ".";
 
 /* TODO: https://www.chartjs.org/docs/latest/configuration/canvas-background.html#color
 // https://stackoverflow.com/questions/38493564/chart-area-background-color-chartjs
diff --git a/packages/client/src/scripts/hpml/type-checker.ts b/packages/client/src/scripts/hpml/type-checker.ts
index eaae600d41..fd9d72052c 100644
--- a/packages/client/src/scripts/hpml/type-checker.ts
+++ b/packages/client/src/scripts/hpml/type-checker.ts
@@ -1,13 +1,15 @@
 import autobind from "autobind-decorator";
-import { Type, envVarsDef, PageVar } from ".";
-import { Expr, isLiteralValue, Variable } from "./expr";
+import type { Expr, Variable } from "./expr";
+import { isLiteralValue } from "./expr";
 import { funcDefs } from "./lib";
+import { envVarsDef } from ".";
+import type { PageVar, Type } from ".";
 
-type TypeError = {
+interface TypeError {
 	arg: number;
 	expect: Type;
 	actual: Type;
-};
+}
 
 /**
  * Hpml type checker
diff --git a/packages/client/src/scripts/i18n.ts b/packages/client/src/scripts/i18n.ts
index 8531b795ae..7e2b237118 100644
--- a/packages/client/src/scripts/i18n.ts
+++ b/packages/client/src/scripts/i18n.ts
@@ -4,9 +4,9 @@ export class I18n<T extends Record<string, any>> {
 	constructor(locale: T) {
 		this.ts = locale;
 
-		//#region BIND
+		// #region BIND
 		this.t = this.t.bind(this);
-		//#endregion
+		// #endregion
 	}
 
 	// string にしているのは、ドット区切りでのパス指定を許可するため
diff --git a/packages/client/src/scripts/idb-proxy.ts b/packages/client/src/scripts/idb-proxy.ts
index a85faa0cfc..618c5c5fb6 100644
--- a/packages/client/src/scripts/idb-proxy.ts
+++ b/packages/client/src/scripts/idb-proxy.ts
@@ -1,6 +1,6 @@
 // FirefoxのプライベートモードなどではindexedDBが使用不可能なので、
 // indexedDBが使えない環境ではlocalStorageを使う
-import { get as iget, set as iset, del as idel } from "idb-keyval";
+import { del as idel, get as iget, set as iset } from "idb-keyval";
 
 const fallbackName = (key: string) => `idbfallback::${key}`;
 
diff --git a/packages/client/src/scripts/init-chart.ts b/packages/client/src/scripts/init-chart.ts
index 32adf73bba..56fd1e35c9 100644
--- a/packages/client/src/scripts/init-chart.ts
+++ b/packages/client/src/scripts/init-chart.ts
@@ -1,20 +1,20 @@
 import {
-	Chart,
 	ArcElement,
-	LineElement,
-	BarElement,
-	PointElement,
 	BarController,
-	LineController,
-	DoughnutController,
+	BarElement,
 	CategoryScale,
-	LinearScale,
-	TimeScale,
+	Chart,
+	DoughnutController,
+	Filler,
 	Legend,
+	LineController,
+	LineElement,
+	LinearScale,
+	PointElement,
+	SubTitle,
+	TimeScale,
 	Title,
 	Tooltip,
-	SubTitle,
-	Filler,
 } from "chart.js";
 import gradient from "chartjs-plugin-gradient";
 import zoomPlugin from "chartjs-plugin-zoom";
diff --git a/packages/client/src/scripts/katex-macro.ts b/packages/client/src/scripts/katex-macro.ts
index f91e657da9..fdf6a0bdc7 100644
--- a/packages/client/src/scripts/katex-macro.ts
+++ b/packages/client/src/scripts/katex-macro.ts
@@ -1,7 +1,7 @@
-type KaTeXMacro = {
+interface KaTeXMacro {
 	args: number;
 	rule: (string | number)[];
-};
+}
 
 function parseSingleKaTeXMacro(src: string): [string, KaTeXMacro] {
 	const invalid: [string, KaTeXMacro] = ["", { args: 0, rule: [] }];
@@ -37,7 +37,7 @@ function parseSingleKaTeXMacro(src: string): [string, KaTeXMacro] {
 
 	currentPos = skipSpaces(closeNameBracketPos + 1);
 
-	let macro: KaTeXMacro = { args: 0, rule: [] };
+	const macro: KaTeXMacro = { args: 0, rule: [] };
 
 	// parse [number of arguments] (optional)
 	if (src[currentPos] === "[") {
@@ -61,8 +61,8 @@ function parseSingleKaTeXMacro(src: string): [string, KaTeXMacro] {
 	currentPos = skipSpaces(currentPos);
 
 	while (currentPos < src.length - 1) {
-		let numbersignPos = -1;
-		let isEscaped = false;
+		let numbersignPos = -1,
+			isEscaped = false;
 
 		for (let i = currentPos; i < src.length - 1; ++i) {
 			if (src[i] !== "\\" && src[i] !== "#") {
@@ -85,9 +85,7 @@ function parseSingleKaTeXMacro(src: string): [string, KaTeXMacro] {
 
 		const argIndexEndPos =
 			src.slice(numbersignPos + 1).search(/[^\d]/) + numbersignPos;
-		const argIndex: number = Number(
-			src.slice(numbersignPos + 1, argIndexEndPos + 1),
-		);
+		const argIndex = Number(src.slice(numbersignPos + 1, argIndexEndPos + 1));
 
 		if (Number.isNaN(argIndex) || argIndex < 1 || macro.args < argIndex)
 			return invalid;
@@ -104,7 +102,7 @@ function parseSingleKaTeXMacro(src: string): [string, KaTeXMacro] {
 }
 
 export function parseKaTeXMacros(src: string): string {
-	let result: { [name: string]: KaTeXMacro } = {};
+	const result: Record<string, KaTeXMacro> = {};
 
 	for (const s of src.split("\n")) {
 		const [name, macro]: [string, KaTeXMacro] = parseSingleKaTeXMacro(s.trim());
@@ -118,16 +116,16 @@ export function parseKaTeXMacros(src: string): string {
 // the boolean value is used for multi-pass expansions (macros can expand to other macros)
 function expandKaTeXMacroOnce(
 	src: string,
-	macros: { [name: string]: KaTeXMacro },
+	macros: Record<string, KaTeXMacro>,
 	maxNumberOfExpansions: number,
 ): [string, boolean, number] {
 	const bracketKinds = 3;
-	const openBracketId: { [bracket: string]: number } = {
+	const openBracketId: Record<string, number> = {
 		"(": 0,
 		"{": 1,
 		"[": 2,
 	};
-	const closeBracketId: { [bracket: string]: number } = {
+	const closeBracketId: Record<string, number> = {
 		")": 0,
 		"}": 1,
 		"]": 2,
@@ -136,14 +134,14 @@ function expandKaTeXMacroOnce(
 	const closeBracketFromId = [")", "}", "]"];
 
 	// mappings from open brackets to their corresponding close brackets
-	type BracketMapping = { [openBracketPos: number]: number };
+	type BracketMapping = Record<number, number>;
 
 	const bracketMapping = ((): BracketMapping => {
-		let result: BracketMapping = {};
+		const result: BracketMapping = {};
 		const n = src.length;
 
-		let depths = new Array<number>(bracketKinds).fill(0); // current bracket depth for "()", "{}", and "[]"
-		let buffer = Array.from(Array<number[]>(bracketKinds), () =>
+		const depths = new Array<number>(bracketKinds).fill(0); // current bracket depth for "()", "{}", and "[]"
+		const buffer = Array.from(Array<number[]>(bracketKinds), () =>
 			Array<number>(n),
 		);
 
@@ -212,17 +210,15 @@ function expandKaTeXMacroOnce(
 		--maxNumberOfExpansions;
 
 		// search for a custom macro
-		let checkedPos = beginPos - 1;
-		let macroName = "";
-		let macroBackslashPos = 0;
-
-		// for macros w/o args: unused
-		//            w/  args: the first open bracket ("(", "{", or "[") after cmd name
-		let macroArgBeginPos = 0;
-
-		// for macros w/o args: the end of cmd name
-		//            w/  args: the closing bracket of the last arg
-		let macroArgEndPos = 0;
+		let checkedPos = beginPos - 1,
+			macroName = "",
+			macroBackslashPos = 0,
+			// for macros w/o args: unused
+			//            w/  args: the first open bracket ("(", "{", or "[") after cmd name
+			macroArgBeginPos = 0,
+			// for macros w/o args: the end of cmd name
+			//            w/  args: the closing bracket of the last arg
+			macroArgEndPos = 0;
 
 		while (checkedPos < endPos) {
 			checkedPos = src.indexOf("\\", checkedPos + 1);
@@ -269,7 +265,7 @@ function expandKaTeXMacroOnce(
 		const numArgs: number = macros[macroName].args;
 		const openBracket: string = macroName.slice(-1);
 
-		let expandedArgs = new Array<string>(numArgs);
+		const expandedArgs = new Array<string>(numArgs);
 
 		for (let i = 0; i < numArgs; ++i) {
 			// find the first open bracket after what we've searched
@@ -308,7 +304,7 @@ export function expandKaTeXMacro(
 
 	let expandMore = true;
 
-	while (expandMore && 0 < maxNumberOfExpansions)
+	while (expandMore && maxNumberOfExpansions > 0)
 		[src, expandMore, maxNumberOfExpansions] = expandKaTeXMacroOnce(
 			src,
 			macros,
diff --git a/packages/client/src/scripts/page-metadata.ts b/packages/client/src/scripts/page-metadata.ts
index 7c86464577..1d7eda8809 100644
--- a/packages/client/src/scripts/page-metadata.ts
+++ b/packages/client/src/scripts/page-metadata.ts
@@ -1,26 +1,18 @@
-import * as misskey from "firefish-js";
-import {
-	ComputedRef,
-	inject,
-	isRef,
-	onActivated,
-	onMounted,
-	provide,
-	ref,
-	Ref,
-} from "vue";
+import type * as misskey from "firefish-js";
+import type { ComputedRef, Ref } from "vue";
+import { inject, isRef, onActivated, onMounted, provide, ref } from "vue";
 
 export const setPageMetadata = Symbol("setPageMetadata");
 export const pageMetadataProvider = Symbol("pageMetadataProvider");
 
-export type PageMetadata = {
+export interface PageMetadata {
 	title: string;
 	subtitle?: string;
 	icon?: string | null;
 	avatar?: misskey.entities.User | null;
 	userName?: misskey.entities.User | null;
 	bg?: string;
-};
+}
 
 export function definePageMetadata(
 	metadata:
diff --git a/packages/client/src/scripts/physics.ts b/packages/client/src/scripts/physics.ts
index cfb8133897..5375c01d29 100644
--- a/packages/client/src/scripts/physics.ts
+++ b/packages/client/src/scripts/physics.ts
@@ -22,8 +22,8 @@ export function physics(container: HTMLElement) {
 
 	// create renderer
 	const render = Matter.Render.create({
-		engine: engine,
-		//element: document.getElementById('debug'),
+		engine,
+		// element: document.getElementById('debug'),
 		options: {
 			width: containerWidth,
 			height: containerHeight,
@@ -52,13 +52,13 @@ export function physics(container: HTMLElement) {
 		},
 	);
 
-	//const wallRight = Matter.Bodies.rectangle(window.innerWidth+50, window.innerHeight/2, 100, window.innerHeight, wallopts);
-	//const wallLeft = Matter.Bodies.rectangle(-50, window.innerHeight/2, 100, window.innerHeight, wallopts);
+	// const wallRight = Matter.Bodies.rectangle(window.innerWidth+50, window.innerHeight/2, 100, window.innerHeight, wallopts);
+	// const wallLeft = Matter.Bodies.rectangle(-50, window.innerHeight/2, 100, window.innerHeight, wallopts);
 
 	Matter.World.add(world, [
 		ground,
-		//wallRight,
-		//wallLeft,
+		// wallRight,
+		// wallLeft,
 	]);
 
 	const objEls = Array.from(container.children);
@@ -89,7 +89,9 @@ export function physics(container: HTMLElement) {
 				objEl.offsetWidth,
 				objEl.offsetHeight,
 				{
-					chamfer: { radius: parseInt(style.borderRadius || "0", 10) },
+					chamfer: {
+						radius: parseInt(style.borderRadius || "0", 10),
+					},
 					restitution: 0.5,
 				},
 			);
@@ -104,7 +106,7 @@ export function physics(container: HTMLElement) {
 
 	const mouse = Matter.Mouse.create(container);
 	const mouseConstraint = Matter.MouseConstraint.create(engine, {
-		mouse: mouse,
+		mouse,
 		constraint: {
 			stiffness: 0.1,
 			render: {
diff --git a/packages/client/src/scripts/popout.ts b/packages/client/src/scripts/popout.ts
index d27428d26a..54aa422257 100644
--- a/packages/client/src/scripts/popout.ts
+++ b/packages/client/src/scripts/popout.ts
@@ -1,5 +1,5 @@
-import * as config from "@/config";
 import { appendQuery } from "./url";
+import * as config from "@/config";
 
 export function popout(path: string, w?: HTMLElement) {
 	let url =
diff --git a/packages/client/src/scripts/popup-position.ts b/packages/client/src/scripts/popup-position.ts
index 874d127b61..45bcd4dbf5 100644
--- a/packages/client/src/scripts/popup-position.ts
+++ b/packages/client/src/scripts/popup-position.ts
@@ -1,5 +1,3 @@
-import { Ref } from "vue";
-
 export function calcPopupPosition(
 	el: HTMLElement,
 	props: {
@@ -22,8 +20,7 @@ export function calcPopupPosition(
 	}
 
 	const calcPosWhenTop = () => {
-		let left: number;
-		let top: number;
+		let left: number, top: number;
 
 		if (props.anchorElement) {
 			left =
@@ -44,8 +41,7 @@ export function calcPopupPosition(
 	};
 
 	const calcPosWhenBottom = () => {
-		let left: number;
-		let top: number;
+		let left: number, top: number;
 
 		if (props.anchorElement) {
 			left =
@@ -70,8 +66,7 @@ export function calcPopupPosition(
 	};
 
 	const calcPosWhenLeft = () => {
-		let left: number;
-		let top: number;
+		let left: number, top: number;
 
 		if (props.anchorElement) {
 			left = rect.left + window.pageXOffset - contentWidth - props.innerMargin;
@@ -92,8 +87,7 @@ export function calcPopupPosition(
 	};
 
 	const calcPosWhenRight = () => {
-		let left: number;
-		let top: number;
+		let left: number, top: number;
 
 		if (props.anchorElement) {
 			left =
diff --git a/packages/client/src/scripts/preprocess.ts b/packages/client/src/scripts/preprocess.ts
index 438a44d30a..bdcb68db9e 100644
--- a/packages/client/src/scripts/preprocess.ts
+++ b/packages/client/src/scripts/preprocess.ts
@@ -8,12 +8,12 @@ export function preprocess(text: string): string {
 			localStorage.getItem("customKaTeXMacroParsed") ?? "{}";
 		const maxNumberOfExpansions = 200; // to prevent infinite expansion loops
 
-		let nodes = mfm.parse(text);
+		const nodes = mfm.parse(text);
 
-		for (let node of nodes) {
-			if (node["type"] === "mathInline" || node["type"] === "mathBlock") {
-				node["props"]["formula"] = expandKaTeXMacro(
-					node["props"]["formula"],
+		for (const node of nodes) {
+			if (node.type === "mathInline" || node.type === "mathBlock") {
+				node.props.formula = expandKaTeXMacro(
+					node.props.formula,
 					parsedKaTeXMacro,
 					maxNumberOfExpansions,
 				);
diff --git a/packages/client/src/scripts/reaction-picker.ts b/packages/client/src/scripts/reaction-picker.ts
index 8baa50278e..353a032d32 100644
--- a/packages/client/src/scripts/reaction-picker.ts
+++ b/packages/client/src/scripts/reaction-picker.ts
@@ -1,4 +1,5 @@
-import { defineAsyncComponent, Ref, ref } from "vue";
+import type { Ref } from "vue";
+import { defineAsyncComponent, ref } from "vue";
 import { popup } from "@/os";
 
 class ReactionPicker {
diff --git a/packages/client/src/scripts/search.ts b/packages/client/src/scripts/search.ts
index ecea1ff2d4..7b75771358 100644
--- a/packages/client/src/scripts/search.ts
+++ b/packages/client/src/scripts/search.ts
@@ -36,7 +36,7 @@ export async function search() {
 		}
 
 		// TODO
-		//v.$root.$emit('warp', date);
+		// v.$root.$emit('warp', date);
 		os.alert({
 			type: "waiting",
 		});
diff --git a/packages/client/src/scripts/select-file.ts b/packages/client/src/scripts/select-file.ts
index 3d5b974227..8366af19f7 100644
--- a/packages/client/src/scripts/select-file.ts
+++ b/packages/client/src/scripts/select-file.ts
@@ -1,5 +1,5 @@
 import { ref } from "vue";
-import { DriveFile } from "firefish-js/built/entities";
+import type { DriveFile } from "firefish-js/built/entities";
 import * as os from "@/os";
 import { stream } from "@/stream";
 import { i18n } from "@/i18n";
@@ -72,7 +72,7 @@ function select(
 				});
 
 				os.api("drive/files/upload-from-url", {
-					url: url,
+					url,
 					folderId: defaultStore.state.uploadFolder,
 					marker,
 				});
diff --git a/packages/client/src/scripts/shuffle.ts b/packages/client/src/scripts/shuffle.ts
index f174152960..f10f1e59dc 100644
--- a/packages/client/src/scripts/shuffle.ts
+++ b/packages/client/src/scripts/shuffle.ts
@@ -2,8 +2,8 @@
  * 配列をシャッフル (破壊的)
  */
 export function shuffle<T extends any[]>(array: T): T {
-	let currentIndex = array.length;
-	let randomIndex;
+	let currentIndex = array.length,
+		randomIndex;
 
 	// While there remain elements to shuffle.
 	while (currentIndex !== 0) {
diff --git a/packages/client/src/scripts/theme-editor.ts b/packages/client/src/scripts/theme-editor.ts
index fc015b6ac2..a010b078fe 100644
--- a/packages/client/src/scripts/theme-editor.ts
+++ b/packages/client/src/scripts/theme-editor.ts
@@ -1,14 +1,29 @@
 import { v4 as uuid } from "uuid";
 
-import { themeProps, Theme } from "./theme";
+import type { Theme } from "./theme";
+import { themeProps } from "./theme";
 
 export type Default = null;
 export type Color = string;
 export type FuncName = "alpha" | "darken" | "lighten";
-export type Func = { type: "func"; name: FuncName; arg: number; value: string };
-export type RefProp = { type: "refProp"; key: string };
-export type RefConst = { type: "refConst"; key: string };
-export type Css = { type: "css"; value: string };
+export interface Func {
+	type: "func";
+	name: FuncName;
+	arg: number;
+	value: string;
+}
+export interface RefProp {
+	type: "refProp";
+	key: string;
+}
+export interface RefConst {
+	type: "refConst";
+	key: string;
+}
+export interface Css {
+	type: "css";
+	value: string;
+}
 
 export type ThemeValue = Color | Func | RefProp | RefConst | Css | Default;
 
@@ -65,7 +80,7 @@ export const convertToMisskeyTheme = (
 	author: string,
 	base: "dark" | "light",
 ): Theme => {
-	const props = {} as { [key: string]: string };
+	const props = {} as Record<string, string>;
 	for (const [key, value] of vm) {
 		if (value === null) continue;
 		props[key] = toThemeString(value);
diff --git a/packages/client/src/scripts/theme.ts b/packages/client/src/scripts/theme.ts
index c52c2c217c..abdabfd17e 100644
--- a/packages/client/src/scripts/theme.ts
+++ b/packages/client/src/scripts/theme.ts
@@ -2,14 +2,14 @@ import { ref } from "vue";
 import tinycolor from "tinycolor2";
 import { globalEvents } from "@/events";
 
-export type Theme = {
+export interface Theme {
 	id: string;
 	name: string;
 	author: string;
 	desc?: string;
 	base?: "dark" | "light";
 	props: Record<string, string>;
-};
+}
 
 import lightTheme from "@/themes/_light.json5";
 import darkTheme from "@/themes/_dark.json5";
@@ -88,7 +88,7 @@ export function applyTheme(theme: Theme, persist = true) {
 
 	for (const tag of document.head.children) {
 		if (tag.tagName === "META" && tag.getAttribute("name") === "theme-color") {
-			tag.setAttribute("content", props["htmlThemeColor"]);
+			tag.setAttribute("content", props.htmlThemeColor);
 			break;
 		}
 	}
diff --git a/packages/client/src/scripts/upload.ts b/packages/client/src/scripts/upload.ts
index e6305de00f..22e1ae48f2 100644
--- a/packages/client/src/scripts/upload.ts
+++ b/packages/client/src/scripts/upload.ts
@@ -1,5 +1,5 @@
 import { reactive, ref } from "vue";
-import * as Misskey from "firefish-js";
+import type * as Misskey from "firefish-js";
 import { readAndCompressImage } from "browser-image-resizer";
 import { defaultStore } from "@/store";
 import { apiUrl } from "@/config";
@@ -7,13 +7,13 @@ import { $i } from "@/account";
 import { alert } from "@/os";
 import { i18n } from "@/i18n";
 
-type Uploading = {
+interface Uploading {
 	id: string;
 	name: string;
 	progressMax: number | undefined;
 	progressValue: number | undefined;
 	img: string;
-};
+}
 export const uploads = ref<Uploading[]>([]);
 
 const compressTypeMap = {
@@ -43,7 +43,7 @@ export function uploadFile(
 		const reader = new FileReader();
 		reader.onload = async (ev) => {
 			const ctx = reactive<Uploading>({
-				id: id,
+				id,
 				name: name || file.name || "untitled",
 				progressMax: undefined,
 				progressValue: undefined,
diff --git a/packages/client/src/scripts/use-chart-tooltip.ts b/packages/client/src/scripts/use-chart-tooltip.ts
index 13ed0e5710..5d50fd41df 100644
--- a/packages/client/src/scripts/use-chart-tooltip.ts
+++ b/packages/client/src/scripts/use-chart-tooltip.ts
@@ -1,4 +1,4 @@
-import { onUnmounted, onDeactivated, ref } from "vue";
+import { onDeactivated, onUnmounted, ref } from "vue";
 import * as os from "@/os";
 import MkChartTooltip from "@/components/MkChartTooltip.vue";
 
diff --git a/packages/client/src/scripts/use-leave-guard.ts b/packages/client/src/scripts/use-leave-guard.ts
index 2a7d677eaa..4893d7926e 100644
--- a/packages/client/src/scripts/use-leave-guard.ts
+++ b/packages/client/src/scripts/use-leave-guard.ts
@@ -1,6 +1,4 @@
-import { inject, onUnmounted, Ref } from "vue";
-import { i18n } from "@/i18n";
-import * as os from "@/os";
+import type { Ref } from "vue";
 
 export function useLeaveGuard(enabled: Ref<boolean>) {
 	/* TODO
diff --git a/packages/client/src/scripts/use-note-capture.ts b/packages/client/src/scripts/use-note-capture.ts
index 1ba85744fc..1cfa79a7c1 100644
--- a/packages/client/src/scripts/use-note-capture.ts
+++ b/packages/client/src/scripts/use-note-capture.ts
@@ -1,5 +1,6 @@
-import { onUnmounted, Ref } from "vue";
-import * as misskey from "firefish-js";
+import type { Ref } from "vue";
+import { onUnmounted } from "vue";
+import type * as misskey from "firefish-js";
 import { stream } from "@/stream";
 import { $i } from "@/account";
 import * as os from "@/os";
diff --git a/packages/client/src/scripts/use-tooltip.ts b/packages/client/src/scripts/use-tooltip.ts
index a5e5ed7a2d..c14d766b6f 100644
--- a/packages/client/src/scripts/use-tooltip.ts
+++ b/packages/client/src/scripts/use-tooltip.ts
@@ -1,20 +1,18 @@
-import { Ref, ref, watch, onUnmounted } from "vue";
+import type { Ref } from "vue";
+import { onUnmounted, ref, watch } from "vue";
 
 export function useTooltip(
 	elRef: Ref<HTMLElement | { $el: HTMLElement } | null | undefined>,
 	onShow: (showing: Ref<boolean>) => void,
 	delay = 300,
 ): void {
-	let isHovering = false;
-
-	// iOS(Androidも?)では、要素をタップした直後に(おせっかいで)mouseoverイベントを発火させたりするため、それを無視するためのフラグ
-	// 無視しないと、画面に触れてないのにツールチップが出たりし、ユーザビリティが損なわれる
-	// TODO: 一度でもタップすると二度とマウスでツールチップ出せなくなるのをどうにかする 定期的にfalseに戻すとか...?
-	let shouldIgnoreMouseover = false;
-
-	let timeoutId: number;
-
-	let changeShowingState: (() => void) | null;
+	let isHovering = false,
+		// iOS(Androidも?)では、要素をタップした直後に(おせっかいで)mouseoverイベントを発火させたりするため、それを無視するためのフラグ
+		// 無視しないと、画面に触れてないのにツールチップが出たりし、ユーザビリティが損なわれる
+		// TODO: 一度でもタップすると二度とマウスでツールチップ出せなくなるのをどうにかする 定期的にfalseに戻すとか...?
+		shouldIgnoreMouseover = false,
+		timeoutId: number,
+		changeShowingState: (() => void) | null;
 
 	const open = () => {
 		close();
@@ -72,9 +70,15 @@ export function useTooltip(
 				stop();
 				const el =
 					elRef.value instanceof Element ? elRef.value : elRef.value.$el;
-				el.addEventListener("mouseover", onMouseover, { passive: true });
-				el.addEventListener("mouseleave", onMouseleave, { passive: true });
-				el.addEventListener("touchstart", onTouchstart, { passive: true });
+				el.addEventListener("mouseover", onMouseover, {
+					passive: true,
+				});
+				el.addEventListener("mouseleave", onMouseleave, {
+					passive: true,
+				});
+				el.addEventListener("touchstart", onTouchstart, {
+					passive: true,
+				});
 				el.addEventListener("touchend", onTouchend, { passive: true });
 				el.addEventListener("click", close, { passive: true });
 			}
diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts
index 694d2dc953..f71dfc4b7c 100644
--- a/packages/client/src/store.ts
+++ b/packages/client/src/store.ts
@@ -1,6 +1,5 @@
 import { markRaw, ref } from "vue";
 import { Storage } from "./pizzax";
-import { Theme } from "./scripts/theme";
 
 export const postFormActions = [];
 export const userActions = [];
@@ -353,14 +352,14 @@ export const defaultStore = markRaw(
 
 const PREFIX = "miux:";
 
-type Plugin = {
+interface Plugin {
 	id: string;
 	name: string;
 	active: boolean;
 	configData: Record<string, any>;
 	token: string;
 	ast: any[];
-};
+}
 
 /**
  * 常にメモリにロードしておく必要がないような設定情報を保管するストレージ(非リアクティブ)
diff --git a/packages/client/src/theme-store.ts b/packages/client/src/theme-store.ts
index a2a5ff5f3e..3dedc045e4 100644
--- a/packages/client/src/theme-store.ts
+++ b/packages/client/src/theme-store.ts
@@ -1,6 +1,6 @@
+import type { Theme } from "./scripts/theme";
 import { api } from "@/os";
 import { $i } from "@/account";
-import { Theme } from "./scripts/theme";
 
 const lsCacheKey = $i ? `themes:${$i.id}` : "";
 
diff --git a/packages/client/src/types/menu.ts b/packages/client/src/types/menu.ts
index 88bf6f33bf..db0d6550ce 100644
--- a/packages/client/src/types/menu.ts
+++ b/packages/client/src/types/menu.ts
@@ -1,16 +1,16 @@
-import * as Misskey from "firefish-js";
-import { Ref } from "vue";
+import type * as Misskey from "firefish-js";
+import type { Ref } from "vue";
 
 export type MenuAction = (ev: MouseEvent) => void;
 
 export type MenuDivider = null;
 export type MenuNull = undefined;
-export type MenuLabel = {
+export interface MenuLabel {
 	type: "label";
 	text: string;
 	textStyle?: string;
-};
-export type MenuLink = {
+}
+export interface MenuLink {
 	type: "link";
 	to: string;
 	text: string;
@@ -18,8 +18,8 @@ export type MenuLink = {
 	icon?: string;
 	indicate?: boolean;
 	avatar?: Misskey.entities.User;
-};
-export type MenuA = {
+}
+export interface MenuA {
 	type: "a";
 	href: string;
 	target?: string;
@@ -28,23 +28,23 @@ export type MenuA = {
 	textStyle?: string;
 	icon?: string;
 	indicate?: boolean;
-};
-export type MenuUser = {
+}
+export interface MenuUser {
 	type: "user";
 	user: Misskey.entities.User;
 	active?: boolean;
 	indicate?: boolean;
 	hidden?: boolean;
 	action: MenuAction;
-};
-export type MenuSwitch = {
+}
+export interface MenuSwitch {
 	type: "switch";
 	ref: Ref<boolean>;
 	text: string;
 	textStyle?: string;
 	disabled?: boolean;
-};
-export type MenuButton = {
+}
+export interface MenuButton {
 	type?: "button";
 	text: string;
 	textStyle?: string;
@@ -56,16 +56,18 @@ export type MenuButton = {
 	hidden?: boolean;
 	avatar?: Misskey.entities.User;
 	action: MenuAction;
-};
-export type MenuParent = {
+}
+export interface MenuParent {
 	type: "parent";
 	text: string;
 	textStyle?: string;
 	icon?: string;
 	children: OuterMenuItem[];
-};
+}
 
-export type MenuPending = { type: "pending" };
+export interface MenuPending {
+	type: "pending";
+}
 
 type OuterMenuItem =
 	| MenuDivider
diff --git a/packages/client/src/ui/_common_/common.vue b/packages/client/src/ui/_common_/common.vue
index e87c3c6d6f..25c205c71e 100644
--- a/packages/client/src/ui/_common_/common.vue
+++ b/packages/client/src/ui/_common_/common.vue
@@ -19,7 +19,7 @@
 <script lang="ts" setup>
 import { defineAsyncComponent } from "vue";
 import { swInject } from "./sw-inject";
-import { popup, popups, pendingApiRequestsCount } from "@/os";
+import { popup, popups } from "@/os";
 import { uploads } from "@/scripts/upload";
 import * as sound from "@/scripts/sound";
 import { $i } from "@/account";
@@ -59,7 +59,7 @@ if ($i) {
 	const connection = stream.useChannel("main", null, "UI");
 	connection.on("notification", onNotification);
 
-	//#region Listen message from SW
+	// #region Listen message from SW
 	if ("serviceWorker" in navigator) {
 		swInject();
 	}
diff --git a/packages/client/src/ui/_common_/navbar-for-mobile.vue b/packages/client/src/ui/_common_/navbar-for-mobile.vue
index 9b616683be..38ef0beb4b 100644
--- a/packages/client/src/ui/_common_/navbar-for-mobile.vue
+++ b/packages/client/src/ui/_common_/navbar-for-mobile.vue
@@ -18,7 +18,7 @@
 					<MkAvatar
 						:user="$i"
 						class="icon"
-						disableLink
+						disable-link
 					/><!-- <MkAcct class="text" :user="$i"/> -->
 				</button>
 			</div>
@@ -124,14 +124,7 @@
 </template>
 
 <script lang="ts" setup>
-import {
-	computed,
-	defineAsyncComponent,
-	defineComponent,
-	ref,
-	toRef,
-	watch,
-} from "vue";
+import { computed, defineAsyncComponent, toRef } from "vue";
 import * as os from "@/os";
 import { navbarItemDef } from "@/navbar";
 import { openAccountMenu as openAccountMenu_ } from "@/account";
diff --git a/packages/client/src/ui/_common_/navbar.vue b/packages/client/src/ui/_common_/navbar.vue
index 0d7102a313..074e7ae975 100644
--- a/packages/client/src/ui/_common_/navbar.vue
+++ b/packages/client/src/ui/_common_/navbar.vue
@@ -18,7 +18,7 @@
 					<MkAvatar
 						:user="$i"
 						class="icon"
-						disableLink
+						disable-link
 					/><!-- <MkAcct class="text" :user="$i"/> -->
 				</button>
 			</div>
@@ -183,15 +183,15 @@ watch(defaultStore.reactiveState.menuDisplay, () => {
 	calcViewState();
 });
 
-let noMaintainerInformation =
+const noMaintainerInformation =
 	isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail);
-let noBotProtection =
+const noBotProtection =
 	!instance.disableRegistration &&
 	!instance.enableHcaptcha &&
 	!instance.enableRecaptcha;
-let noEmailServer = !instance.enableEmail;
-let thereIsUnresolvedAbuseReport = ref(false);
-let updateAvailable = ref(false);
+const noEmailServer = !instance.enableEmail;
+const thereIsUnresolvedAbuseReport = ref(false);
+const updateAvailable = ref(false);
 
 if ($i?.isAdmin) {
 	os.api("admin/abuse-user-reports", {
diff --git a/packages/client/src/ui/_common_/statusbar-federation.vue b/packages/client/src/ui/_common_/statusbar-federation.vue
index e7025eb27b..6700ea3736 100644
--- a/packages/client/src/ui/_common_/statusbar-federation.vue
+++ b/packages/client/src/ui/_common_/statusbar-federation.vue
@@ -39,13 +39,11 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineAsyncComponent, ref, toRef, watch } from "vue";
-import * as misskey from "firefish-js";
+import { ref } from "vue";
+import type * as misskey from "firefish-js";
 import MarqueeText from "@/components/MkMarquee.vue";
 import * as os from "@/os";
 import { useInterval } from "@/scripts/use-interval";
-import { getNoteSummary } from "@/scripts/get-note-summary";
-import { notePage } from "@/filters/note";
 import { getProxiedImageUrlNullable } from "@/scripts/media-proxy";
 
 const props = defineProps<{
@@ -59,7 +57,7 @@ const props = defineProps<{
 
 const instances = ref<misskey.entities.Instance[]>([]);
 const fetching = ref(true);
-let key = ref(0);
+const key = ref(0);
 
 const tick = () => {
 	os.api("federation/instances", {
diff --git a/packages/client/src/ui/_common_/statusbar-rss.vue b/packages/client/src/ui/_common_/statusbar-rss.vue
index 4797794e42..1c38d681eb 100644
--- a/packages/client/src/ui/_common_/statusbar-rss.vue
+++ b/packages/client/src/ui/_common_/statusbar-rss.vue
@@ -27,9 +27,8 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineAsyncComponent, ref, toRef, watch } from "vue";
+import { ref } from "vue";
 import MarqueeText from "@/components/MkMarquee.vue";
-import * as os from "@/os";
 import { useInterval } from "@/scripts/use-interval";
 import { shuffle } from "@/scripts/shuffle";
 
@@ -45,7 +44,7 @@ const props = defineProps<{
 
 const items = ref([]);
 const fetching = ref(true);
-let key = ref(0);
+const key = ref(0);
 
 const tick = () => {
 	fetch(`/api/fetch-rss?url=${props.url}`, {}).then((res) => {
diff --git a/packages/client/src/ui/_common_/statusbar-user-list.vue b/packages/client/src/ui/_common_/statusbar-user-list.vue
index 39e7ebba0e..7b8ae66b1f 100644
--- a/packages/client/src/ui/_common_/statusbar-user-list.vue
+++ b/packages/client/src/ui/_common_/statusbar-user-list.vue
@@ -34,8 +34,8 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineAsyncComponent, ref, toRef, watch } from "vue";
-import * as misskey from "firefish-js";
+import { ref, watch } from "vue";
+import type * as misskey from "firefish-js";
 import MarqueeText from "@/components/MkMarquee.vue";
 import * as os from "@/os";
 import { useInterval } from "@/scripts/use-interval";
@@ -53,7 +53,7 @@ const props = defineProps<{
 
 const notes = ref<misskey.entities.Note[]>([]);
 const fetching = ref(true);
-let key = ref(0);
+const key = ref(0);
 
 const tick = () => {
 	if (props.userListId == null) return;
diff --git a/packages/client/src/ui/_common_/statusbars.vue b/packages/client/src/ui/_common_/statusbars.vue
index 830f9f570b..9e093087fe 100644
--- a/packages/client/src/ui/_common_/statusbars.vue
+++ b/packages/client/src/ui/_common_/statusbars.vue
@@ -49,8 +49,7 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineAsyncComponent, ref, toRef, watch } from "vue";
-import * as os from "@/os";
+import { defineAsyncComponent } from "vue";
 import { defaultStore } from "@/store";
 const XRss = defineAsyncComponent(() => import("./statusbar-rss.vue"));
 const XFederation = defineAsyncComponent(
diff --git a/packages/client/src/ui/_common_/stream-indicator.vue b/packages/client/src/ui/_common_/stream-indicator.vue
index 4898e9ea84..4863471b95 100644
--- a/packages/client/src/ui/_common_/stream-indicator.vue
+++ b/packages/client/src/ui/_common_/stream-indicator.vue
@@ -22,7 +22,7 @@ import { onUnmounted, ref } from "vue";
 import { stream } from "@/stream";
 import { i18n } from "@/i18n";
 
-let hasDisconnected = ref(false);
+const hasDisconnected = ref(false);
 
 function onDisconnected() {
 	hasDisconnected.value = true;
diff --git a/packages/client/src/ui/_common_/sw-inject.ts b/packages/client/src/ui/_common_/sw-inject.ts
index 51087749cc..4f100ae9f2 100644
--- a/packages/client/src/ui/_common_/sw-inject.ts
+++ b/packages/client/src/ui/_common_/sw-inject.ts
@@ -1,7 +1,5 @@
-import { inject } from "vue";
 import { post } from "@/os";
 import { $i, login } from "@/account";
-import { defaultStore } from "@/store";
 import { getAccountFromId } from "@/scripts/get-account-from-id";
 import { mainRouter } from "@/router";
 
@@ -29,7 +27,6 @@ export function swInject() {
 				}
 				return mainRouter.push(ev.data.url);
 			default:
-				return;
 		}
 	});
 }
diff --git a/packages/client/src/ui/deck.vue b/packages/client/src/ui/deck.vue
index 71bb80b013..521967b860 100644
--- a/packages/client/src/ui/deck.vue
+++ b/packages/client/src/ui/deck.vue
@@ -182,14 +182,7 @@
 </template>
 
 <script lang="ts" setup>
-import {
-	computed,
-	defineAsyncComponent,
-	onMounted,
-	provide,
-	ref,
-	watch,
-} from "vue";
+import { computed, defineAsyncComponent, ref, watch } from "vue";
 import { v4 as uuid } from "uuid";
 import XCommon from "./_common_/common.vue";
 import {
@@ -204,7 +197,6 @@ import DeckColumnCore from "@/ui/deck/column-core.vue";
 import XSidebar from "@/ui/_common_/navbar.vue";
 import XDrawerMenu from "@/ui/_common_/navbar-for-mobile.vue";
 import MkButton from "@/components/MkButton.vue";
-import { getScrollContainer } from "@/scripts/scroll";
 import * as os from "@/os";
 import { navbarItemDef } from "@/navbar";
 import { $i } from "@/account";
diff --git a/packages/client/src/ui/deck/channel-column.vue b/packages/client/src/ui/deck/channel-column.vue
index 1c1fdb6683..4860d3af55 100644
--- a/packages/client/src/ui/deck/channel-column.vue
+++ b/packages/client/src/ui/deck/channel-column.vue
@@ -23,7 +23,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import XColumn from "./column.vue";
 import type { Column } from "./deck-store";
 import { updateColumn } from "./deck-store";
diff --git a/packages/client/src/ui/deck/column.vue b/packages/client/src/ui/deck/column.vue
index 3e4d9d937f..fb6084c40d 100644
--- a/packages/client/src/ui/deck/column.vue
+++ b/packages/client/src/ui/deck/column.vue
@@ -56,18 +56,9 @@
 </template>
 
 <script lang="ts" setup>
-import {
-	Ref,
-	onBeforeUnmount,
-	onMounted,
-	provide,
-	watch,
-	ref,
-	computed,
-} from "vue";
+import { computed, onBeforeUnmount, onMounted, provide, ref, watch } from "vue";
 import type { Column } from "./deck-store";
 import {
-	deckStore,
 	popRightColumn,
 	removeColumn,
 	stackLeftColumn,
@@ -109,13 +100,13 @@ const emit = defineEmits<{
 
 const body = ref<HTMLDivElement>();
 
-let dragging = ref(false);
+const dragging = ref(false);
 watch(dragging, (v) =>
 	os.deckGlobalEvents.emit(v ? "column.dragStart" : "column.dragEnd"),
 );
 
-let draghover = ref(false),
-	dropready = ref(false);
+const draghover = ref(false);
+const dropready = ref(false);
 
 const isMainColumn = computed(() => props.column.type === "main");
 const active = computed(() => props.column.active !== false);
diff --git a/packages/client/src/ui/deck/deck-store.ts b/packages/client/src/ui/deck/deck-store.ts
index c65cdbcaf9..cbe6f4f933 100644
--- a/packages/client/src/ui/deck/deck-store.ts
+++ b/packages/client/src/ui/deck/deck-store.ts
@@ -1,18 +1,17 @@
 import { throttle } from "throttle-debounce";
 import { markRaw } from "vue";
-import { notificationTypes } from "firefish-js";
+import type { notificationTypes } from "firefish-js";
 import { Storage } from "../../pizzax";
-import { i18n } from "@/i18n";
 import { api } from "@/os";
 import { deepClone } from "@/scripts/clone";
 
-type ColumnWidget = {
+interface ColumnWidget {
 	name: string;
 	id: string;
 	data: Record<string, any>;
-};
+}
 
-export type Column = {
+export interface Column {
 	id: string;
 	type:
 		| "main"
@@ -34,7 +33,7 @@ export type Column = {
 	listId?: string;
 	includingTypes?: typeof notificationTypes[number][];
 	tl?: "home" | "local" | "social" | "recommended" | "global";
-};
+}
 
 export const deckStore = markRaw(
 	new Storage("deck", {
@@ -113,7 +112,7 @@ export async function getProfiles(): Promise<string[]> {
 export async function deleteProfile(key: string): Promise<any> {
 	return await api("i/registry/remove", {
 		scope: ["client", "deck", "profiles"],
-		key: key,
+		key,
 	});
 }
 
@@ -123,7 +122,10 @@ export async function renameProfile(oldKey: string, newKey: string) {
 	await api("i/registry/set", {
 		scope: ["client", "deck", "profiles"],
 		key: newKey,
-		value: { columns: deckStore.state.columns, layout: deckStore.state.layout },
+		value: {
+			columns: deckStore.state.columns,
+			layout: deckStore.state.layout,
+		},
 	});
 	deckStore.set("profile", newKey);
 	saveDeck();
@@ -153,9 +155,9 @@ export function removeColumn(id: Column["id"]) {
 }
 
 export function swapColumn(a: Column["id"], b: Column["id"]) {
-	const aX = deckStore.state.layout.findIndex((ids) => ids.indexOf(a) !== -1);
+	const aX = deckStore.state.layout.findIndex((ids) => ids.includes(a));
 	const aY = deckStore.state.layout[aX].findIndex((id) => id === a);
-	const bX = deckStore.state.layout.findIndex((ids) => ids.indexOf(b) !== -1);
+	const bX = deckStore.state.layout.findIndex((ids) => ids.includes(b));
 	const bY = deckStore.state.layout[bX].findIndex((id) => id === b);
 	const layout = deepClone(deckStore.state.layout);
 	layout[aX][aY] = b;
diff --git a/packages/client/src/ui/deck/list-column.vue b/packages/client/src/ui/deck/list-column.vue
index e141dc1d1a..2de1ec4cdd 100644
--- a/packages/client/src/ui/deck/list-column.vue
+++ b/packages/client/src/ui/deck/list-column.vue
@@ -23,7 +23,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import XColumn from "./column.vue";
 import type { Column } from "./deck-store";
 import { updateColumn } from "./deck-store";
diff --git a/packages/client/src/ui/deck/main-column.vue b/packages/client/src/ui/deck/main-column.vue
index 9c46cfb96c..7d6f9dfcdb 100644
--- a/packages/client/src/ui/deck/main-column.vue
+++ b/packages/client/src/ui/deck/main-column.vue
@@ -29,10 +29,7 @@ import * as os from "@/os";
 import { i18n } from "@/i18n";
 import { mainRouter } from "@/router";
 import type { PageMetadata } from "@/scripts/page-metadata";
-import {
-	provideMetadataReceiver,
-	setPageMetadata,
-} from "@/scripts/page-metadata";
+import { provideMetadataReceiver } from "@/scripts/page-metadata";
 
 defineProps<{
 	column: Column;
@@ -43,7 +40,7 @@ const emit = defineEmits<{
 	(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
 }>();
 
-let pageMetadata = ref<null | ComputedRef<PageMetadata>>();
+const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
 
 provide("router", mainRouter);
 provideMetadataReceiver((info) => {
diff --git a/packages/client/src/ui/deck/tl-column.vue b/packages/client/src/ui/deck/tl-column.vue
index 19ea907431..e53710de74 100644
--- a/packages/client/src/ui/deck/tl-column.vue
+++ b/packages/client/src/ui/deck/tl-column.vue
@@ -64,9 +64,9 @@ const emit = defineEmits<{
 	(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
 }>();
 
-let disabled = ref(false),
-	indicated = ref(false),
-	columnActive = ref(true);
+const disabled = ref(false);
+const indicated = ref(false);
+const columnActive = ref(true);
 
 onMounted(() => {
 	if (props.column.tl == null) {
diff --git a/packages/client/src/ui/deck/widgets-column.vue b/packages/client/src/ui/deck/widgets-column.vue
index 364b3d0a51..9b81430279 100644
--- a/packages/client/src/ui/deck/widgets-column.vue
+++ b/packages/client/src/ui/deck/widgets-column.vue
@@ -34,7 +34,6 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 
-import {} from "vue";
 import XColumn from "./column.vue";
 import type { Column } from "./deck-store";
 import {
@@ -55,7 +54,7 @@ const emit = defineEmits<{
 	(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
 }>();
 
-let edit = ref(false);
+const edit = ref(false);
 
 function addWidget(widget) {
 	addColumnWidget(props.column.id, widget);
diff --git a/packages/client/src/ui/universal.vue b/packages/client/src/ui/universal.vue
index 882f59ddc7..0c9aa65efc 100644
--- a/packages/client/src/ui/universal.vue
+++ b/packages/client/src/ui/universal.vue
@@ -183,10 +183,7 @@ import { navbarItemDef } from "@/navbar";
 import { i18n } from "@/i18n";
 import { $i } from "@/account";
 import { mainRouter } from "@/router";
-import {
-	provideMetadataReceiver,
-	setPageMetadata,
-} from "@/scripts/page-metadata";
+import { provideMetadataReceiver } from "@/scripts/page-metadata";
 import { deviceKind } from "@/scripts/device-kind";
 
 const XWidgets = defineAsyncComponent(() => import("./universal.widgets.vue"));
@@ -210,7 +207,7 @@ window.addEventListener("resize", () => {
 const buttonAnimIndex = ref(0);
 const drawerMenuShowing = ref(false);
 
-let pageMetadata = ref<null | ComputedRef<PageMetadata>>();
+const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
 const widgetsEl = ref<HTMLElement>();
 const postButton = ref<HTMLElement>();
 const widgetsShowing = ref(false);
diff --git a/packages/client/src/ui/visitor.vue b/packages/client/src/ui/visitor.vue
index 9b602b5b05..b7ad4175f3 100644
--- a/packages/client/src/ui/visitor.vue
+++ b/packages/client/src/ui/visitor.vue
@@ -4,11 +4,10 @@
 </template>
 
 <script lang="ts">
-import { defineAsyncComponent, defineComponent } from "vue";
+import { defineComponent } from "vue";
 import DesignA from "./visitor/a.vue";
 import DesignB from "./visitor/b.vue";
 import XCommon from "./_common_/common.vue";
-import { i18n } from "@/i18n";
 
 export default defineComponent({
 	components: {
diff --git a/packages/client/src/ui/visitor/a.vue b/packages/client/src/ui/visitor/a.vue
index ebf8af132c..c00ad4de90 100644
--- a/packages/client/src/ui/visitor/a.vue
+++ b/packages/client/src/ui/visitor/a.vue
@@ -74,7 +74,7 @@
 </template>
 
 <script lang="ts">
-import { defineAsyncComponent, defineComponent } from "vue";
+import { defineComponent } from "vue";
 import XHeader from "./header.vue";
 import { host, instanceName } from "@/config";
 import { search } from "@/scripts/search";
diff --git a/packages/client/src/ui/visitor/b.vue b/packages/client/src/ui/visitor/b.vue
index 07ebaf69c5..2515876b76 100644
--- a/packages/client/src/ui/visitor/b.vue
+++ b/packages/client/src/ui/visitor/b.vue
@@ -72,29 +72,24 @@
 
 <script lang="ts" setup>
 import type { ComputedRef } from "vue";
-import { onMounted, provide, ref, computed } from "vue";
+import { computed, onMounted, provide, ref } from "vue";
 import XHeader from "./header.vue";
 import XKanban from "./kanban.vue";
 import { host, instanceName } from "@/config";
 import { search } from "@/scripts/search";
 import * as os from "@/os";
 import { instance } from "@/instance";
-import MkPagination from "@/components/MkPagination.vue";
 import XSigninDialog from "@/components/MkSigninDialog.vue";
 import XSignupDialog from "@/components/MkSignupDialog.vue";
-import MkButton from "@/components/MkButton.vue";
 import { ColdDeviceStorage, defaultStore } from "@/store";
 import { mainRouter } from "@/router";
 import type { PageMetadata } from "@/scripts/page-metadata";
-import {
-	provideMetadataReceiver,
-	setPageMetadata,
-} from "@/scripts/page-metadata";
+import { provideMetadataReceiver } from "@/scripts/page-metadata";
 import { i18n } from "@/i18n";
 
 const DESKTOP_THRESHOLD = 1000;
 
-let pageMetadata = ref<null | ComputedRef<PageMetadata>>();
+const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
 
 provide("router", mainRouter);
 provideMetadataReceiver((info) => {
@@ -113,9 +108,9 @@ const isTimelineAvailable =
 	!instance.disableRecommendedTimeline ||
 	!instance.disableGlobalTimeline;
 const showMenu = ref(false);
-let isDesktop = ref(window.innerWidth >= DESKTOP_THRESHOLD),
-	narrow = ref(window.innerWidth < 1280),
-	meta = ref();
+const isDesktop = ref(window.innerWidth >= DESKTOP_THRESHOLD);
+const narrow = ref(window.innerWidth < 1280);
+const meta = ref();
 
 const keymap = computed(() => {
 	return {
@@ -169,7 +164,7 @@ onMounted(() => {
 });
 
 defineExpose({
-	showMenu: showMenu,
+	showMenu,
 });
 </script>
 
diff --git a/packages/client/src/ui/visitor/kanban.vue b/packages/client/src/ui/visitor/kanban.vue
index f9c68c788a..c92dc9fde3 100644
--- a/packages/client/src/ui/visitor/kanban.vue
+++ b/packages/client/src/ui/visitor/kanban.vue
@@ -81,7 +81,7 @@
 </template>
 
 <script lang="ts">
-import { defineAsyncComponent, defineComponent } from "vue";
+import { defineComponent } from "vue";
 import { host, instanceName } from "@/config";
 import * as os from "@/os";
 import MkPagination from "@/components/MkPagination.vue";
diff --git a/packages/client/src/ui/zen.vue b/packages/client/src/ui/zen.vue
index d4e6dae87e..c4c4ff7c05 100644
--- a/packages/client/src/ui/zen.vue
+++ b/packages/client/src/ui/zen.vue
@@ -12,13 +12,10 @@ import { provide, ref } from "vue";
 import XCommon from "./_common_/common.vue";
 import { mainRouter } from "@/router";
 import type { PageMetadata } from "@/scripts/page-metadata";
-import {
-	provideMetadataReceiver,
-	setPageMetadata,
-} from "@/scripts/page-metadata";
+import { provideMetadataReceiver } from "@/scripts/page-metadata";
 import { instanceName } from "@/config";
 
-let pageMetadata = ref<null | ComputedRef<PageMetadata>>();
+const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
 
 provide("router", mainRouter);
 provideMetadataReceiver((info) => {
diff --git a/packages/client/src/widgets/activity.chart.vue b/packages/client/src/widgets/activity.chart.vue
index 16f55238c3..b8d099a5a7 100644
--- a/packages/client/src/widgets/activity.chart.vue
+++ b/packages/client/src/widgets/activity.chart.vue
@@ -40,12 +40,12 @@ const props = defineProps<{
 
 const viewBoxX: number = ref(147);
 const viewBoxY: number = ref(60);
-let zoom: number = ref(1),
-	pos: number = ref(0),
-	pointsNote: any = ref(null),
-	pointsReply: any = ref(null),
-	pointsRenote: any = ref(null),
-	pointsTotal: any = ref(null);
+const zoom: number = ref(1);
+const pos: number = ref(0);
+const pointsNote: any = ref(null);
+const pointsReply: any = ref(null);
+const pointsRenote: any = ref(null);
+const pointsTotal: any = ref(null);
 
 function dragListen(fn) {
 	window.addEventListener("mousemove", fn);
diff --git a/packages/client/src/widgets/activity.vue b/packages/client/src/widgets/activity.vue
index beeba81d71..2eb62d9ccd 100644
--- a/packages/client/src/widgets/activity.vue
+++ b/packages/client/src/widgets/activity.vue
@@ -37,13 +37,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive, ref, watch } from "vue";
+import { ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import XCalendar from "./activity.calendar.vue";
 import XChart from "./activity.chart.vue";
 import MkHeatmap from "@/components/MkHeatmap.vue";
diff --git a/packages/client/src/widgets/aiscript.vue b/packages/client/src/widgets/aiscript.vue
index ac1472da17..e470a33c19 100644
--- a/packages/client/src/widgets/aiscript.vue
+++ b/packages/client/src/widgets/aiscript.vue
@@ -26,14 +26,10 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, watch } from "vue";
+import { ref } from "vue";
 import { AiScript, parse, utils } from "@syuilo/aiscript";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import * as os from "@/os";
 import MkContainer from "@/components/MkContainer.vue";
diff --git a/packages/client/src/widgets/button.vue b/packages/client/src/widgets/button.vue
index b9378e0ea2..52d985cc82 100644
--- a/packages/client/src/widgets/button.vue
+++ b/packages/client/src/widgets/button.vue
@@ -7,14 +7,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, watch } from "vue";
-import { AiScript, parse, utils } from "@syuilo/aiscript";
+import { AiScript, parse } from "@syuilo/aiscript";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import * as os from "@/os";
 import { createAiScriptEnv } from "@/scripts/aiscript/api";
diff --git a/packages/client/src/widgets/calendar.vue b/packages/client/src/widgets/calendar.vue
index eb2ec6c410..619e8359d4 100644
--- a/packages/client/src/widgets/calendar.vue
+++ b/packages/client/src/widgets/calendar.vue
@@ -44,13 +44,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onUnmounted, ref } from "vue";
+import { ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import { i18n } from "@/i18n";
 import { useInterval } from "@/scripts/use-interval";
@@ -128,7 +124,7 @@ const tick = () => {
 
 	if (hasBirthday) {
 		const [bdayYear, bdayMonth, bdayDay] = $i.birthday.split("-");
-		if (month.value === +bdayMonth && day.value == +bdayDay) {
+		if (month.value === +bdayMonth && day.value === +bdayDay) {
 			isBirthday.value = true;
 		}
 	}
diff --git a/packages/client/src/widgets/clock.vue b/packages/client/src/widgets/clock.vue
index a8fa7b8303..6cdd520d98 100644
--- a/packages/client/src/widgets/clock.vue
+++ b/packages/client/src/widgets/clock.vue
@@ -48,13 +48,8 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import {} from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import MkContainer from "@/components/MkContainer.vue";
 import MkAnalogClock from "@/components/MkAnalogClock.vue";
diff --git a/packages/client/src/widgets/digital-clock.vue b/packages/client/src/widgets/digital-clock.vue
index 1b259b11f1..d77452459b 100644
--- a/packages/client/src/widgets/digital-clock.vue
+++ b/packages/client/src/widgets/digital-clock.vue
@@ -15,13 +15,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onUnmounted, ref, watch, computed } from "vue";
+import { computed } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import { timezones } from "@/scripts/timezones";
 import MkDigitalClock from "@/components/MkDigitalClock.vue";
diff --git a/packages/client/src/widgets/federation.vue b/packages/client/src/widgets/federation.vue
index a8e121519c..b00280554c 100644
--- a/packages/client/src/widgets/federation.vue
+++ b/packages/client/src/widgets/federation.vue
@@ -48,13 +48,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import MkContainer from "@/components/MkContainer.vue";
 import MkMiniChart from "@/components/MkMiniChart.vue";
diff --git a/packages/client/src/widgets/index.ts b/packages/client/src/widgets/index.ts
index 4c48811a96..746bd5eeb9 100644
--- a/packages/client/src/widgets/index.ts
+++ b/packages/client/src/widgets/index.ts
@@ -1,4 +1,5 @@
-import { App, defineAsyncComponent } from "vue";
+import type { App } from "vue";
+import { defineAsyncComponent } from "vue";
 
 export default function (app: App) {
 	app.component(
diff --git a/packages/client/src/widgets/instance-cloud.vue b/packages/client/src/widgets/instance-cloud.vue
index 9aeb843711..c3f53dc014 100644
--- a/packages/client/src/widgets/instance-cloud.vue
+++ b/packages/client/src/widgets/instance-cloud.vue
@@ -22,12 +22,7 @@
 <script lang="ts" setup>
 import { ref, shallowRef } from "vue";
 
-import {} from "vue";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { Widget, WidgetComponentExpose } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import MkContainer from "@/components/MkContainer.vue";
@@ -61,7 +56,7 @@ const { widgetProps, configure } = useWidgetPropsManager(
 );
 
 const cloud = ref<InstanceType<typeof MkTagCloud> | null>();
-let activeInstances = shallowRef(null);
+const activeInstances = shallowRef(null);
 
 function onInstanceClick(i) {
 	os.pageWindow(`/instance-info/${i.host}`);
diff --git a/packages/client/src/widgets/job-queue.vue b/packages/client/src/widgets/job-queue.vue
index 05cf59ab87..c58d48f088 100644
--- a/packages/client/src/widgets/job-queue.vue
+++ b/packages/client/src/widgets/job-queue.vue
@@ -123,18 +123,13 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive, ref } from "vue";
+import { onUnmounted, reactive } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import { stream } from "@/stream";
 import number from "@/filters/number";
 import * as sound from "@/scripts/sound";
-import * as os from "@/os";
 import { deepClone } from "@/scripts/clone";
 
 const name = "jobQueue";
diff --git a/packages/client/src/widgets/memo.vue b/packages/client/src/widgets/memo.vue
index 78c5ad5a6b..1fdd1a25f9 100644
--- a/packages/client/src/widgets/memo.vue
+++ b/packages/client/src/widgets/memo.vue
@@ -23,15 +23,10 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive, ref, watch } from "vue";
+import { ref, watch } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
-import * as os from "@/os";
 import MkContainer from "@/components/MkContainer.vue";
 import { defaultStore } from "@/store";
 import { i18n } from "@/i18n";
diff --git a/packages/client/src/widgets/notifications.vue b/packages/client/src/widgets/notifications.vue
index cc253b5cc6..f320321652 100644
--- a/packages/client/src/widgets/notifications.vue
+++ b/packages/client/src/widgets/notifications.vue
@@ -32,11 +32,7 @@
 <script lang="ts" setup>
 import { defineAsyncComponent } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import MkContainer from "@/components/MkContainer.vue";
 import XNotifications from "@/components/MkNotifications.vue";
diff --git a/packages/client/src/widgets/online-users.vue b/packages/client/src/widgets/online-users.vue
index 6293094e71..4a3662887e 100644
--- a/packages/client/src/widgets/online-users.vue
+++ b/packages/client/src/widgets/online-users.vue
@@ -20,13 +20,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import * as os from "@/os";
 import { useInterval } from "@/scripts/use-interval";
diff --git a/packages/client/src/widgets/photos.vue b/packages/client/src/widgets/photos.vue
index 3a01306240..779857dfb3 100644
--- a/packages/client/src/widgets/photos.vue
+++ b/packages/client/src/widgets/photos.vue
@@ -26,13 +26,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive, ref } from "vue";
+import { onUnmounted, ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import { stream } from "@/stream";
 import { getStaticImageUrl } from "@/scripts/get-static-image-url";
diff --git a/packages/client/src/widgets/post-form.vue b/packages/client/src/widgets/post-form.vue
index e76d6ba6f1..79dd3bef45 100644
--- a/packages/client/src/widgets/post-form.vue
+++ b/packages/client/src/widgets/post-form.vue
@@ -10,11 +10,7 @@
 <script lang="ts" setup>
 import {} from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import XPostForm from "@/components/MkPostForm.vue";
 
diff --git a/packages/client/src/widgets/rss-ticker.vue b/packages/client/src/widgets/rss-ticker.vue
index 9c9b741486..840eb63e99 100644
--- a/packages/client/src/widgets/rss-ticker.vue
+++ b/packages/client/src/widgets/rss-ticker.vue
@@ -37,16 +37,11 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, watch } from "vue";
+import { ref, watch } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import MarqueeText from "@/components/MkMarquee.vue";
 import type { GetFormResultType } from "@/scripts/form";
-import * as os from "@/os";
 import MkContainer from "@/components/MkContainer.vue";
 import { useInterval } from "@/scripts/use-interval";
 import { shuffle } from "@/scripts/shuffle";
@@ -104,7 +99,7 @@ const { widgetProps, configure } = useWidgetPropsManager(
 
 const items = ref([]);
 const fetching = ref(true);
-let key = ref(0);
+const key = ref(0);
 
 const tick = () => {
 	fetch(`/api/fetch-rss?url=${widgetProps.url}`, {}).then((res) => {
diff --git a/packages/client/src/widgets/rss.vue b/packages/client/src/widgets/rss.vue
index 9ba99e2d28..2ce7947840 100644
--- a/packages/client/src/widgets/rss.vue
+++ b/packages/client/src/widgets/rss.vue
@@ -29,15 +29,10 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, watch } from "vue";
+import { ref, watch } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
-import * as os from "@/os";
 import MkContainer from "@/components/MkContainer.vue";
 import { useInterval } from "@/scripts/use-interval";
 
diff --git a/packages/client/src/widgets/server-info.vue b/packages/client/src/widgets/server-info.vue
index 7b2b63d2a6..8f8b8ef281 100644
--- a/packages/client/src/widgets/server-info.vue
+++ b/packages/client/src/widgets/server-info.vue
@@ -31,11 +31,7 @@
 
 <script lang="ts" setup>
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import { host } from "@/config";
 
diff --git a/packages/client/src/widgets/server-metric/cpu-mem.vue b/packages/client/src/widgets/server-metric/cpu-mem.vue
index 1b3a5b1137..df03b8135e 100644
--- a/packages/client/src/widgets/server-metric/cpu-mem.vue
+++ b/packages/client/src/widgets/server-metric/cpu-mem.vue
@@ -97,16 +97,16 @@ const cpuGradientId = uuid();
 const cpuMaskId = uuid();
 const memGradientId = uuid();
 const memMaskId = uuid();
-let cpuPolylinePoints: string = ref(""),
-	memPolylinePoints: string = ref(""),
-	cpuPolygonPoints: string = ref(""),
-	memPolygonPoints: string = ref(""),
-	cpuHeadX: any = ref(null),
-	cpuHeadY: any = ref(null),
-	memHeadX: any = ref(null),
-	memHeadY: any = ref(null),
-	cpuP: string = ref(""),
-	memP: string = ref("");
+const cpuPolylinePoints: string = ref("");
+const memPolylinePoints: string = ref("");
+const cpuPolygonPoints: string = ref("");
+const memPolygonPoints: string = ref("");
+const cpuHeadX: any = ref(null);
+const cpuHeadY: any = ref(null);
+const memHeadX: any = ref(null);
+const memHeadY: any = ref(null);
+const cpuP: string = ref("");
+const memP: string = ref("");
 
 onMounted(() => {
 	props.connection.on("stats", onStats);
diff --git a/packages/client/src/widgets/server-metric/cpu.vue b/packages/client/src/widgets/server-metric/cpu.vue
index 8461e118d9..500e28b677 100644
--- a/packages/client/src/widgets/server-metric/cpu.vue
+++ b/packages/client/src/widgets/server-metric/cpu.vue
@@ -18,7 +18,7 @@ const props = defineProps<{
 	meta: any;
 }>();
 
-let usage: number = ref(0);
+const usage: number = ref(0);
 
 function onStats(stats) {
 	usage.value = stats.cpu;
diff --git a/packages/client/src/widgets/server-metric/disk.vue b/packages/client/src/widgets/server-metric/disk.vue
index ac28c7cb50..dcf6efd2fe 100644
--- a/packages/client/src/widgets/server-metric/disk.vue
+++ b/packages/client/src/widgets/server-metric/disk.vue
@@ -13,7 +13,6 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import {} from "vue";
 import XPie from "./pie.vue";
 import bytes from "@/filters/bytes";
 
diff --git a/packages/client/src/widgets/server-metric/index.vue b/packages/client/src/widgets/server-metric/index.vue
index 940d2763c7..f6e3b495bb 100644
--- a/packages/client/src/widgets/server-metric/index.vue
+++ b/packages/client/src/widgets/server-metric/index.vue
@@ -58,13 +58,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { onUnmounted, ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "../widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "../widget";
+import { useWidgetPropsManager } from "../widget";
 import XCpuMemory from "./cpu-mem.vue";
 import XNet from "./net.vue";
 import XCpu from "./cpu.vue";
diff --git a/packages/client/src/widgets/server-metric/meilisearch.vue b/packages/client/src/widgets/server-metric/meilisearch.vue
index bfadc0a3a3..db3212c86e 100644
--- a/packages/client/src/widgets/server-metric/meilisearch.vue
+++ b/packages/client/src/widgets/server-metric/meilisearch.vue
@@ -28,11 +28,11 @@ const props = defineProps<{
 	meta: any;
 }>();
 
-let progress: number = ref(0),
-	serverStats = ref(null),
-	totalSize: number = ref(0),
-	indexCount: number = ref(0),
-	available: string = ref("unavailable");
+const progress: number = ref(0);
+const serverStats = ref(null);
+const totalSize: number = ref(0);
+const indexCount: number = ref(0);
+const available: string = ref("unavailable");
 
 function onStats(stats) {
 	totalSize.value = stats.meilisearch.size;
diff --git a/packages/client/src/widgets/server-metric/mem.vue b/packages/client/src/widgets/server-metric/mem.vue
index bc7c9d561b..96d13b36e5 100644
--- a/packages/client/src/widgets/server-metric/mem.vue
+++ b/packages/client/src/widgets/server-metric/mem.vue
@@ -20,10 +20,10 @@ const props = defineProps<{
 	meta: any;
 }>();
 
-let usage: number = ref(0),
-	total: number = ref(0),
-	used: number = ref(0),
-	free: number = ref(0);
+const usage: number = ref(0);
+const total: number = ref(0);
+const used: number = ref(0);
+const free: number = ref(0);
 
 function onStats(stats) {
 	usage.value = stats.mem.active / stats.mem.total;
diff --git a/packages/client/src/widgets/server-metric/net.vue b/packages/client/src/widgets/server-metric/net.vue
index 7f1c8c0464..592604c5a1 100644
--- a/packages/client/src/widgets/server-metric/net.vue
+++ b/packages/client/src/widgets/server-metric/net.vue
@@ -51,16 +51,16 @@ const props = defineProps<{
 const viewBoxX: number = ref(50);
 const viewBoxY: number = ref(30);
 const stats: any[] = ref([]);
-let inPolylinePoints: string = ref(""),
-	outPolylinePoints: string = ref(""),
-	inPolygonPoints: string = ref(""),
-	outPolygonPoints: string = ref(""),
-	inHeadX: any = ref(null),
-	inHeadY: any = ref(null),
-	outHeadX: any = ref(null),
-	outHeadY: any = ref(null),
-	inRecent: number = ref(0),
-	outRecent: number = ref(0);
+const inPolylinePoints: string = ref("");
+const outPolylinePoints: string = ref("");
+const inPolygonPoints: string = ref("");
+const outPolygonPoints: string = ref("");
+const inHeadX: any = ref(null);
+const inHeadY: any = ref(null);
+const outHeadX: any = ref(null);
+const outHeadY: any = ref(null);
+const inRecent: number = ref(0);
+const outRecent: number = ref(0);
 
 onMounted(() => {
 	props.connection.on("stats", onStats);
diff --git a/packages/client/src/widgets/server-metric/pie.vue b/packages/client/src/widgets/server-metric/pie.vue
index 5fe26cff7d..93880757b0 100644
--- a/packages/client/src/widgets/server-metric/pie.vue
+++ b/packages/client/src/widgets/server-metric/pie.vue
@@ -27,8 +27,6 @@
 <script lang="ts" setup>
 import { computed } from "vue";
 
-import {} from "vue";
-
 const props = defineProps<{
 	value: number;
 	reverse?: boolean;
diff --git a/packages/client/src/widgets/slideshow.vue b/packages/client/src/widgets/slideshow.vue
index 70601466da..6a7ec6c59d 100644
--- a/packages/client/src/widgets/slideshow.vue
+++ b/packages/client/src/widgets/slideshow.vue
@@ -23,13 +23,9 @@
 </template>
 
 <script lang="ts" setup>
-import { nextTick, onMounted, onUnmounted, reactive, ref } from "vue";
+import { onMounted, ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import * as os from "@/os";
 import { useInterval } from "@/scripts/use-interval";
diff --git a/packages/client/src/widgets/timeline.vue b/packages/client/src/widgets/timeline.vue
index 8ff30d2999..392840392e 100644
--- a/packages/client/src/widgets/timeline.vue
+++ b/packages/client/src/widgets/timeline.vue
@@ -67,18 +67,13 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive, ref, watch } from "vue";
+import { ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import * as os from "@/os";
 import MkContainer from "@/components/MkContainer.vue";
 import XTimeline from "@/components/MkTimeline.vue";
-import { $i } from "@/account";
 import { i18n } from "@/i18n";
 
 const name = "timeline";
diff --git a/packages/client/src/widgets/trends.vue b/packages/client/src/widgets/trends.vue
index 52b0681278..d66d5731f3 100644
--- a/packages/client/src/widgets/trends.vue
+++ b/packages/client/src/widgets/trends.vue
@@ -37,13 +37,9 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from "vue";
+import { ref } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 import MkContainer from "@/components/MkContainer.vue";
 import MkMiniChart from "@/components/MkMiniChart.vue";
diff --git a/packages/client/src/widgets/unix-clock.vue b/packages/client/src/widgets/unix-clock.vue
index 3d2a893187..ba35769347 100644
--- a/packages/client/src/widgets/unix-clock.vue
+++ b/packages/client/src/widgets/unix-clock.vue
@@ -19,11 +19,7 @@
 <script lang="ts" setup>
 import { onUnmounted, ref, watch } from "vue";
 import type { Widget, WidgetComponentExpose } from "./widget";
-import {
-	WidgetComponentEmits,
-	WidgetComponentProps,
-	useWidgetPropsManager,
-} from "./widget";
+import { useWidgetPropsManager } from "./widget";
 import type { GetFormResultType } from "@/scripts/form";
 
 const name = "unixClock";
diff --git a/packages/client/src/widgets/user-list.vue b/packages/client/src/widgets/user-list.vue
index cfcdacba22..90a6ef6cd1 100644
--- a/packages/client/src/widgets/user-list.vue
+++ b/packages/client/src/widgets/user-list.vue
@@ -64,24 +64,10 @@ const { widgetProps, configure, save } = useWidgetPropsManager(
 	props,
 	emit,
 );
-let list = ref(),
-	users = ref([]),
-	fetching = ref(true);
-async function chooseList() {
-	const lists = await os.api("users/lists/list");
-	const { canceled, result: list } = await os.select({
-		title: i18n.ts.selectList,
-		items: lists.map((x) => ({
-			value: x,
-			text: x.name,
-		})),
-		default: widgetProps.listId,
-	});
-	if (canceled) return;
-	widgetProps.listId = list.id;
-	save();
-	fetch();
-}
+const list = ref();
+const users = ref([]);
+const fetching = ref(true);
+
 const fetch = () => {
 	if (widgetProps.listId == null) {
 		fetching.value = false;
@@ -99,6 +85,23 @@ const fetch = () => {
 		});
 	});
 };
+
+async function chooseList() {
+	const lists = await os.api("users/lists/list");
+	const { canceled, result: list } = await os.select({
+		title: i18n.ts.selectList,
+		items: lists.map((x) => ({
+			value: x,
+			text: x.name,
+		})),
+		default: widgetProps.listId,
+	});
+	if (canceled) return;
+	widgetProps.listId = list.id;
+	save();
+	fetch();
+}
+
 useInterval(fetch, 1000 * 60, {
 	immediate: true,
 	afterMounted: true,
diff --git a/packages/client/src/widgets/widget.ts b/packages/client/src/widgets/widget.ts
index 1afc296de0..9f33cecfa2 100644
--- a/packages/client/src/widgets/widget.ts
+++ b/packages/client/src/widgets/widget.ts
@@ -1,27 +1,27 @@
 import { reactive, watch } from "vue";
 import { throttle } from "throttle-debounce";
-import { Form, GetFormResultType } from "@/scripts/form";
+import type { Form, GetFormResultType } from "@/scripts/form";
 import * as os from "@/os";
 import { deepClone } from "@/scripts/clone";
 
-export type Widget<P extends Record<string, unknown>> = {
+export interface Widget<P extends Record<string, unknown>> {
 	id: string;
 	data: Partial<P>;
-};
+}
 
-export type WidgetComponentProps<P extends Record<string, unknown>> = {
+export interface WidgetComponentProps<P extends Record<string, unknown>> {
 	widget?: Widget<P>;
-};
+}
 
-export type WidgetComponentEmits<P extends Record<string, unknown>> = {
+export interface WidgetComponentEmits<P extends Record<string, unknown>> {
 	(ev: "updateProps", props: P);
-};
+}
 
-export type WidgetComponentExpose = {
+export interface WidgetComponentExpose {
 	name: string;
 	id: string | null;
 	configure: () => void;
-};
+}
 
 export const useWidgetPropsManager = <
 	F extends Form & Record<string, { default: any }>,
diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json
index 2d292dbfb0..8e955859f1 100644
--- a/packages/client/tsconfig.json
+++ b/packages/client/tsconfig.json
@@ -23,24 +23,13 @@
 		"useDefineForClassFields": true,
 		"baseUrl": ".",
 		"paths": {
-			"@/*": ["./src/*"],
+			"@/*": ["./src/*"]
 		},
-		"typeRoots": [
-			"node_modules/@types",
-			"@types",
-		],
-		"types": [
-			"vite/client",
-		],
-		"lib": [
-			"esnext",
-			"dom"
-		],
+		"typeRoots": ["node_modules/@types", "@types"],
+		"types": ["vite/client"],
+		"lib": ["esnext", "dom"],
 		"jsx": "preserve"
 	},
 	"compileOnSave": false,
-	"include": [
-		"./**/*.ts",
-		"./**/*.vue"
-	]
+	"include": ["./**/*.ts", "./**/*.vue"]
 }
diff --git a/packages/client/vite.config.ts b/packages/client/vite.config.ts
index 90f75b66cf..feec421fa8 100644
--- a/packages/client/vite.config.ts
+++ b/packages/client/vite.config.ts
@@ -2,10 +2,12 @@ import * as fs from "fs";
 import pluginVue from "@vitejs/plugin-vue";
 import { defineConfig } from "vite";
 
+import viteCompression from "vite-plugin-compression";
+import AutoImport from "unplugin-auto-import/vite";
+import Components from "unplugin-vue-components/vite";
 import locales from "../../locales";
 import meta from "../../package.json";
 import pluginJson5 from "./vite.json5";
-import viteCompression from "vite-plugin-compression";
 
 const extensions = [
 	".ts",
@@ -37,6 +39,22 @@ export default defineConfig(({ command, mode }) => {
 			pluginVue({
 				reactivityTransform: true,
 			}),
+			AutoImport({
+				include: [
+					/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
+					/\.vue$/,
+					/\.vue\?vue/, // .vue
+				],
+				imports: ["vue"],
+				vueTemplate: true,
+				dts: true,
+				eslintrc: {
+					enabled: true,
+				},
+			}),
+			Components({
+				dts: true,
+			}),
 			pluginJson5(),
 			viteCompression({
 				algorithm: "brotliCompress",
diff --git a/packages/client/vite.json5.ts b/packages/client/vite.json5.ts
index 8653c66d8c..8b4900bedc 100644
--- a/packages/client/vite.json5.ts
+++ b/packages/client/vite.json5.ts
@@ -1,9 +1,9 @@
 // Original: https://github.com/rollup/plugins/tree/8835dd2aed92f408d7dc72d7cc25a9728e16face/packages/json
 
 import JSON5 from "json5";
-import { Plugin } from "rollup";
+import type { Plugin } from "rollup";
 import { createFilter, dataToEsm } from "@rollup/pluginutils";
-import { RollupJsonOptions } from "@rollup/plugin-json";
+import type { RollupJsonOptions } from "@rollup/plugin-json";
 
 interface Json5SyntaxError extends SyntaxError {
 	lineNumber: number;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 24528076f3..ba269f4a2e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -743,6 +743,9 @@ importers:
       eslint-plugin-file-progress:
         specifier: ^1.3.0
         version: 1.3.0(eslint@8.46.0)
+      eslint-plugin-unused-imports:
+        specifier: ^3.0.0
+        version: 3.0.0(eslint@8.46.0)
       eventemitter3:
         specifier: 5.0.1
         version: 5.0.1
@@ -779,9 +782,6 @@ importers:
       mfm-js:
         specifier: 0.23.3
         version: 0.23.3
-      paralint:
-        specifier: ^1.2.1
-        version: 1.2.1
       photoswipe:
         specifier: 5.3.8
         version: 5.3.8
@@ -857,6 +857,12 @@ importers:
       unicode-emoji-json:
         specifier: ^0.4.0
         version: 0.4.0
+      unplugin-auto-import:
+        specifier: ^0.16.6
+        version: 0.16.6(rollup@3.27.2)
+      unplugin-vue-components:
+        specifier: ^0.25.1
+        version: 0.25.1(rollup@3.27.2)(vue@3.3.4)
       uuid:
         specifier: 9.0.0
         version: 9.0.0
@@ -865,7 +871,7 @@ importers:
         version: 1.8.0
       vite:
         specifier: 4.4.9
-        version: 4.4.9(@types/node@20.4.9)(sass@1.64.2)
+        version: 4.4.9(sass@1.64.2)
       vite-plugin-compression:
         specifier: ^0.5.1
         version: 0.5.1(vite@4.4.9)
@@ -1103,6 +1109,10 @@ packages:
       '@jridgewell/gen-mapping': 0.3.3
       '@jridgewell/trace-mapping': 0.3.19
 
+  /@antfu/utils@0.7.5:
+    resolution: {integrity: sha512-dlR6LdS+0SzOAPx/TPRhnoi7hE251OVeT2Snw0RguNbBSbjUHdWr0l3vcUUDg26rEysT89kCbtw1lVorBXLLCg==}
+    dev: true
+
   /@babel/code-frame@7.22.10:
     resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==}
     engines: {node: '>=6.9.0'}
@@ -2919,13 +2929,6 @@ packages:
       semver: 7.5.4
     dev: false
 
-  /@npmcli/promise-spawn@6.0.2:
-    resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==}
-    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
-    dependencies:
-      which: 3.0.1
-    dev: true
-
   /@nsfw-filter/gif-frames@1.0.2:
     resolution: {integrity: sha512-XZrbJWEN8YfVla5i+PD4Wj51rRlJ8OgnXiPjjOt/OsrbsCR9GZRD4jr953oNWcwiRaoIcOCFWQNMQukO7Yb1dA==}
     dependencies:
@@ -3099,6 +3102,21 @@ packages:
       picomatch: 2.3.1
     dev: true
 
+  /@rollup/pluginutils@5.0.2(rollup@3.27.2):
+    resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
+    engines: {node: '>=14.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0||^3.0.0
+    peerDependenciesMeta:
+      rollup:
+        optional: true
+    dependencies:
+      '@types/estree': 1.0.1
+      estree-walker: 2.0.2
+      picomatch: 2.3.1
+      rollup: 3.27.2
+    dev: true
+
   /@rometools/cli-darwin-arm64@12.1.3:
     resolution: {integrity: sha512-AmFTUDYjBuEGQp/Wwps+2cqUr+qhR7gyXAUnkL5psCuNCz3807TrUq/ecOoct5MIavGJTH6R4aaSL6+f+VlBEg==}
     cpu: [arm64]
@@ -4902,7 +4920,7 @@ packages:
       vite: ^4.0.0
       vue: ^3.2.25
     dependencies:
-      vite: 4.4.9(@types/node@20.4.9)(sass@1.64.2)
+      vite: 4.4.9(sass@1.64.2)
       vue: 3.3.4
     dev: true
 
@@ -7579,11 +7597,6 @@ packages:
       es5-ext: 0.10.62
       type: 1.2.0
 
-  /dargs@8.1.0:
-    resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==}
-    engines: {node: '>=12'}
-    dev: true
-
   /dashdash@1.14.1:
     resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==}
     engines: {node: '>=0.10'}
@@ -8963,6 +8976,20 @@ packages:
       strip-indent: 3.0.0
     dev: true
 
+  /eslint-plugin-unused-imports@3.0.0(eslint@8.46.0):
+    resolution: {integrity: sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      '@typescript-eslint/eslint-plugin': ^6.0.0
+      eslint: ^8.0.0
+    peerDependenciesMeta:
+      '@typescript-eslint/eslint-plugin':
+        optional: true
+    dependencies:
+      eslint: 8.46.0
+      eslint-rule-composer: 0.3.0
+    dev: true
+
   /eslint-plugin-vitest-globals@1.4.0:
     resolution: {integrity: sha512-WE+YlK9X9s4vf5EaYRU0Scw7WItDZStm+PapFSYlg2ABNtaQ4zIG7wEqpoUB3SlfM+SgkhgmzR0TeJOO5k3/Nw==}
     dev: true
@@ -9020,6 +9047,11 @@ packages:
       - supports-color
     dev: true
 
+  /eslint-rule-composer@0.3.0:
+    resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==}
+    engines: {node: '>=4.0.0'}
+    dev: true
+
   /eslint-rule-docs@1.1.235:
     resolution: {integrity: sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==}
     dev: true
@@ -13121,7 +13153,7 @@ packages:
       content-disposition: 0.5.4
       content-type: 1.0.5
       cookies: 0.8.0
-      debug: 4.3.3
+      debug: 4.3.4(supports-color@8.1.1)
       delegates: 1.0.0
       depd: 2.0.0
       destroy: 1.2.0
@@ -13831,7 +13863,6 @@ packages:
     engines: {node: '>=16 || 14 >=14.17'}
     dependencies:
       brace-expansion: 2.0.1
-    dev: false
 
   /minimist-options@4.1.0:
     resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
@@ -13958,6 +13989,15 @@ packages:
     hasBin: true
     dev: false
 
+  /mlly@1.4.0:
+    resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
+    dependencies:
+      acorn: 8.10.0
+      pathe: 1.1.1
+      pkg-types: 1.0.3
+      ufo: 1.2.0
+    dev: true
+
   /mocha@10.2.0:
     resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==}
     engines: {node: '>= 14.0.0'}
@@ -14751,17 +14791,6 @@ packages:
     resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
     dev: false
 
-  /paralint@1.2.1:
-    resolution: {integrity: sha512-HPGVDd5eUNYBhtftRypBHlUTMy5UAnHBzFO601oLEODZ0uvXUJge1y43GZQM2CnyOOUyDQlNMK/9vcjjAxbfcA==}
-    hasBin: true
-    dependencies:
-      '@npmcli/promise-spawn': 6.0.2
-      dargs: 8.1.0
-      fast-glob: 3.3.1
-      minimist: 1.2.8
-      tslib: 2.6.1
-    dev: true
-
   /parent-module@1.0.1:
     resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
     engines: {node: '>=6'}
@@ -14948,6 +14977,10 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /pathe@1.1.1:
+    resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
+    dev: true
+
   /pause-stream@0.0.11:
     resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==}
     dependencies:
@@ -15091,6 +15124,14 @@ packages:
       find-up: 4.1.0
     dev: true
 
+  /pkg-types@1.0.3:
+    resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
+    dependencies:
+      jsonc-parser: 3.2.0
+      mlly: 1.4.0
+      pathe: 1.1.1
+    dev: true
+
   /plimit-lit@1.5.0:
     resolution: {integrity: sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==}
     dependencies:
@@ -16511,6 +16552,10 @@ packages:
       ajv-keywords: 3.5.2(ajv@6.12.6)
     dev: true
 
+  /scule@1.0.0:
+    resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==}
+    dev: true
+
   /secure-json-parse@2.7.0:
     resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
     dev: false
@@ -17204,6 +17249,12 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /strip-literal@1.3.0:
+    resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==}
+    dependencies:
+      acorn: 8.10.0
+    dev: true
+
   /strip-outer@2.0.0:
     resolution: {integrity: sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -18242,6 +18293,10 @@ packages:
     engines: {node: '>=14.17'}
     hasBin: true
 
+  /ufo@1.2.0:
+    resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==}
+    dev: true
+
   /ulid@2.3.0:
     resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==}
     hasBin: true
@@ -18300,6 +18355,24 @@ packages:
     resolution: {integrity: sha512-lVNOwh2AnmbwqtSrEVjAWKQoVzWgyWmXVqPuPkPfKb0tnA0+uYN/4ILCTdy9IRj/+3drAVhmjwjNJQr2dhCwnA==}
     dev: true
 
+  /unimport@3.1.3(rollup@3.27.2):
+    resolution: {integrity: sha512-up4TE2yA+nMyyErGTjbYGVw95MriGa2hVRXQ3/JRp7984cwwqULcnBjHaovVpsO8tZc2j0fvgGu9yiBKOyxvYw==}
+    dependencies:
+      '@rollup/pluginutils': 5.0.2(rollup@3.27.2)
+      escape-string-regexp: 5.0.0
+      fast-glob: 3.3.1
+      local-pkg: 0.4.3
+      magic-string: 0.30.2
+      mlly: 1.4.0
+      pathe: 1.1.1
+      pkg-types: 1.0.3
+      scule: 1.0.0
+      strip-literal: 1.3.0
+      unplugin: 1.4.0
+    transitivePeerDependencies:
+      - rollup
+    dev: true
+
   /union-value@1.0.1:
     resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==}
     engines: {node: '>=0.10.0'}
@@ -18366,6 +18439,68 @@ packages:
     engines: {node: '>= 0.8'}
     dev: false
 
+  /unplugin-auto-import@0.16.6(rollup@3.27.2):
+    resolution: {integrity: sha512-M+YIITkx3C/Hg38hp8HmswP5mShUUyJOzpifv7RTlAbeFlO2Tyw0pwrogSSxnipHDPTtI8VHFBpkYkNKzYSuyA==}
+    engines: {node: '>=14'}
+    peerDependencies:
+      '@nuxt/kit': ^3.2.2
+      '@vueuse/core': '*'
+    peerDependenciesMeta:
+      '@nuxt/kit':
+        optional: true
+      '@vueuse/core':
+        optional: true
+    dependencies:
+      '@antfu/utils': 0.7.5
+      '@rollup/pluginutils': 5.0.2(rollup@3.27.2)
+      fast-glob: 3.3.1
+      local-pkg: 0.4.3
+      magic-string: 0.30.2
+      minimatch: 9.0.3
+      unimport: 3.1.3(rollup@3.27.2)
+      unplugin: 1.4.0
+    transitivePeerDependencies:
+      - rollup
+    dev: true
+
+  /unplugin-vue-components@0.25.1(rollup@3.27.2)(vue@3.3.4):
+    resolution: {integrity: sha512-kzS2ZHVMaGU2XEO2keYQcMjNZkanDSGDdY96uQT9EPe+wqSZwwgbFfKVJ5ti0+8rGAcKHColwKUvctBhq2LJ3A==}
+    engines: {node: '>=14'}
+    peerDependencies:
+      '@babel/parser': ^7.15.8
+      '@nuxt/kit': ^3.2.2
+      vue: 2 || 3
+    peerDependenciesMeta:
+      '@babel/parser':
+        optional: true
+      '@nuxt/kit':
+        optional: true
+    dependencies:
+      '@antfu/utils': 0.7.5
+      '@rollup/pluginutils': 5.0.2(rollup@3.27.2)
+      chokidar: 3.5.3
+      debug: 4.3.4(supports-color@8.1.1)
+      fast-glob: 3.3.1
+      local-pkg: 0.4.3
+      magic-string: 0.30.2
+      minimatch: 9.0.3
+      resolve: 1.22.4
+      unplugin: 1.4.0
+      vue: 3.3.4
+    transitivePeerDependencies:
+      - rollup
+      - supports-color
+    dev: true
+
+  /unplugin@1.4.0:
+    resolution: {integrity: sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==}
+    dependencies:
+      acorn: 8.10.0
+      chokidar: 3.5.3
+      webpack-sources: 3.2.3
+      webpack-virtual-modules: 0.5.0
+    dev: true
+
   /unset-value@1.0.0:
     resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==}
     engines: {node: '>=0.10.0'}
@@ -18597,12 +18732,12 @@ packages:
       chalk: 4.1.2
       debug: 4.3.4(supports-color@8.1.1)
       fs-extra: 10.1.0
-      vite: 4.4.9(@types/node@20.4.9)(sass@1.64.2)
+      vite: 4.4.9(sass@1.64.2)
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /vite@4.4.9(@types/node@20.4.9)(sass@1.64.2):
+  /vite@4.4.9(sass@1.64.2):
     resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
     engines: {node: ^14.18.0 || >=16.0.0}
     hasBin: true
@@ -18630,7 +18765,6 @@ packages:
       terser:
         optional: true
     dependencies:
-      '@types/node': 20.4.9
       esbuild: 0.18.20
       postcss: 8.4.27
       rollup: 3.27.2
@@ -18861,6 +18995,10 @@ packages:
     engines: {node: '>=10.13.0'}
     dev: true
 
+  /webpack-virtual-modules@0.5.0:
+    resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
+    dev: true
+
   /webpack@5.88.1(@swc/core@1.3.68)(webpack-cli@5.1.3):
     resolution: {integrity: sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==}
     engines: {node: '>=10.13.0'}
@@ -19052,14 +19190,6 @@ packages:
     dependencies:
       isexe: 2.0.0
 
-  /which@3.0.1:
-    resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==}
-    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
-    hasBin: true
-    dependencies:
-      isexe: 2.0.0
-    dev: true
-
   /wide-align@1.1.5:
     resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
     dependencies: