diff --git a/.config/docker_example.env b/.config/docker_example.env
index 7a0261524b..4fe8e76b78 100644
--- a/.config/docker_example.env
+++ b/.config/docker_example.env
@@ -2,3 +2,4 @@
 POSTGRES_PASSWORD=example-misskey-pass
 POSTGRES_USER=example-misskey-user
 POSTGRES_DB=misskey
+DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}"
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index c5755315fc..d4678ec5e0 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -17,7 +17,7 @@ updates:
   directory: "/"
   schedule:
     interval: daily
-  open-pull-requests-limit: 5
+  open-pull-requests-limit: 10
   # List dependencies required to be updated together, sharing the same version numbers.
   # Those who simply have the common owner (e.g. @fastify) don't need to be listed.
   groups:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7e1ac6a78..474fcad674 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,14 +14,21 @@
 
 ## 202x.x.x (Unreleased)
 
+### General
+- Feat: [mCaptcha](https://github.com/mCaptcha/mCaptcha)のサポートを追加
+- Fix: リストライムラインの「リノートを表示」が正しく機能しない問題を修正
+
 ### Client
+- Feat: 新しいゲームを追加
 - Enhance: ハッシュタグ入力時に、本文の末尾の行に何も書かれていない場合は新たにスペースを追加しないように
+- Fix: ネイティブモードの絵文字がモノクロにならないように
 - Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正
 - Enhance: チャンネルノートのピン留めをノートのメニューからできるよ
 
 ### Server
 - Enhance: 連合先のレートリミットに引っかかった際にリトライするようになりました
 - Enhance: ActivityPub Deliver queueでBodyを事前処理するように (#12916)
+- Enhance: クリップをエクスポートできるように
 
 ## 2023.12.2
 
diff --git a/docker-compose_example.yml b/docker-compose_example.yml
index 60ba4dc8ca..5cebbe4164 100644
--- a/docker-compose_example.yml
+++ b/docker-compose_example.yml
@@ -7,6 +7,7 @@ services:
     links:
       - db
       - redis
+#     - mcaptcha
 #     - meilisearch
     depends_on:
       db:
@@ -48,6 +49,36 @@ services:
       interval: 5s
       retries: 20
 
+#  mcaptcha:
+#    restart: always
+#    image: mcaptcha/mcaptcha:latest
+#    networks:
+#      internal_network:
+#      external_network:
+#        aliases:
+#          - localhost
+#    ports:
+#      - 7493:7493
+#    env_file:
+#      - .config/docker.env
+#    environment:
+#      PORT: 7493
+#      MCAPTCHA_redis_URL: "redis://mcaptcha_redis/"
+#    depends_on:
+#      db:
+#        condition: service_healthy
+#      mcaptcha_redis:
+#        condition: service_healthy
+#
+#  mcaptcha_redis:
+#    image: mcaptcha/cache:latest
+#    networks:
+#      - internal_network
+#    healthcheck:
+#      test: "redis-cli ping"
+#      interval: 5s
+#      retries: 20
+
 #  meilisearch:
 #    restart: always
 #    image: getmeili/meilisearch:v1.3.4
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 3937784153..7c73caaac9 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -382,6 +382,11 @@ export interface Locale {
     "enableHcaptcha": string;
     "hcaptchaSiteKey": string;
     "hcaptchaSecretKey": string;
+    "mcaptcha": string;
+    "enableMcaptcha": string;
+    "mcaptchaSiteKey": string;
+    "mcaptchaSecretKey": string;
+    "mcaptchaInstanceUrl": string;
     "recaptcha": string;
     "enableRecaptcha": string;
     "recaptchaSiteKey": string;
@@ -1187,6 +1192,7 @@ export interface Locale {
     "decorate": string;
     "addMfmFunction": string;
     "enableQuickAddMfmFunction": string;
+    "bubbleGame": string;
     "_announcement": {
         "forExistingUsers": string;
         "forExistingUsersDescription": string;
@@ -1651,6 +1657,15 @@ export interface Locale {
                 "title": string;
                 "description": string;
             };
+            "_bubbleGameExplodingHead": {
+                "title": string;
+                "description": string;
+            };
+            "_bubbleGameDoubleExplodingHead": {
+                "title": string;
+                "description": string;
+                "flavor": string;
+            };
         };
     };
     "_role": {
@@ -2251,6 +2266,7 @@ export interface Locale {
     "_exportOrImport": {
         "allNotes": string;
         "favoritedNotes": string;
+        "clips": string;
         "followingList": string;
         "muteList": string;
         "blockingList": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 77f9a9ec0f..55ff3201f0 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -379,6 +379,11 @@ hcaptcha: "hCaptcha"
 enableHcaptcha: "hCaptchaを有効にする"
 hcaptchaSiteKey: "サイトキー"
 hcaptchaSecretKey: "シークレットキー"
+mcaptcha: "mCaptcha"
+enableMcaptcha: "mCaptchaを有効にする"
+mcaptchaSiteKey: "サイトキー"
+mcaptchaSecretKey: "シークレットキー"
+mcaptchaInstanceUrl: "mCaptchaのインスタンスのURL"
 recaptcha: "reCAPTCHA"
 enableRecaptcha: "reCAPTCHAを有効にする"
 recaptchaSiteKey: "サイトキー"
@@ -1184,6 +1189,7 @@ seasonalScreenEffect: "季節に応じた画面の演出"
 decorate: "デコる"
 addMfmFunction: "装飾を追加"
 enableQuickAddMfmFunction: "高度なMFMのピッカーを表示する"
+bubbleGame: "バブルゲーム"
 
 _announcement:
   forExistingUsers: "既存ユーザーのみ"
@@ -1562,6 +1568,13 @@ _achievements:
     _tutorialCompleted:
       title: "Misskey初心者講座 修了証"
       description: "チュートリアルを完了した"
+    _bubbleGameExplodingHead:
+      title: "🤯"
+      description: "バブルゲームで最も大きいモノを出した"
+    _bubbleGameDoubleExplodingHead:
+      title: "ダブル🤯"
+      description: "バブルゲームで最も大きいモノを2つ同時に出した"
+      flavor: "これくらいの おべんとばこに 🤯 🤯 ちょっとつめて"
 
 _role:
   new: "ロールの作成"
@@ -2154,6 +2167,7 @@ _profile:
 _exportOrImport:
   allNotes: "全てのノート"
   favoritedNotes: "お気に入りにしたノート"
+  clips: "クリップ"
   followingList: "フォロー"
   muteList: "ミュート"
   blockingList: "ブロック"
diff --git a/packages/backend/migration/1704373210054-support-mcaptcha.js b/packages/backend/migration/1704373210054-support-mcaptcha.js
new file mode 100644
index 0000000000..ce42b90716
--- /dev/null
+++ b/packages/backend/migration/1704373210054-support-mcaptcha.js
@@ -0,0 +1,22 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export class SupportMcaptcha1704373210054 {
+    name = 'SupportMcaptcha1704373210054'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "meta" ADD "enableMcaptcha" boolean NOT NULL DEFAULT false`);
+        await queryRunner.query(`ALTER TABLE "meta" ADD "mcaptchaSitekey" character varying(1024)`);
+        await queryRunner.query(`ALTER TABLE "meta" ADD "mcaptchaSecretKey" character varying(1024)`);
+        await queryRunner.query(`ALTER TABLE "meta" ADD "mcaptchaInstanceUrl" character varying(1024)`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "mcaptchaInstanceUrl"`);
+        await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "mcaptchaSecretKey"`);
+        await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "mcaptchaSitekey"`);
+        await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableMcaptcha"`);
+    }
+}
diff --git a/packages/backend/src/GlobalModule.ts b/packages/backend/src/GlobalModule.ts
index 3e9d19f825..c83845b94c 100644
--- a/packages/backend/src/GlobalModule.ts
+++ b/packages/backend/src/GlobalModule.ts
@@ -3,7 +3,6 @@
  * SPDX-License-Identifier: AGPL-3.0-only
  */
 
-import { setTimeout } from 'node:timers/promises';
 import { Global, Inject, Module } from '@nestjs/common';
 import * as Redis from 'ioredis';
 import { DataSource } from 'typeorm';
@@ -12,6 +11,7 @@ import { DI } from './di-symbols.js';
 import { Config, loadConfig } from './config.js';
 import { createPostgresDataSource } from './postgres.js';
 import { RepositoryModule } from './models/RepositoryModule.js';
+import { allSettled } from './misc/promise-tracker.js';
 import type { Provider, OnApplicationShutdown } from '@nestjs/common';
 
 const $config: Provider = {
@@ -33,7 +33,7 @@ const $meilisearch: Provider = {
 	useFactory: (config: Config) => {
 		if (config.meilisearch) {
 			return new MeiliSearch({
-				host: `${config.meilisearch.ssl ? 'https' : 'http' }://${config.meilisearch.host}:${config.meilisearch.port}`,
+				host: `${config.meilisearch.ssl ? 'https' : 'http'}://${config.meilisearch.host}:${config.meilisearch.port}`,
 				apiKey: config.meilisearch.apiKey,
 			});
 		} else {
@@ -91,17 +91,12 @@ export class GlobalModule implements OnApplicationShutdown {
 		@Inject(DI.redisForPub) private redisForPub: Redis.Redis,
 		@Inject(DI.redisForSub) private redisForSub: Redis.Redis,
 		@Inject(DI.redisForTimelines) private redisForTimelines: Redis.Redis,
-	) {}
+	) { }
 
 	public async dispose(): Promise<void> {
-		if (process.env.NODE_ENV === 'test') {
-			// XXX:
-			// Shutting down the existing connections causes errors on Jest as
-			// Misskey has asynchronous postgres/redis connections that are not
-			// awaited.
-			// Let's wait for some random time for them to finish.
-			await setTimeout(5000);
-		}
+		// Wait for all potential DB queries
+		await allSettled();
+		// And then disconnect from DB
 		await Promise.all([
 			this.db.destroy(),
 			this.redisClient.disconnect(),
diff --git a/packages/backend/src/core/AchievementService.ts b/packages/backend/src/core/AchievementService.ts
index 88fc033859..a28b68ee86 100644
--- a/packages/backend/src/core/AchievementService.ts
+++ b/packages/backend/src/core/AchievementService.ts
@@ -87,6 +87,8 @@ export const ACHIEVEMENT_TYPES = [
 	'brainDiver',
 	'smashTestNotificationButton',
 	'tutorialCompleted',
+	'bubbleGameExplodingHead',
+	'bubbleGameDoubleExplodingHead',
 ] as const;
 
 @Injectable()
diff --git a/packages/backend/src/core/CaptchaService.ts b/packages/backend/src/core/CaptchaService.ts
index f64196f4fc..6c5ee4835d 100644
--- a/packages/backend/src/core/CaptchaService.ts
+++ b/packages/backend/src/core/CaptchaService.ts
@@ -73,6 +73,37 @@ export class CaptchaService {
 		}
 	}
 
+	// https://codeberg.org/Gusted/mCaptcha/src/branch/main/mcaptcha.go
+	@bindThis
+	public async verifyMcaptcha(secret: string, siteKey: string, instanceHost: string, response: string | null | undefined): Promise<void> {
+		if (response == null) {
+			throw new Error('mcaptcha-failed: no response provided');
+		}
+
+		const endpointUrl = new URL('/api/v1/pow/siteverify', instanceHost);
+		const result = await this.httpRequestService.send(endpointUrl.toString(), {
+			method: 'POST',
+			body: JSON.stringify({
+				key: siteKey,
+				secret: secret,
+				token: response,
+			}),
+			headers: {
+				'Content-Type': 'application/json',
+			},
+		});
+
+		if (result.status !== 200) {
+			throw new Error('mcaptcha-failed: mcaptcha didn\'t return 200 OK');
+		}
+
+		const resp = (await result.json()) as { valid: boolean };
+
+		if (!resp.valid) {
+			throw new Error('mcaptcha-request-failed');
+		}
+	}
+
 	@bindThis
 	public async verifyTurnstile(secret: string, response: string | null | undefined): Promise<void> {
 		if (response == null) {
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index ed8d51df16..97fb80ab39 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -58,6 +58,7 @@ import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
 import { UtilityService } from '@/core/UtilityService.js';
 import { UserBlockingService } from '@/core/UserBlockingService.js';
 import { isReply } from '@/misc/is-reply.js';
+import { trackPromise } from '@/misc/promise-tracker.js';
 
 type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
 
@@ -676,7 +677,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 						this.relayService.deliverToRelays(user, noteActivity);
 					}
 
-					dm.execute();
+					trackPromise(dm.execute());
 				})();
 			}
 			//#endregion
diff --git a/packages/backend/src/core/NoteReadService.ts b/packages/backend/src/core/NoteReadService.ts
index 03c1735e04..c73cf76592 100644
--- a/packages/backend/src/core/NoteReadService.ts
+++ b/packages/backend/src/core/NoteReadService.ts
@@ -14,6 +14,7 @@ import { IdService } from '@/core/IdService.js';
 import { GlobalEventService } from '@/core/GlobalEventService.js';
 import type { NoteUnreadsRepository, MutingsRepository, NoteThreadMutingsRepository } from '@/models/_.js';
 import { bindThis } from '@/decorators.js';
+import { trackPromise } from '@/misc/promise-tracker.js';
 
 @Injectable()
 export class NoteReadService implements OnApplicationShutdown {
@@ -107,7 +108,7 @@ export class NoteReadService implements OnApplicationShutdown {
 
 			// TODO: ↓まとめてクエリしたい
 
-			this.noteUnreadsRepository.countBy({
+			trackPromise(this.noteUnreadsRepository.countBy({
 				userId: userId,
 				isMentioned: true,
 			}).then(mentionsCount => {
@@ -115,9 +116,9 @@ export class NoteReadService implements OnApplicationShutdown {
 					// 全て既読になったイベントを発行
 					this.globalEventService.publishMainStream(userId, 'readAllUnreadMentions');
 				}
-			});
+			}));
 
-			this.noteUnreadsRepository.countBy({
+			trackPromise(this.noteUnreadsRepository.countBy({
 				userId: userId,
 				isSpecified: true,
 			}).then(specifiedCount => {
@@ -125,7 +126,7 @@ export class NoteReadService implements OnApplicationShutdown {
 					// 全て既読になったイベントを発行
 					this.globalEventService.publishMainStream(userId, 'readAllUnreadSpecifiedNotes');
 				}
-			});
+			}));
 		}
 	}
 
diff --git a/packages/backend/src/core/NotificationService.ts b/packages/backend/src/core/NotificationService.ts
index ad7be83e5b..765fcae063 100644
--- a/packages/backend/src/core/NotificationService.ts
+++ b/packages/backend/src/core/NotificationService.ts
@@ -20,6 +20,7 @@ import { CacheService } from '@/core/CacheService.js';
 import type { Config } from '@/config.js';
 import { UserListService } from '@/core/UserListService.js';
 import type { FilterUnionByProperty } from '@/types.js';
+import { trackPromise } from '@/misc/promise-tracker.js';
 
 @Injectable()
 export class NotificationService implements OnApplicationShutdown {
@@ -74,7 +75,18 @@ export class NotificationService implements OnApplicationShutdown {
 	}
 
 	@bindThis
-	public async createNotification<T extends MiNotification['type']>(
+	public createNotification<T extends MiNotification['type']>(
+		notifieeId: MiUser['id'],
+		type: T,
+		data: Omit<FilterUnionByProperty<MiNotification, 'type', T>, 'type' | 'id' | 'createdAt' | 'notifierId'>,
+		notifierId?: MiUser['id'] | null,
+	) {
+		trackPromise(
+			this.#createNotificationInternal(notifieeId, type, data, notifierId),
+		);
+	}
+
+	async #createNotificationInternal<T extends MiNotification['type']>(
 		notifieeId: MiUser['id'],
 		type: T,
 		data: Omit<FilterUnionByProperty<MiNotification, 'type', T>, 'type' | 'id' | 'createdAt' | 'notifierId'>,
diff --git a/packages/backend/src/core/QueueModule.ts b/packages/backend/src/core/QueueModule.ts
index 4444dc9787..20a53ff282 100644
--- a/packages/backend/src/core/QueueModule.ts
+++ b/packages/backend/src/core/QueueModule.ts
@@ -3,12 +3,12 @@
  * SPDX-License-Identifier: AGPL-3.0-only
  */
 
-import { setTimeout } from 'node:timers/promises';
 import { Inject, Module, OnApplicationShutdown } from '@nestjs/common';
 import * as Bull from 'bullmq';
 import { DI } from '@/di-symbols.js';
 import type { Config } from '@/config.js';
 import { QUEUE, baseQueueOptions } from '@/queue/const.js';
+import { allSettled } from '@/misc/promise-tracker.js';
 import type { Provider } from '@nestjs/common';
 import type { DeliverJobData, InboxJobData, EndedPollNotificationJobData, WebhookDeliverJobData, RelationshipJobData } from '../queue/types.js';
 
@@ -106,14 +106,9 @@ export class QueueModule implements OnApplicationShutdown {
 	) {}
 
 	public async dispose(): Promise<void> {
-		if (process.env.NODE_ENV === 'test') {
-			// XXX:
-			// Shutting down the existing connections causes errors on Jest as
-			// Misskey has asynchronous postgres/redis connections that are not
-			// awaited.
-			// Let's wait for some random time for them to finish.
-			await setTimeout(5000);
-		}
+		// Wait for all potential queue jobs
+		await allSettled();
+		// And then close all queues
 		await Promise.all([
 			this.systemQueue.close(),
 			this.endedPollNotificationQueue.close(),
diff --git a/packages/backend/src/core/QueueService.ts b/packages/backend/src/core/QueueService.ts
index 4f99dee64e..dc3f248da4 100644
--- a/packages/backend/src/core/QueueService.ts
+++ b/packages/backend/src/core/QueueService.ts
@@ -182,6 +182,16 @@ export class QueueService {
 		});
 	}
 
+	@bindThis
+	public createExportClipsJob(user: ThinUser) {
+		return this.dbQueue.add('exportClips', {
+			user: { id: user.id },
+		}, {
+			removeOnComplete: true,
+			removeOnFail: true,
+		});
+	}
+
 	@bindThis
 	public createExportFavoritesJob(user: ThinUser) {
 		return this.dbQueue.add('exportFavorites', {
diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts
index 3ca12551b1..2e8f76fa8a 100644
--- a/packages/backend/src/core/ReactionService.ts
+++ b/packages/backend/src/core/ReactionService.ts
@@ -28,6 +28,7 @@ import { UserBlockingService } from '@/core/UserBlockingService.js';
 import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 import { RoleService } from '@/core/RoleService.js';
 import { FeaturedService } from '@/core/FeaturedService.js';
+import { trackPromise } from '@/misc/promise-tracker.js';
 
 const FALLBACK = '❤';
 const PER_NOTE_REACTION_USER_PAIR_CACHE_MAX = 16;
@@ -268,7 +269,7 @@ export class ReactionService {
 				}
 			}
 
-			dm.execute();
+			trackPromise(dm.execute());
 		}
 		//#endregion
 	}
@@ -316,7 +317,7 @@ export class ReactionService {
 				dm.addDirectRecipe(reactee as MiRemoteUser);
 			}
 			dm.addFollowersRecipe();
-			dm.execute();
+			trackPromise(dm.execute());
 		}
 		//#endregion
 	}
diff --git a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts
index 81003bcf1c..d7414e9c99 100644
--- a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts
+++ b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts
@@ -144,7 +144,7 @@ class DeliverManager {
 		}
 
 		// deliver
-		this.queueService.deliverMany(this.actor, this.activity, inboxes);
+		await this.queueService.deliverMany(this.actor, this.activity, inboxes);
 	}
 }
 
diff --git a/packages/backend/src/daemons/ServerStatsService.ts b/packages/backend/src/daemons/ServerStatsService.ts
index c5ef9b2fa3..4c55acea5a 100644
--- a/packages/backend/src/daemons/ServerStatsService.ts
+++ b/packages/backend/src/daemons/ServerStatsService.ts
@@ -37,7 +37,7 @@ export class ServerStatsService implements OnApplicationShutdown {
 		const log = [] as any[];
 
 		ev.on('requestServerStatsLog', x => {
-			ev.emit(`serverStatsLog:${x.id}`, log.slice(0, x.length ?? 50));
+			ev.emit(`serverStatsLog:${x.id}`, log.slice(0, x.length));
 		});
 
 		const tick = async () => {
diff --git a/packages/backend/src/misc/promise-tracker.ts b/packages/backend/src/misc/promise-tracker.ts
new file mode 100644
index 0000000000..c7166c6de9
--- /dev/null
+++ b/packages/backend/src/misc/promise-tracker.ts
@@ -0,0 +1,23 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+const promiseRefs: Set<WeakRef<Promise<unknown>>> = new Set();
+
+/**
+ * This tracks promises that other modules decided not to wait for,
+ * and makes sure they are all settled before fully closing down the server.
+ */
+export function trackPromise(promise: Promise<unknown>) {
+	if (process.env.NODE_ENV !== 'test') {
+		return;
+	}
+	const ref = new WeakRef(promise);
+	promiseRefs.add(ref);
+	promise.finally(() => promiseRefs.delete(ref));
+}
+
+export async function allSettled(): Promise<void> {
+	await Promise.allSettled([...promiseRefs].map(r => r.deref()));
+}
diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts
index f5a75ed28a..3265e85dd7 100644
--- a/packages/backend/src/models/Meta.ts
+++ b/packages/backend/src/models/Meta.ts
@@ -191,6 +191,29 @@ export class MiMeta {
 	})
 	public hcaptchaSecretKey: string | null;
 
+	@Column('boolean', {
+		default: false,
+	})
+	public enableMcaptcha: boolean;
+
+	@Column('varchar', {
+		length: 1024,
+		nullable: true,
+	})
+	public mcaptchaSitekey: string | null;
+
+	@Column('varchar', {
+		length: 1024,
+		nullable: true,
+	})
+	public mcaptchaSecretKey: string | null;
+
+	@Column('varchar', {
+		length: 1024,
+		nullable: true,
+	})
+	public mcaptchaInstanceUrl: string | null;
+
 	@Column('boolean', {
 		default: false,
 	})
@@ -467,7 +490,7 @@ export class MiMeta {
 		nullable: true,
 	})
 	public truemailInstance: string | null;
-	
+
 	@Column('varchar', {
 		length: 1024,
 		nullable: true,
diff --git a/packages/backend/src/queue/QueueProcessorModule.ts b/packages/backend/src/queue/QueueProcessorModule.ts
index e6327002c5..9c52c7d76a 100644
--- a/packages/backend/src/queue/QueueProcessorModule.ts
+++ b/packages/backend/src/queue/QueueProcessorModule.ts
@@ -24,6 +24,7 @@ import { ExportCustomEmojisProcessorService } from './processors/ExportCustomEmo
 import { ExportFollowingProcessorService } from './processors/ExportFollowingProcessorService.js';
 import { ExportMutingProcessorService } from './processors/ExportMutingProcessorService.js';
 import { ExportNotesProcessorService } from './processors/ExportNotesProcessorService.js';
+import { ExportClipsProcessorService } from './processors/ExportClipsProcessorService.js';
 import { ExportUserListsProcessorService } from './processors/ExportUserListsProcessorService.js';
 import { ExportAntennasProcessorService } from './processors/ExportAntennasProcessorService.js';
 import { ImportBlockingProcessorService } from './processors/ImportBlockingProcessorService.js';
@@ -53,6 +54,7 @@ import { RelationshipProcessorService } from './processors/RelationshipProcessor
 		DeleteDriveFilesProcessorService,
 		ExportCustomEmojisProcessorService,
 		ExportNotesProcessorService,
+		ExportClipsProcessorService,
 		ExportFavoritesProcessorService,
 		ExportFollowingProcessorService,
 		ExportMutingProcessorService,
diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts
index b872dd65f7..bcc1a69f80 100644
--- a/packages/backend/src/queue/QueueProcessorService.ts
+++ b/packages/backend/src/queue/QueueProcessorService.ts
@@ -16,6 +16,7 @@ import { InboxProcessorService } from './processors/InboxProcessorService.js';
 import { DeleteDriveFilesProcessorService } from './processors/DeleteDriveFilesProcessorService.js';
 import { ExportCustomEmojisProcessorService } from './processors/ExportCustomEmojisProcessorService.js';
 import { ExportNotesProcessorService } from './processors/ExportNotesProcessorService.js';
+import { ExportClipsProcessorService } from './processors/ExportClipsProcessorService.js';
 import { ExportFollowingProcessorService } from './processors/ExportFollowingProcessorService.js';
 import { ExportMutingProcessorService } from './processors/ExportMutingProcessorService.js';
 import { ExportBlockingProcessorService } from './processors/ExportBlockingProcessorService.js';
@@ -91,6 +92,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
 		private deleteDriveFilesProcessorService: DeleteDriveFilesProcessorService,
 		private exportCustomEmojisProcessorService: ExportCustomEmojisProcessorService,
 		private exportNotesProcessorService: ExportNotesProcessorService,
+		private exportClipsProcessorService: ExportClipsProcessorService,
 		private exportFavoritesProcessorService: ExportFavoritesProcessorService,
 		private exportFollowingProcessorService: ExportFollowingProcessorService,
 		private exportMutingProcessorService: ExportMutingProcessorService,
@@ -164,6 +166,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
 				case 'deleteDriveFiles': return this.deleteDriveFilesProcessorService.process(job);
 				case 'exportCustomEmojis': return this.exportCustomEmojisProcessorService.process(job);
 				case 'exportNotes': return this.exportNotesProcessorService.process(job);
+				case 'exportClips': return this.exportClipsProcessorService.process(job);
 				case 'exportFavorites': return this.exportFavoritesProcessorService.process(job);
 				case 'exportFollowing': return this.exportFollowingProcessorService.process(job);
 				case 'exportMuting': return this.exportMutingProcessorService.process(job);
diff --git a/packages/backend/src/queue/processors/ExportClipsProcessorService.ts b/packages/backend/src/queue/processors/ExportClipsProcessorService.ts
new file mode 100644
index 0000000000..5221497bd3
--- /dev/null
+++ b/packages/backend/src/queue/processors/ExportClipsProcessorService.ts
@@ -0,0 +1,206 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import * as fs from 'node:fs';
+import { Writable } from 'node:stream';
+import { Inject, Injectable, StreamableFile } from '@nestjs/common';
+import { MoreThan } from 'typeorm';
+import { format as dateFormat } from 'date-fns';
+import { DI } from '@/di-symbols.js';
+import type { ClipNotesRepository, ClipsRepository, MiClip, MiClipNote, MiUser, NotesRepository, PollsRepository, UsersRepository } from '@/models/_.js';
+import type Logger from '@/logger.js';
+import { DriveService } from '@/core/DriveService.js';
+import { createTemp } from '@/misc/create-temp.js';
+import type { MiPoll } from '@/models/Poll.js';
+import type { MiNote } from '@/models/Note.js';
+import { bindThis } from '@/decorators.js';
+import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
+import { Packed } from '@/misc/json-schema.js';
+import { IdService } from '@/core/IdService.js';
+import { QueueLoggerService } from '../QueueLoggerService.js';
+import type * as Bull from 'bullmq';
+import type { DbJobDataWithUser } from '../types.js';
+
+@Injectable()
+export class ExportClipsProcessorService {
+	private logger: Logger;
+
+	constructor(
+		@Inject(DI.usersRepository)
+		private usersRepository: UsersRepository,
+
+		@Inject(DI.pollsRepository)
+		private pollsRepository: PollsRepository,
+
+		@Inject(DI.clipsRepository)
+		private clipsRepository: ClipsRepository,
+
+		@Inject(DI.clipNotesRepository)
+		private clipNotesRepository: ClipNotesRepository,
+
+		private driveService: DriveService,
+		private queueLoggerService: QueueLoggerService,
+		private idService: IdService,
+	) {
+		this.logger = this.queueLoggerService.logger.createSubLogger('export-clips');
+	}
+
+	@bindThis
+	public async process(job: Bull.Job<DbJobDataWithUser>): Promise<void> {
+		this.logger.info(`Exporting clips of ${job.data.user.id} ...`);
+
+		const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
+		if (user == null) {
+			return;
+		}
+
+		// Create temp file
+		const [path, cleanup] = await createTemp();
+
+		this.logger.info(`Temp file is ${path}`);
+
+		try {
+			const stream = Writable.toWeb(fs.createWriteStream(path, { flags: 'a' }));
+			const writer = stream.getWriter();
+			writer.closed.catch(this.logger.error);
+
+			await writer.write('[');
+
+			await this.processClips(writer, user, job);
+
+			await writer.write(']');
+			await writer.close();
+
+			this.logger.succ(`Exported to: ${path}`);
+
+			const fileName = 'clips-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.json';
+			const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'json' });
+
+			this.logger.succ(`Exported to: ${driveFile.id}`);
+		} finally {
+			cleanup();
+		}
+	}
+
+	async processClips(writer: WritableStreamDefaultWriter, user: MiUser, job: Bull.Job<DbJobDataWithUser>) {
+		let exportedClipsCount = 0;
+		let cursor: MiClip['id'] | null = null;
+
+		while (true) {
+			const clips = await this.clipsRepository.find({
+				where: {
+					userId: user.id,
+					...(cursor ? { id: MoreThan(cursor) } : {}),
+				},
+				take: 100,
+				order: {
+					id: 1,
+				},
+			});
+
+			if (clips.length === 0) {
+				job.updateProgress(100);
+				break;
+			}
+
+			cursor = clips.at(-1)?.id ?? null;
+
+			for (const clip of clips) {
+				// Stringify but remove the last `]}`
+				const content = JSON.stringify(this.serializeClip(clip)).slice(0, -2);
+				const isFirst = exportedClipsCount === 0;
+				await writer.write(isFirst ? content : ',\n' + content);
+
+				await this.processClipNotes(writer, clip.id);
+
+				await writer.write(']}');
+				exportedClipsCount++;
+			}
+
+			const total = await this.clipsRepository.countBy({
+				userId: user.id,
+			});
+
+			job.updateProgress(exportedClipsCount / total);
+		}
+	}
+
+	async processClipNotes(writer: WritableStreamDefaultWriter, clipId: string): Promise<void> {
+		let exportedClipNotesCount = 0;
+		let cursor: MiClipNote['id'] | null = null;
+
+		while (true) {
+			const clipNotes = await this.clipNotesRepository.find({
+				where: {
+					clipId,
+					...(cursor ? { id: MoreThan(cursor) } : {}),
+				},
+				take: 100,
+				order: {
+					id: 1,
+				},
+				relations: ['note', 'note.user'],
+			}) as (MiClipNote & { note: MiNote & { user: MiUser } })[];
+
+			if (clipNotes.length === 0) {
+				break;
+			}
+
+			cursor = clipNotes.at(-1)?.id ?? null;
+
+			for (const clipNote of clipNotes) {
+				let poll: MiPoll | undefined;
+				if (clipNote.note.hasPoll) {
+					poll = await this.pollsRepository.findOneByOrFail({ noteId: clipNote.note.id });
+				}
+				const content = JSON.stringify(this.serializeClipNote(clipNote, poll));
+				const isFirst = exportedClipNotesCount === 0;
+				await writer.write(isFirst ? content : ',\n' + content);
+
+				exportedClipNotesCount++;
+			}
+		}
+	}
+
+	private serializeClip(clip: MiClip): Record<string, unknown> {
+		return {
+			id: clip.id,
+			name: clip.name,
+			description: clip.description,
+			lastClippedAt: clip.lastClippedAt?.toISOString(),
+			clipNotes: [],
+		};
+	}
+
+	private serializeClipNote(clip: MiClipNote & { note: MiNote & { user: MiUser } }, poll: MiPoll | undefined): Record<string, unknown> {
+		return {
+			id: clip.id,
+			createdAt: this.idService.parse(clip.id).date.toISOString(),
+			note: {
+				id: clip.note.id,
+				text: clip.note.text,
+				createdAt: this.idService.parse(clip.note.id).date.toISOString(),
+				fileIds: clip.note.fileIds,
+				replyId: clip.note.replyId,
+				renoteId: clip.note.renoteId,
+				poll: poll,
+				cw: clip.note.cw,
+				visibility: clip.note.visibility,
+				visibleUserIds: clip.note.visibleUserIds,
+				localOnly: clip.note.localOnly,
+				reactionAcceptance: clip.note.reactionAcceptance,
+				uri: clip.note.uri,
+				url: clip.note.url,
+				user: {
+					id: clip.note.user.id,
+					name: clip.note.user.name,
+					username: clip.note.user.username,
+					host: clip.note.user.host,
+					uri: clip.note.user.uri,
+				},
+			},
+		};
+	}
+}
diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts
index 86a64d7121..a3a9805444 100644
--- a/packages/backend/src/server/api/EndpointsModule.ts
+++ b/packages/backend/src/server/api/EndpointsModule.ts
@@ -208,6 +208,7 @@ import * as ep___i_exportBlocking from './endpoints/i/export-blocking.js';
 import * as ep___i_exportFollowing from './endpoints/i/export-following.js';
 import * as ep___i_exportMute from './endpoints/i/export-mute.js';
 import * as ep___i_exportNotes from './endpoints/i/export-notes.js';
+import * as ep___i_exportClips from './endpoints/i/export-clips.js';
 import * as ep___i_exportFavorites from './endpoints/i/export-favorites.js';
 import * as ep___i_exportUserLists from './endpoints/i/export-user-lists.js';
 import * as ep___i_exportAntennas from './endpoints/i/export-antennas.js';
@@ -569,6 +570,7 @@ const $i_exportBlocking: Provider = { provide: 'ep:i/export-blocking', useClass:
 const $i_exportFollowing: Provider = { provide: 'ep:i/export-following', useClass: ep___i_exportFollowing.default };
 const $i_exportMute: Provider = { provide: 'ep:i/export-mute', useClass: ep___i_exportMute.default };
 const $i_exportNotes: Provider = { provide: 'ep:i/export-notes', useClass: ep___i_exportNotes.default };
+const $i_exportClips: Provider = { provide: 'ep:i/export-clips', useClass: ep___i_exportClips.default };
 const $i_exportFavorites: Provider = { provide: 'ep:i/export-favorites', useClass: ep___i_exportFavorites.default };
 const $i_exportUserLists: Provider = { provide: 'ep:i/export-user-lists', useClass: ep___i_exportUserLists.default };
 const $i_exportAntennas: Provider = { provide: 'ep:i/export-antennas', useClass: ep___i_exportAntennas.default };
@@ -934,6 +936,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
 		$i_exportFollowing,
 		$i_exportMute,
 		$i_exportNotes,
+		$i_exportClips,
 		$i_exportFavorites,
 		$i_exportUserLists,
 		$i_exportAntennas,
@@ -1293,6 +1296,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
 		$i_exportFollowing,
 		$i_exportMute,
 		$i_exportNotes,
+		$i_exportClips,
 		$i_exportFavorites,
 		$i_exportUserLists,
 		$i_exportAntennas,
diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts
index 753984ef52..6b4d9d9f70 100644
--- a/packages/backend/src/server/api/SignupApiService.ts
+++ b/packages/backend/src/server/api/SignupApiService.ts
@@ -65,6 +65,7 @@ export class SignupApiService {
 				'hcaptcha-response'?: string;
 				'g-recaptcha-response'?: string;
 				'turnstile-response'?: string;
+				'm-captcha-response'?: string;
 			}
 		}>,
 		reply: FastifyReply,
@@ -82,6 +83,12 @@ export class SignupApiService {
 				});
 			}
 
+			if (instance.enableMcaptcha && instance.mcaptchaSecretKey && instance.mcaptchaSitekey && instance.mcaptchaInstanceUrl) {
+				await this.captchaService.verifyMcaptcha(instance.mcaptchaSecretKey, instance.mcaptchaSitekey, instance.mcaptchaInstanceUrl, body['m-captcha-response']).catch(err => {
+					throw new FastifyReplyError(400, err);
+				});
+			}
+
 			if (instance.enableRecaptcha && instance.recaptchaSecretKey) {
 				await this.captchaService.verifyRecaptcha(instance.recaptchaSecretKey, body['g-recaptcha-response']).catch(err => {
 					throw new FastifyReplyError(400, err);
diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts
index 41232091c6..bd8aa4af72 100644
--- a/packages/backend/src/server/api/endpoints.ts
+++ b/packages/backend/src/server/api/endpoints.ts
@@ -3,8 +3,8 @@
  * SPDX-License-Identifier: AGPL-3.0-only
  */
 
-import type { Schema } from '@/misc/json-schema.js';
 import { permissions } from 'misskey-js';
+import type { Schema } from '@/misc/json-schema.js';
 import { RolePolicies } from '@/core/RoleService.js';
 
 import * as ep___admin_meta from './endpoints/admin/meta.js';
@@ -209,6 +209,7 @@ import * as ep___i_exportBlocking from './endpoints/i/export-blocking.js';
 import * as ep___i_exportFollowing from './endpoints/i/export-following.js';
 import * as ep___i_exportMute from './endpoints/i/export-mute.js';
 import * as ep___i_exportNotes from './endpoints/i/export-notes.js';
+import * as ep___i_exportClips from './endpoints/i/export-clips.js';
 import * as ep___i_exportFavorites from './endpoints/i/export-favorites.js';
 import * as ep___i_exportUserLists from './endpoints/i/export-user-lists.js';
 import * as ep___i_exportAntennas from './endpoints/i/export-antennas.js';
@@ -568,6 +569,7 @@ const eps = [
 	['i/export-following', ep___i_exportFollowing],
 	['i/export-mute', ep___i_exportMute],
 	['i/export-notes', ep___i_exportNotes],
+	['i/export-clips', ep___i_exportClips],
 	['i/export-favorites', ep___i_exportFavorites],
 	['i/export-user-lists', ep___i_exportUserLists],
 	['i/export-antennas', ep___i_exportAntennas],
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts
index 281f6c484c..0627c5055c 100644
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/meta.ts
@@ -41,6 +41,18 @@ export const meta = {
 				type: 'string',
 				optional: false, nullable: true,
 			},
+			enableMcaptcha: {
+				type: 'boolean',
+				optional: false, nullable: false,
+			},
+			mcaptchaSiteKey: {
+				type: 'string',
+				optional: false, nullable: true,
+			},
+			mcaptchaInstanceUrl: {
+				type: 'string',
+				optional: false, nullable: true,
+			},
 			enableRecaptcha: {
 				type: 'boolean',
 				optional: false, nullable: false,
@@ -163,6 +175,10 @@ export const meta = {
 				type: 'string',
 				optional: false, nullable: true,
 			},
+			mcaptchaSecretKey: {
+				type: 'string',
+				optional: false, nullable: true,
+			},
 			recaptchaSecretKey: {
 				type: 'string',
 				optional: false, nullable: true,
@@ -468,6 +484,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				emailRequiredForSignup: instance.emailRequiredForSignup,
 				enableHcaptcha: instance.enableHcaptcha,
 				hcaptchaSiteKey: instance.hcaptchaSiteKey,
+				enableMcaptcha: instance.enableMcaptcha,
+				mcaptchaSiteKey: instance.mcaptchaSitekey,
+				mcaptchaInstanceUrl: instance.mcaptchaInstanceUrl,
 				enableRecaptcha: instance.enableRecaptcha,
 				recaptchaSiteKey: instance.recaptchaSiteKey,
 				enableTurnstile: instance.enableTurnstile,
@@ -498,6 +517,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				sensitiveWords: instance.sensitiveWords,
 				preservedUsernames: instance.preservedUsernames,
 				hcaptchaSecretKey: instance.hcaptchaSecretKey,
+				mcaptchaSecretKey: instance.mcaptchaSecretKey,
 				recaptchaSecretKey: instance.recaptchaSecretKey,
 				turnstileSecretKey: instance.turnstileSecretKey,
 				sensitiveMediaDetection: instance.sensitiveMediaDetection,
diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
index 3a6426435d..d76d3dfeea 100644
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
@@ -63,6 +63,10 @@ export const paramDef = {
 		enableHcaptcha: { type: 'boolean' },
 		hcaptchaSiteKey: { type: 'string', nullable: true },
 		hcaptchaSecretKey: { type: 'string', nullable: true },
+		enableMcaptcha: { type: 'boolean' },
+		mcaptchaSiteKey: { type: 'string', nullable: true },
+		mcaptchaInstanceUrl: { type: 'string', nullable: true },
+		mcaptchaSecretKey: { type: 'string', nullable: true },
 		enableRecaptcha: { type: 'boolean' },
 		recaptchaSiteKey: { type: 'string', nullable: true },
 		recaptchaSecretKey: { type: 'string', nullable: true },
@@ -269,6 +273,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				set.hcaptchaSecretKey = ps.hcaptchaSecretKey;
 			}
 
+			if (ps.enableMcaptcha !== undefined) {
+				set.enableMcaptcha = ps.enableMcaptcha;
+			}
+
+			if (ps.mcaptchaSiteKey !== undefined) {
+				set.mcaptchaSitekey = ps.mcaptchaSiteKey;
+			}
+
+			if (ps.mcaptchaInstanceUrl !== undefined) {
+				set.mcaptchaInstanceUrl = ps.mcaptchaInstanceUrl;
+			}
+
+			if (ps.mcaptchaSecretKey !== undefined) {
+				set.mcaptchaSecretKey = ps.mcaptchaSecretKey;
+			}
+
 			if (ps.enableRecaptcha !== undefined) {
 				set.enableRecaptcha = ps.enableRecaptcha;
 			}
@@ -472,7 +492,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 					set.verifymailAuthKey = ps.verifymailAuthKey;
 				}
 			}
-			
+
 			if (ps.enableTruemailApi !== undefined) {
 				set.enableTruemailApi = ps.enableTruemailApi;
 			}
diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts
index 0bf2688b4a..7293c2e39b 100644
--- a/packages/backend/src/server/api/endpoints/antennas/notes.ts
+++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts
@@ -14,6 +14,7 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
 import { IdService } from '@/core/IdService.js';
 import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
 import { GlobalEventService } from '@/core/GlobalEventService.js';
+import { trackPromise } from '@/misc/promise-tracker.js';
 import { ApiError } from '../../error.js';
 
 export const meta = {
@@ -92,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 
 			antenna.isActive = true;
 			antenna.lastUsedAt = new Date();
-			this.antennasRepository.update(antenna.id, antenna);
+			trackPromise(this.antennasRepository.update(antenna.id, antenna));
 
 			if (needPublishEvent) {
 				this.globalEventService.publishInternalEvent('antennaUpdated', antenna);
diff --git a/packages/backend/src/server/api/endpoints/i/export-clips.ts b/packages/backend/src/server/api/endpoints/i/export-clips.ts
new file mode 100644
index 0000000000..9435a2b23c
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/i/export-clips.ts
@@ -0,0 +1,35 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Injectable } from '@nestjs/common';
+import ms from 'ms';
+import { Endpoint } from '@/server/api/endpoint-base.js';
+import { QueueService } from '@/core/QueueService.js';
+
+export const meta = {
+	secure: true,
+	requireCredential: true,
+	limit: {
+		duration: ms('1day'),
+		max: 1,
+	},
+} as const;
+
+export const paramDef = {
+	type: 'object',
+	properties: {},
+	required: [],
+} as const;
+
+@Injectable()
+export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
+	constructor(
+		private queueService: QueueService,
+	) {
+		super(meta, paramDef, async (ps, me) => {
+			this.queueService.createExportClipsJob(me);
+		});
+	}
+}
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index f7c2962bc2..529e82678d 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -108,6 +108,18 @@ export const meta = {
 				type: 'string',
 				optional: false, nullable: true,
 			},
+			enableMcaptcha: {
+				type: 'boolean',
+				optional: false, nullable: false,
+			},
+			mcaptchaSiteKey: {
+				type: 'string',
+				optional: false, nullable: true,
+			},
+			mcaptchaInstanceUrl: {
+				type: 'string',
+				optional: false, nullable: true,
+			},
 			enableRecaptcha: {
 				type: 'boolean',
 				optional: false, nullable: false,
@@ -351,6 +363,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				emailRequiredForSignup: instance.emailRequiredForSignup,
 				enableHcaptcha: instance.enableHcaptcha,
 				hcaptchaSiteKey: instance.hcaptchaSiteKey,
+				enableMcaptcha: instance.enableMcaptcha,
+				mcaptchaSiteKey: instance.mcaptchaSitekey,
+				mcaptchaInstanceUrl: instance.mcaptchaInstanceUrl,
 				enableRecaptcha: instance.enableRecaptcha,
 				recaptchaSiteKey: instance.recaptchaSiteKey,
 				enableTurnstile: instance.enableTurnstile,
diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts
index 909b5a5e03..e0245814c4 100644
--- a/packages/backend/src/server/api/stream/channels/user-list.ts
+++ b/packages/backend/src/server/api/stream/channels/user-list.ts
@@ -21,6 +21,7 @@ class UserListChannel extends Channel {
 	private membershipsMap: Record<string, Pick<MiUserListMembership, 'withReplies'> | undefined> = {};
 	private listUsersClock: NodeJS.Timeout;
 	private withFiles: boolean;
+	private withRenotes: boolean;
 
 	constructor(
 		private userListsRepository: UserListsRepository,
@@ -39,6 +40,7 @@ class UserListChannel extends Channel {
 	public async init(params: any) {
 		this.listId = params.listId as string;
 		this.withFiles = params.withFiles ?? false;
+		this.withRenotes = params.withRenotes ?? true;
 
 		// Check existence and owner
 		const listExist = await this.userListsRepository.exist({
@@ -104,6 +106,8 @@ class UserListChannel extends Channel {
 			}
 		}
 
+		if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return;
+
 		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
diff --git a/packages/backend/test/e2e/exports.ts b/packages/backend/test/e2e/exports.ts
new file mode 100644
index 0000000000..9686f2b7fd
--- /dev/null
+++ b/packages/backend/test/e2e/exports.ts
@@ -0,0 +1,194 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+process.env.NODE_ENV = 'test';
+
+import * as assert from 'assert';
+import { signup, api, startServer, startJobQueue, port, post } from '../utils.js';
+import type { INestApplicationContext } from '@nestjs/common';
+import type * as misskey from 'misskey-js';
+
+describe('export-clips', () => {
+	let app: INestApplicationContext;
+	let alice: misskey.entities.SignupResponse;
+	let bob: misskey.entities.SignupResponse;
+
+	// XXX: Any better way to get the result?
+	async function pollFirstDriveFile() {
+		while (true) {
+			const files = (await api('/drive/files', {}, alice)).body;
+			if (!files.length) {
+				await new Promise(r => setTimeout(r, 100));
+				continue;
+			}
+			if (files.length > 1) {
+				throw new Error('Too many files?');
+			}
+			const file = (await api('/drive/files/show', { fileId: files[0].id }, alice)).body;
+			const res = await fetch(new URL(new URL(file.url).pathname, `http://127.0.0.1:${port}`));
+			return await res.json();
+		}
+	}
+
+	beforeAll(async () => {
+		app = await startServer();
+		await startJobQueue();
+		alice = await signup({ username: 'alice' });
+		bob = await signup({ username: 'bob' });
+	}, 1000 * 60 * 2);
+
+	afterAll(async () => {
+		await app.close();
+	});
+
+	beforeEach(async () => {
+		// Clean all clips and files of alice
+		const clips = (await api('/clips/list', {}, alice)).body;
+		for (const clip of clips) {
+			const res = await api('/clips/delete', { clipId: clip.id }, alice);
+			if (res.status !== 204) {
+				throw new Error('Failed to delete clip');
+			}
+		}
+		const files = (await api('/drive/files', {}, alice)).body;
+		for (const file of files) {
+			const res = await api('/drive/files/delete', { fileId: file.id }, alice);
+			if (res.status !== 204) {
+				throw new Error('Failed to delete file');
+			}
+		}
+	});
+
+	test('basic export', async () => {
+		let res = await api('/clips/create', {
+			name: 'foo',
+			description: 'bar',
+		}, alice);
+		assert.strictEqual(res.status, 200);
+
+		res = await api('/i/export-clips', {}, alice);
+		assert.strictEqual(res.status, 204);
+
+		const exported = await pollFirstDriveFile();
+		assert.strictEqual(exported[0].name, 'foo');
+		assert.strictEqual(exported[0].description, 'bar');
+		assert.strictEqual(exported[0].clipNotes.length, 0);
+	});
+
+	test('export with notes', async () => {
+		let res = await api('/clips/create', {
+			name: 'foo',
+			description: 'bar',
+		}, alice);
+		assert.strictEqual(res.status, 200);
+		const clip = res.body;
+
+		const note1 = await post(alice, {
+			text: 'baz1',
+		});
+
+		const note2 = await post(alice, {
+			text: 'baz2',
+			poll: {
+				choices: ['sakura', 'izumi', 'ako'],
+			},
+		});
+
+		for (const note of [note1, note2]) {
+			res = await api('/clips/add-note', {
+				clipId: clip.id,
+				noteId: note.id,
+			}, alice);
+			assert.strictEqual(res.status, 204);
+		}
+
+		res = await api('/i/export-clips', {}, alice);
+		assert.strictEqual(res.status, 204);
+
+		const exported = await pollFirstDriveFile();
+		assert.strictEqual(exported[0].name, 'foo');
+		assert.strictEqual(exported[0].description, 'bar');
+		assert.strictEqual(exported[0].clipNotes.length, 2);
+		assert.strictEqual(exported[0].clipNotes[0].note.text, 'baz1');
+		assert.strictEqual(exported[0].clipNotes[1].note.text, 'baz2');
+		assert.deepStrictEqual(exported[0].clipNotes[1].note.poll.choices[0], 'sakura');
+	});
+
+	test('multiple clips', async () => {
+		let res = await api('/clips/create', {
+			name: 'kawaii',
+			description: 'kawaii',
+		}, alice);
+		assert.strictEqual(res.status, 200);
+		const clip1 = res.body;
+
+		res = await api('/clips/create', {
+			name: 'yuri',
+			description: 'yuri',
+		}, alice);
+		assert.strictEqual(res.status, 200);
+		const clip2 = res.body;
+
+		const note1 = await post(alice, {
+			text: 'baz1',
+		});
+
+		const note2 = await post(alice, {
+			text: 'baz2',
+		});
+
+		res = await api('/clips/add-note', {
+			clipId: clip1.id,
+			noteId: note1.id,
+		}, alice);
+		assert.strictEqual(res.status, 204);
+
+		res = await api('/clips/add-note', {
+			clipId: clip2.id,
+			noteId: note2.id,
+		}, alice);
+		assert.strictEqual(res.status, 204);
+
+		res = await api('/i/export-clips', {}, alice);
+		assert.strictEqual(res.status, 204);
+
+		const exported = await pollFirstDriveFile();
+		assert.strictEqual(exported[0].name, 'kawaii');
+		assert.strictEqual(exported[0].clipNotes.length, 1);
+		assert.strictEqual(exported[0].clipNotes[0].note.text, 'baz1');
+		assert.strictEqual(exported[1].name, 'yuri');
+		assert.strictEqual(exported[1].clipNotes.length, 1);
+		assert.strictEqual(exported[1].clipNotes[0].note.text, 'baz2');
+	});
+
+	test('Clipping other user\'s note', async () => {
+		let res = await api('/clips/create', {
+			name: 'kawaii',
+			description: 'kawaii',
+		}, alice);
+		assert.strictEqual(res.status, 200);
+		const clip = res.body;
+
+		const note = await post(bob, {
+			text: 'baz',
+			visibility: 'followers',
+		});
+
+		res = await api('/clips/add-note', {
+			clipId: clip.id,
+			noteId: note.id,
+		}, alice);
+		assert.strictEqual(res.status, 204);
+
+		res = await api('/i/export-clips', {}, alice);
+		assert.strictEqual(res.status, 204);
+
+		const exported = await pollFirstDriveFile();
+		assert.strictEqual(exported[0].name, 'kawaii');
+		assert.strictEqual(exported[0].clipNotes.length, 1);
+		assert.strictEqual(exported[0].clipNotes[0].note.text, 'baz');
+		assert.strictEqual(exported[0].clipNotes[0].note.user.username, 'bob');
+	});
+});
diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts
index 46b8ea9cdd..7c9428d476 100644
--- a/packages/backend/test/utils.ts
+++ b/packages/backend/test/utils.ts
@@ -17,7 +17,7 @@ import { entities } from '../src/postgres.js';
 import { loadConfig } from '../src/config.js';
 import type * as misskey from 'misskey-js';
 
-export { server as startServer } from '@/boot/common.js';
+export { server as startServer, jobQueue as startJobQueue } from '@/boot/common.js';
 
 interface UserToken {
 	token: string;
diff --git a/packages/frontend/assets/drop-and-fusion/bgm_1.mp3 b/packages/frontend/assets/drop-and-fusion/bgm_1.mp3
new file mode 100644
index 0000000000..cafc34ad9c
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/bgm_1.mp3 differ
diff --git a/packages/frontend/assets/drop-and-fusion/bubble2.mp3 b/packages/frontend/assets/drop-and-fusion/bubble2.mp3
new file mode 100644
index 0000000000..8b4f8df6e9
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/bubble2.mp3 differ
diff --git a/packages/frontend/assets/drop-and-fusion/cold_face.png b/packages/frontend/assets/drop-and-fusion/cold_face.png
new file mode 100644
index 0000000000..f5f53e9efc
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/cold_face.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/drop-arrow.svg b/packages/frontend/assets/drop-and-fusion/drop-arrow.svg
new file mode 100644
index 0000000000..f98bb8a1ac
--- /dev/null
+++ b/packages/frontend/assets/drop-and-fusion/drop-arrow.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
+    <path d="M0,0L128,0L64,64L0,0Z" style="fill:rgb(255,61,0);"/>
+    <path d="M0,0L128,0L64,64L0,0ZM28.971,12L64,47.029C64,47.029 99.029,12 99.029,12L28.971,12Z" style="fill:rgb(255,122,0);"/>
+</svg>
diff --git a/packages/frontend/assets/drop-and-fusion/dropper.png b/packages/frontend/assets/drop-and-fusion/dropper.png
new file mode 100644
index 0000000000..f4300aa5c0
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/dropper.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/exploding_head.png b/packages/frontend/assets/drop-and-fusion/exploding_head.png
new file mode 100644
index 0000000000..e8ec5182c8
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/exploding_head.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/face_with_open_mouth.png b/packages/frontend/assets/drop-and-fusion/face_with_open_mouth.png
new file mode 100644
index 0000000000..c523020f62
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/face_with_open_mouth.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/face_with_symbols_on_mouth.png b/packages/frontend/assets/drop-and-fusion/face_with_symbols_on_mouth.png
new file mode 100644
index 0000000000..db9e839c84
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/face_with_symbols_on_mouth.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/frame-dark.svg b/packages/frontend/assets/drop-and-fusion/frame-dark.svg
new file mode 100644
index 0000000000..3fa7c0da81
--- /dev/null
+++ b/packages/frontend/assets/drop-and-fusion/frame-dark.svg
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 450 600" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g>
+        <g transform="matrix(0.944444,0,0,0.8125,12.5,100)">
+            <rect x="0" y="0" width="450" height="600"/>
+        </g>
+        <g transform="matrix(0.944444,0,0,0.8125,12.5,100)">
+            <rect x="0" y="0" width="450" height="600" style="fill:rgb(255,147,2);fill-opacity:0.15;"/>
+        </g>
+        <use xlink:href="#_Image1" x="0" y="49.048" width="450px" height="551px"/>
+    </g>
+    <g transform="matrix(0.755719,0.654896,-0.654896,0.755719,383.517,-217.265)">
+        <g transform="matrix(0.755719,-0.654896,0.654896,0.755719,-147.545,415.355)">
+            <use xlink:href="#_Image2" x="0" y="49" width="450px" height="551px"/>
+        </g>
+    </g>
+    <use xlink:href="#_Image3" x="25" y="99.5" width="400px" height="475px"/>
+    <g transform="matrix(1,0,0,2,1.13687e-13,25)">
+        <rect x="25" y="37.5" width="400" height="12.5" style="fill:url(#_Linear4);"/>
+    </g>
+    <defs>
+        <image id="_Image1" width="450px" height="551px" xlink:href="data:image/png;base64,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CSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCp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"/>
+        <image id="_Image2" width="450px" height="551px" xlink:href="data:image/png;base64,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"/>
+        <image id="_Image3" width="400px" height="475px" xlink:href="data:image/png;base64,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"/>
+        <linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(7.65404e-16,12.5,-0.390625,2.39189e-17,225,37.5)"><stop offset="0" style="stop-color:rgb(255,14,0);stop-opacity:0.5"/><stop offset="1" style="stop-color:rgb(255,13,0);stop-opacity:0"/></linearGradient>
+    </defs>
+</svg>
diff --git a/packages/frontend/assets/drop-and-fusion/frame-light.svg b/packages/frontend/assets/drop-and-fusion/frame-light.svg
new file mode 100644
index 0000000000..6052ccbaa0
--- /dev/null
+++ b/packages/frontend/assets/drop-and-fusion/frame-light.svg
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 450 600" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
+    <g>
+        <g transform="matrix(0.944444,0,0,0.8125,12.5,100)">
+            <rect x="0" y="0" width="450" height="600" style="fill:white;"/>
+        </g>
+        <g transform="matrix(0.944444,0,0,0.8125,12.5,100)">
+            <rect x="0" y="0" width="450" height="600" style="fill:rgb(255,147,2);fill-opacity:0.15;"/>
+        </g>
+        <use xlink:href="#_Image1" x="0" y="49.048" width="450px" height="551px"/>
+    </g>
+    <g transform="matrix(0.755719,0.654896,-0.654896,0.755719,383.517,-217.265)">
+        <g transform="matrix(0.755719,-0.654896,0.654896,0.755719,-147.545,415.355)">
+            <use xlink:href="#_Image2" x="0" y="49" width="450px" height="551px"/>
+        </g>
+    </g>
+    <use xlink:href="#_Image3" x="25" y="99.5" width="400px" height="475px"/>
+    <g transform="matrix(1,0,0,2,1.13687e-13,25)">
+        <rect x="25" y="37.5" width="400" height="12.5" style="fill:url(#_Linear4);"/>
+    </g>
+    <defs>
+        <image id="_Image1" width="450px" height="551px" xlink:href="data:image/png;base64,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CSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCpCSEAqQkhAKkJIQCp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"/>
+        <image id="_Image2" width="450px" height="551px" xlink:href="data:image/png;base64,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"/>
+        <image id="_Image3" width="400px" height="475px" xlink:href="data:image/png;base64,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"/>
+        <linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(7.65404e-16,12.5,-0.390625,2.39189e-17,225,37.5)"><stop offset="0" style="stop-color:rgb(255,14,0);stop-opacity:0.5"/><stop offset="1" style="stop-color:rgb(255,13,0);stop-opacity:0"/></linearGradient>
+    </defs>
+</svg>
diff --git a/packages/frontend/assets/drop-and-fusion/gameover.png b/packages/frontend/assets/drop-and-fusion/gameover.png
new file mode 100644
index 0000000000..8b622577ca
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/gameover.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/grinning_squinting_face.png b/packages/frontend/assets/drop-and-fusion/grinning_squinting_face.png
new file mode 100644
index 0000000000..fd72d749a1
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/grinning_squinting_face.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/heart_suit.png b/packages/frontend/assets/drop-and-fusion/heart_suit.png
new file mode 100644
index 0000000000..b0105f8582
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/heart_suit.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_1.png b/packages/frontend/assets/drop-and-fusion/keycap_1.png
new file mode 100644
index 0000000000..d672f2854a
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_1.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_10.png b/packages/frontend/assets/drop-and-fusion/keycap_10.png
new file mode 100644
index 0000000000..32cf193540
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_10.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_2.png b/packages/frontend/assets/drop-and-fusion/keycap_2.png
new file mode 100644
index 0000000000..81c3f58e6e
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_2.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_3.png b/packages/frontend/assets/drop-and-fusion/keycap_3.png
new file mode 100644
index 0000000000..424d8c123d
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_3.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_4.png b/packages/frontend/assets/drop-and-fusion/keycap_4.png
new file mode 100644
index 0000000000..ea6ae50531
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_4.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_5.png b/packages/frontend/assets/drop-and-fusion/keycap_5.png
new file mode 100644
index 0000000000..ad435da69a
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_5.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_6.png b/packages/frontend/assets/drop-and-fusion/keycap_6.png
new file mode 100644
index 0000000000..70c9522b43
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_6.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_7.png b/packages/frontend/assets/drop-and-fusion/keycap_7.png
new file mode 100644
index 0000000000..5a24307487
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_7.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_8.png b/packages/frontend/assets/drop-and-fusion/keycap_8.png
new file mode 100644
index 0000000000..9689d8ecfb
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_8.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/keycap_9.png b/packages/frontend/assets/drop-and-fusion/keycap_9.png
new file mode 100644
index 0000000000..ac3f638841
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/keycap_9.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/logo.png b/packages/frontend/assets/drop-and-fusion/logo.png
new file mode 100644
index 0000000000..c6725bea88
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/logo.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/pleading_face.png b/packages/frontend/assets/drop-and-fusion/pleading_face.png
new file mode 100644
index 0000000000..42f58d411c
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/pleading_face.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/poi1.mp3 b/packages/frontend/assets/drop-and-fusion/poi1.mp3
new file mode 100644
index 0000000000..59dae90965
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/poi1.mp3 differ
diff --git a/packages/frontend/assets/drop-and-fusion/poi2.mp3 b/packages/frontend/assets/drop-and-fusion/poi2.mp3
new file mode 100644
index 0000000000..a65c653891
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/poi2.mp3 differ
diff --git a/packages/frontend/assets/drop-and-fusion/smiling_face_with_hearts.png b/packages/frontend/assets/drop-and-fusion/smiling_face_with_hearts.png
new file mode 100644
index 0000000000..416ef0410a
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/smiling_face_with_hearts.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/smiling_face_with_sunglasses.png b/packages/frontend/assets/drop-and-fusion/smiling_face_with_sunglasses.png
new file mode 100644
index 0000000000..c0f72254c2
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/smiling_face_with_sunglasses.png differ
diff --git a/packages/frontend/assets/drop-and-fusion/zany_face.png b/packages/frontend/assets/drop-and-fusion/zany_face.png
new file mode 100644
index 0000000000..f14f9db20b
Binary files /dev/null and b/packages/frontend/assets/drop-and-fusion/zany_face.png differ
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index 864779fd9d..9ef18a56a7 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -4,7 +4,7 @@
 	"type": "module",
 	"scripts": {
 		"watch": "vite",
-		"dev": "vite --config vite.config.local-dev.ts",
+		"dev": "vite --config vite.config.local-dev.ts --debug hmr",
 		"build": "vite build",
 		"storybook-dev": "nodemon --verbose --watch src --ext \"mdx,ts,vue\" --ignore \"*.stories.ts\" --exec \"pnpm build-storybook-pre && pnpm exec storybook dev -p 6006 --ci\"",
 		"build-storybook-pre": "(tsc -p .storybook || echo done.) && node .storybook/generate.js && node .storybook/preload-locale.js && node .storybook/preload-theme.js",
@@ -19,6 +19,7 @@
 	"dependencies": {
 		"@discordapp/twemoji": "15.0.2",
 		"@github/webauthn-json": "2.1.1",
+		"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
 		"@misskey-dev/browser-image-resizer": "2.2.1-misskey.10",
 		"@rollup/plugin-json": "6.1.0",
 		"@rollup/plugin-replace": "5.0.5",
diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts
index ef69eff764..c67911c9c3 100644
--- a/packages/frontend/src/boot/common.ts
+++ b/packages/frontend/src/boot/common.ts
@@ -22,6 +22,7 @@ import { getAccountFromId } from '@/scripts/get-account-from-id.js';
 import { deckStore } from '@/ui/deck/deck-store.js';
 import { miLocalStorage } from '@/local-storage.js';
 import { fetchCustomEmojis } from '@/custom-emojis.js';
+import { setupRouter } from '@/global/router/definition.js';
 
 export async function common(createVue: () => App<Element>) {
 	console.info(`Misskey v${version}`);
@@ -241,6 +242,8 @@ export async function common(createVue: () => App<Element>) {
 
 	const app = createVue();
 
+	setupRouter(app);
+
 	if (_DEV_) {
 		app.config.performance = true;
 	}
diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts
index 0159d0c032..5011ce9e74 100644
--- a/packages/frontend/src/boot/main-boot.ts
+++ b/packages/frontend/src/boot/main-boot.ts
@@ -3,23 +3,23 @@
  * SPDX-License-Identifier: AGPL-3.0-only
  */
 
-import { createApp, markRaw, defineAsyncComponent } from 'vue';
+import { createApp, defineAsyncComponent, markRaw } from 'vue';
 import { common } from './common.js';
 import { ui } from '@/config.js';
 import { i18n } from '@/i18n.js';
-import { confirm, alert, post, popup, toast } from '@/os.js';
+import { alert, confirm, popup, post, toast } from '@/os.js';
 import { useStream } from '@/stream.js';
 import * as sound from '@/scripts/sound.js';
-import { $i, updateAccount, signout } from '@/account.js';
-import { defaultStore, ColdDeviceStorage } from '@/store.js';
+import { $i, signout, updateAccount } from '@/account.js';
+import { ColdDeviceStorage, defaultStore } from '@/store.js';
 import { makeHotkey } from '@/scripts/hotkey.js';
 import { reactionPicker } from '@/scripts/reaction-picker.js';
 import { miLocalStorage } from '@/local-storage.js';
 import { claimAchievement, claimedAchievements } from '@/scripts/achievements.js';
-import { mainRouter } from '@/router.js';
 import { initializeSw } from '@/scripts/initialize-sw.js';
 import { deckStore } from '@/ui/deck/deck-store.js';
 import { emojiPicker } from '@/scripts/emoji-picker.js';
+import { mainRouter } from '@/global/router/main.js';
 
 export async function mainBoot() {
 	const { isClientUpdated } = await common(() => createApp(
diff --git a/packages/frontend/src/components/MkCaptcha.vue b/packages/frontend/src/components/MkCaptcha.vue
index 328215c791..7aa08cf51f 100644
--- a/packages/frontend/src/components/MkCaptcha.vue
+++ b/packages/frontend/src/components/MkCaptcha.vue
@@ -6,12 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div>
 	<span v-if="!available">Loading<MkEllipsis/></span>
-	<div ref="captchaEl"></div>
+	<div v-if="props.provider == 'mcaptcha'">
+		<div id="mcaptcha__widget-container" class="m-captcha-style"></div>
+		<div ref="captchaEl"></div>
+	</div>
+	<div v-else ref="captchaEl"></div>
 </div>
 </template>
 
 <script lang="ts" setup>
-import { ref, shallowRef, computed, onMounted, onBeforeUnmount, watch } from 'vue';
+import { ref, shallowRef, computed, onMounted, onBeforeUnmount, watch, onUnmounted } from 'vue';
 import { defaultStore } from '@/store.js';
 
 // APIs provided by Captcha services
@@ -25,7 +29,7 @@ export type Captcha = {
 	getResponse(id: string): string;
 };
 
-export type CaptchaProvider = 'hcaptcha' | 'recaptcha' | 'turnstile';
+export type CaptchaProvider = 'hcaptcha' | 'recaptcha' | 'turnstile' | 'mcaptcha';
 
 type CaptchaContainer = {
 	readonly [_ in CaptchaProvider]?: Captcha;
@@ -38,6 +42,7 @@ declare global {
 const props = defineProps<{
 	provider: CaptchaProvider;
 	sitekey: string | null; // null will show error on request
+	instanceUrl?: string | null;
 	modelValue?: string | null;
 }>();
 
@@ -54,6 +59,7 @@ const variable = computed(() => {
 		case 'hcaptcha': return 'hcaptcha';
 		case 'recaptcha': return 'grecaptcha';
 		case 'turnstile': return 'turnstile';
+		case 'mcaptcha': return 'mcaptcha';
 	}
 });
 
@@ -64,6 +70,7 @@ const src = computed(() => {
 		case 'hcaptcha': return 'https://js.hcaptcha.com/1/api.js?render=explicit&recaptchacompat=off';
 		case 'recaptcha': return 'https://www.recaptcha.net/recaptcha/api.js?render=explicit';
 		case 'turnstile': return 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit';
+		case 'mcaptcha': return null;
 	}
 });
 
@@ -71,9 +78,9 @@ const scriptId = computed(() => `script-${props.provider}`);
 
 const captcha = computed<Captcha>(() => window[variable.value] || {} as unknown as Captcha);
 
-if (loaded) {
+if (loaded || props.provider === 'mcaptcha') {
 	available.value = true;
-} else {
+} else if (src.value !== null) {
 	(document.getElementById(scriptId.value) ?? document.head.appendChild(Object.assign(document.createElement('script'), {
 		async: true,
 		id: scriptId.value,
@@ -86,7 +93,7 @@ function reset() {
 	if (captcha.value.reset) captcha.value.reset();
 }
 
-function requestRender() {
+async function requestRender() {
 	if (captcha.value.render && captchaEl.value instanceof Element) {
 		captcha.value.render(captchaEl.value, {
 			sitekey: props.sitekey,
@@ -95,6 +102,15 @@ function requestRender() {
 			'expired-callback': callback,
 			'error-callback': callback,
 		});
+	} else if (props.provider === 'mcaptcha' && props.instanceUrl && props.sitekey) {
+		const { default: Widget } = await import('@mcaptcha/vanilla-glue');
+		// @ts-expect-error avoid typecheck error
+		new Widget({
+			siteKey: {
+				instanceUrl: new URL(props.instanceUrl),
+				key: props.sitekey,
+			},
+		});
 	} else {
 		window.setTimeout(requestRender, 1);
 	}
@@ -104,14 +120,27 @@ function callback(response?: string) {
 	emit('update:modelValue', typeof response === 'string' ? response : null);
 }
 
+function onReceivedMessage(message: MessageEvent) {
+	if (message.data.token) {
+		if (props.instanceUrl && new URL(message.origin).host === new URL(props.instanceUrl).host) {
+			callback(<string>message.data.token);
+		}
+	}
+}
+
 onMounted(() => {
 	if (available.value) {
+		window.addEventListener('message', onReceivedMessage);
 		requestRender();
 	} else {
 		watch(available, requestRender);
 	}
 });
 
+onUnmounted(() => {
+	window.removeEventListener('message', onReceivedMessage);
+});
+
 onBeforeUnmount(() => {
 	reset();
 });
diff --git a/packages/frontend/src/components/MkDrive.file.vue b/packages/frontend/src/components/MkDrive.file.vue
index b46b25eba2..8a74319f29 100644
--- a/packages/frontend/src/components/MkDrive.file.vue
+++ b/packages/frontend/src/components/MkDrive.file.vue
@@ -45,9 +45,9 @@ import bytes from '@/filters/bytes.js';
 import * as os from '@/os.js';
 import { i18n } from '@/i18n.js';
 import { $i } from '@/account.js';
-import { useRouter } from '@/router.js';
 import { getDriveFileMenu } from '@/scripts/get-drive-file-menu.js';
 import { deviceKind } from '@/scripts/device-kind.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue
index 2647ace7db..28058c338b 100644
--- a/packages/frontend/src/components/MkPageWindow.vue
+++ b/packages/frontend/src/components/MkPageWindow.vue
@@ -23,26 +23,26 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</template>
 
 	<div ref="contents" :class="$style.root" style="container-type: inline-size;">
-		<RouterView :key="reloadCount" :router="router"/>
+		<RouterView :key="reloadCount" :router="windowRouter"/>
 	</div>
 </MkWindow>
 </template>
 
 <script lang="ts" setup>
-import { ComputedRef, onMounted, onUnmounted, provide, shallowRef, ref, computed } from 'vue';
+import { computed, ComputedRef, onMounted, onUnmounted, provide, ref, shallowRef } from 'vue';
 import RouterView from '@/components/global/RouterView.vue';
 import MkWindow from '@/components/MkWindow.vue';
 import { popout as _popout } from '@/scripts/popout.js';
 import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 import { url } from '@/config.js';
-import { mainRouter, routes, page } from '@/router.js';
-import { $i } from '@/account.js';
-import { Router, useScrollPositionManager } from '@/nirax.js';
+import { useScrollPositionManager } from '@/nirax.js';
 import { i18n } from '@/i18n.js';
 import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import { openingWindowsCount } from '@/os.js';
 import { claimAchievement } from '@/scripts/achievements.js';
 import { getScrollContainer } from '@/scripts/scroll.js';
+import { useRouterFactory } from '@/global/router/supplier.js';
+import { mainRouter } from '@/global/router/main.js';
 
 const props = defineProps<{
 	initialPath: string;
@@ -52,14 +52,15 @@ defineEmits<{
 	(ev: 'closed'): void;
 }>();
 
-const router = new Router(routes, props.initialPath, !!$i, page(() => import('@/pages/not-found.vue')));
+const routerFactory = useRouterFactory();
+const windowRouter = routerFactory(props.initialPath);
 
 const contents = shallowRef<HTMLElement>();
 const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
 const windowEl = shallowRef<InstanceType<typeof MkWindow>>();
 const history = ref<{ path: string; key: any; }[]>([{
-	path: router.getCurrentPath(),
-	key: router.getCurrentKey(),
+	path: windowRouter.getCurrentPath(),
+	key: windowRouter.getCurrentKey(),
 }]);
 const buttonsLeft = computed(() => {
 	const buttons = [];
@@ -88,11 +89,11 @@ const buttonsRight = computed(() => {
 });
 const reloadCount = ref(0);
 
-router.addListener('push', ctx => {
+windowRouter.addListener('push', ctx => {
 	history.value.push({ path: ctx.path, key: ctx.key });
 });
 
-provide('router', router);
+provide('router', windowRouter);
 provideMetadataReceiver((info) => {
 	pageMetadata.value = info;
 });
@@ -112,20 +113,20 @@ const contextmenu = computed(() => ([{
 	icon: 'ti ti-external-link',
 	text: i18n.ts.openInNewTab,
 	action: () => {
-		window.open(url + router.getCurrentPath(), '_blank', 'noopener');
+		window.open(url + windowRouter.getCurrentPath(), '_blank', 'noopener');
 		windowEl.value.close();
 	},
 }, {
 	icon: 'ti ti-link',
 	text: i18n.ts.copyLink,
 	action: () => {
-		copyToClipboard(url + router.getCurrentPath());
+		copyToClipboard(url + windowRouter.getCurrentPath());
 	},
 }]));
 
 function back() {
 	history.value.pop();
-	router.replace(history.value.at(-1)!.path, history.value.at(-1)!.key);
+	windowRouter.replace(history.value.at(-1)!.path, history.value.at(-1)!.key);
 }
 
 function reload() {
@@ -137,16 +138,16 @@ function close() {
 }
 
 function expand() {
-	mainRouter.push(router.getCurrentPath(), 'forcePage');
+	mainRouter.push(windowRouter.getCurrentPath(), 'forcePage');
 	windowEl.value.close();
 }
 
 function popout() {
-	_popout(router.getCurrentPath(), windowEl.value.$el);
+	_popout(windowRouter.getCurrentPath(), windowEl.value.$el);
 	windowEl.value.close();
 }
 
-useScrollPositionManager(() => getScrollContainer(contents.value), router);
+useScrollPositionManager(() => getScrollContainer(contents.value), windowRouter);
 
 onMounted(() => {
 	openingWindowsCount.value++;
diff --git a/packages/frontend/src/components/MkPlusOneEffect.vue b/packages/frontend/src/components/MkPlusOneEffect.vue
index a741a3f7a8..e5e5a9edf4 100644
--- a/packages/frontend/src/components/MkPlusOneEffect.vue
+++ b/packages/frontend/src/components/MkPlusOneEffect.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div :class="$style.root" :style="{ zIndex, top: `${y - 64}px`, left: `${x - 64}px` }">
-	<span class="text" :class="{ up }">+1</span>
+	<span class="text" :class="{ up }">+{{ value }}</span>
 </div>
 </template>
 
@@ -16,7 +16,9 @@ import * as os from '@/os.js';
 const props = withDefaults(defineProps<{
 	x: number;
 	y: number;
+	value?: number;
 }>(), {
+	value: 1,
 });
 
 const emit = defineEmits<{
@@ -40,6 +42,7 @@ onMounted(() => {
 
 <style lang="scss" module>
 .root {
+	user-select: none;
 	pointer-events: none;
 	position: fixed;
 	width: 128px;
diff --git a/packages/frontend/src/components/MkSignupDialog.form.vue b/packages/frontend/src/components/MkSignupDialog.form.vue
index c71330d62c..79e17c9aef 100644
--- a/packages/frontend/src/components/MkSignupDialog.form.vue
+++ b/packages/frontend/src/components/MkSignupDialog.form.vue
@@ -63,6 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</template>
 			</MkInput>
 			<MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :class="$style.captcha" provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/>
+			<MkCaptcha v-if="instance.enableMcaptcha" ref="mcaptcha" v-model="mCaptchaResponse" :class="$style.captcha" provider="mcaptcha" :sitekey="instance.mcaptchaSiteKey" :instanceUrl="instance.mcaptchaInstanceUrl"/>
 			<MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" :class="$style.captcha" provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/>
 			<MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" :class="$style.captcha" provider="turnstile" :sitekey="instance.turnstileSiteKey"/>
 			<MkButton type="submit" :disabled="shouldDisableSubmitting" large gradate rounded data-cy-signup-submit style="margin: 0 auto;">
@@ -117,6 +118,7 @@ const passwordStrength = ref<'' | 'low' | 'medium' | 'high'>('');
 const passwordRetypeState = ref<null | 'match' | 'not-match'>(null);
 const submitting = ref<boolean>(false);
 const hCaptchaResponse = ref<string | null>(null);
+const mCaptchaResponse = ref<string | null>(null);
 const reCaptchaResponse = ref<string | null>(null);
 const turnstileResponse = ref<string | null>(null);
 const usernameAbortController = ref<null | AbortController>(null);
@@ -125,6 +127,7 @@ const emailAbortController = ref<null | AbortController>(null);
 const shouldDisableSubmitting = computed((): boolean => {
 	return submitting.value ||
 		instance.enableHcaptcha && !hCaptchaResponse.value ||
+		instance.enableMcaptcha && !mCaptchaResponse.value ||
 		instance.enableRecaptcha && !reCaptchaResponse.value ||
 		instance.enableTurnstile && !turnstileResponse.value ||
 		instance.emailRequiredForSignup && emailState.value !== 'ok' ||
@@ -252,6 +255,7 @@ async function onSubmit(): Promise<void> {
 			emailAddress: email.value,
 			invitationCode: invitationCode.value,
 			'hcaptcha-response': hCaptchaResponse.value,
+			'm-captcha-response': mCaptchaResponse.value,
 			'g-recaptcha-response': reCaptchaResponse.value,
 			'turnstile-response': turnstileResponse.value,
 		});
diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue
index d5adc02ca7..63f779dbde 100644
--- a/packages/frontend/src/components/MkTimeline.vue
+++ b/packages/frontend/src/components/MkTimeline.vue
@@ -132,6 +132,7 @@ function connectChannel() {
 		connection.on('mention', onNote);
 	} else if (props.src === 'list') {
 		connection = stream.useChannel('userList', {
+			withRenotes: props.withRenotes,
 			withFiles: props.onlyFiles ? true : undefined,
 			listId: props.list,
 		});
@@ -198,6 +199,7 @@ function updatePaginationQuery() {
 	} else if (props.src === 'list') {
 		endpoint = 'notes/user-list-timeline';
 		query = {
+			withRenotes: props.withRenotes,
 			withFiles: props.onlyFiles ? true : undefined,
 			listId: props.list,
 		};
@@ -236,8 +238,9 @@ function refreshEndpointAndChannel() {
 	updatePaginationQuery();
 }
 
+// デッキのリストカラムでwithRenotesを変更した場合に自動的に更新されるようにさせる
 // IDが切り替わったら切り替え先のTLを表示させたい
-watch(() => [props.list, props.antenna, props.channel, props.role], refreshEndpointAndChannel);
+watch(() => [props.list, props.antenna, props.channel, props.role, props.withRenotes], refreshEndpointAndChannel);
 
 // 初回表示用
 refreshEndpointAndChannel();
diff --git a/packages/frontend/src/components/global/MkA.vue b/packages/frontend/src/components/global/MkA.vue
index d34f47a68a..fbea279dbe 100644
--- a/packages/frontend/src/components/global/MkA.vue
+++ b/packages/frontend/src/components/global/MkA.vue
@@ -15,7 +15,7 @@ import * as os from '@/os.js';
 import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 import { url } from '@/config.js';
 import { i18n } from '@/i18n.js';
-import { useRouter } from '@/router.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const props = withDefaults(defineProps<{
 	to: string;
diff --git a/packages/frontend/src/components/global/MkEmoji.vue b/packages/frontend/src/components/global/MkEmoji.vue
index 76ca8688d1..f6b21343b6 100644
--- a/packages/frontend/src/components/global/MkEmoji.vue
+++ b/packages/frontend/src/components/global/MkEmoji.vue
@@ -5,15 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <img v-if="!useOsNativeEmojis" :class="$style.root" :src="url" :alt="props.emoji" decoding="async" @pointerenter="computeTitle" @click="onClick"/>
-<span v-else-if="useOsNativeEmojis" :alt="props.emoji" @pointerenter="computeTitle" @click="onClick">{{ props.emoji }}</span>
-<span v-else>{{ emoji }}</span>
+<span v-else :alt="props.emoji" @pointerenter="computeTitle" @click="onClick">{{ colorizedNativeEmoji }}</span>
 </template>
 
 <script lang="ts" setup>
 import { computed, inject } from 'vue';
 import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base.js';
 import { defaultStore } from '@/store.js';
-import { getEmojiName } from '@/scripts/emojilist.js';
+import { colorizeEmoji, getEmojiName } from '@/scripts/emojilist.js';
 import * as os from '@/os.js';
 import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 import * as sound from '@/scripts/sound.js';
@@ -30,9 +29,8 @@ const react = inject<((name: string) => void) | null>('react', null);
 const char2path = defaultStore.state.emojiStyle === 'twemoji' ? char2twemojiFilePath : char2fluentEmojiFilePath;
 
 const useOsNativeEmojis = computed(() => defaultStore.state.emojiStyle === 'native');
-const url = computed(() => {
-	return char2path(props.emoji);
-});
+const url = computed(() => char2path(props.emoji));
+const colorizedNativeEmoji = computed(() => colorizeEmoji(props.emoji));
 
 // Searching from an array with 2000 items for every emoji felt like too energy-consuming, so I decided to do it lazily on pointerenter
 function computeTitle(event: PointerEvent): void {
diff --git a/packages/frontend/src/components/global/RouterView.vue b/packages/frontend/src/components/global/RouterView.vue
index 99ed8adbef..dc7474835d 100644
--- a/packages/frontend/src/components/global/RouterView.vue
+++ b/packages/frontend/src/components/global/RouterView.vue
@@ -16,12 +16,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 </template>
 
 <script lang="ts" setup>
-import { inject, onBeforeUnmount, provide, shallowRef, ref } from 'vue';
-import { Resolved, Router } from '@/nirax.js';
+import { inject, onBeforeUnmount, provide, ref, shallowRef } from 'vue';
+import { IRouter, Resolved } from '@/nirax.js';
 import { defaultStore } from '@/store.js';
 
 const props = defineProps<{
-	router?: Router;
+	router?: IRouter;
 }>();
 
 const router = props.router ?? inject('router');
diff --git a/packages/frontend/src/global/router/definition.ts b/packages/frontend/src/global/router/definition.ts
new file mode 100644
index 0000000000..727d6b1bb2
--- /dev/null
+++ b/packages/frontend/src/global/router/definition.ts
@@ -0,0 +1,571 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { App, AsyncComponentLoader, defineAsyncComponent, provide } from 'vue';
+import { IRouter, Router } from '@/nirax.js';
+import { $i, iAmModerator } from '@/account.js';
+import MkLoading from '@/pages/_loading_.vue';
+import MkError from '@/pages/_error_.vue';
+import { setMainRouter } from '@/global/router/main.js';
+
+const page = (loader: AsyncComponentLoader<any>) => defineAsyncComponent({
+	loader: loader,
+	loadingComponent: MkLoading,
+	errorComponent: MkError,
+});
+const routes = [{
+	path: '/@:initUser/pages/:initPageName/view-source',
+	component: page(() => import('@/pages/page-editor/page-editor.vue')),
+}, {
+	path: '/@:username/pages/:pageName',
+	component: page(() => import('@/pages/page.vue')),
+}, {
+	path: '/@:acct/following',
+	component: page(() => import('@/pages/user/following.vue')),
+}, {
+	path: '/@:acct/followers',
+	component: page(() => import('@/pages/user/followers.vue')),
+}, {
+	name: 'user',
+	path: '/@:acct/:page?',
+	component: page(() => import('@/pages/user/index.vue')),
+}, {
+	name: 'note',
+	path: '/notes/:noteId',
+	component: page(() => import('@/pages/note.vue')),
+}, {
+	name: 'list',
+	path: '/list/:listId',
+	component: page(() => import('@/pages/list.vue')),
+}, {
+	path: '/clips/:clipId',
+	component: page(() => import('@/pages/clip.vue')),
+}, {
+	path: '/instance-info/:host',
+	component: page(() => import('@/pages/instance-info.vue')),
+}, {
+	name: 'settings',
+	path: '/settings',
+	component: page(() => import('@/pages/settings/index.vue')),
+	loginRequired: true,
+	children: [{
+		path: '/profile',
+		name: 'profile',
+		component: page(() => import('@/pages/settings/profile.vue')),
+	}, {
+		path: '/avatar-decoration',
+		name: 'avatarDecoration',
+		component: page(() => import('@/pages/settings/avatar-decoration.vue')),
+	}, {
+		path: '/roles',
+		name: 'roles',
+		component: page(() => import('@/pages/settings/roles.vue')),
+	}, {
+		path: '/privacy',
+		name: 'privacy',
+		component: page(() => import('@/pages/settings/privacy.vue')),
+	}, {
+		path: '/emoji-picker',
+		name: 'emojiPicker',
+		component: page(() => import('@/pages/settings/emoji-picker.vue')),
+	}, {
+		path: '/drive',
+		name: 'drive',
+		component: page(() => import('@/pages/settings/drive.vue')),
+	}, {
+		path: '/drive/cleaner',
+		name: 'drive',
+		component: page(() => import('@/pages/settings/drive-cleaner.vue')),
+	}, {
+		path: '/notifications',
+		name: 'notifications',
+		component: page(() => import('@/pages/settings/notifications.vue')),
+	}, {
+		path: '/email',
+		name: 'email',
+		component: page(() => import('@/pages/settings/email.vue')),
+	}, {
+		path: '/security',
+		name: 'security',
+		component: page(() => import('@/pages/settings/security.vue')),
+	}, {
+		path: '/general',
+		name: 'general',
+		component: page(() => import('@/pages/settings/general.vue')),
+	}, {
+		path: '/theme/install',
+		name: 'theme',
+		component: page(() => import('@/pages/settings/theme.install.vue')),
+	}, {
+		path: '/theme/manage',
+		name: 'theme',
+		component: page(() => import('@/pages/settings/theme.manage.vue')),
+	}, {
+		path: '/theme',
+		name: 'theme',
+		component: page(() => import('@/pages/settings/theme.vue')),
+	}, {
+		path: '/navbar',
+		name: 'navbar',
+		component: page(() => import('@/pages/settings/navbar.vue')),
+	}, {
+		path: '/statusbar',
+		name: 'statusbar',
+		component: page(() => import('@/pages/settings/statusbar.vue')),
+	}, {
+		path: '/sounds',
+		name: 'sounds',
+		component: page(() => import('@/pages/settings/sounds.vue')),
+	}, {
+		path: '/plugin/install',
+		name: 'plugin',
+		component: page(() => import('@/pages/settings/plugin.install.vue')),
+	}, {
+		path: '/plugin',
+		name: 'plugin',
+		component: page(() => import('@/pages/settings/plugin.vue')),
+	}, {
+		path: '/import-export',
+		name: 'import-export',
+		component: page(() => import('@/pages/settings/import-export.vue')),
+	}, {
+		path: '/mute-block',
+		name: 'mute-block',
+		component: page(() => import('@/pages/settings/mute-block.vue')),
+	}, {
+		path: '/api',
+		name: 'api',
+		component: page(() => import('@/pages/settings/api.vue')),
+	}, {
+		path: '/apps',
+		name: 'api',
+		component: page(() => import('@/pages/settings/apps.vue')),
+	}, {
+		path: '/webhook/edit/:webhookId',
+		name: 'webhook',
+		component: page(() => import('@/pages/settings/webhook.edit.vue')),
+	}, {
+		path: '/webhook/new',
+		name: 'webhook',
+		component: page(() => import('@/pages/settings/webhook.new.vue')),
+	}, {
+		path: '/webhook',
+		name: 'webhook',
+		component: page(() => import('@/pages/settings/webhook.vue')),
+	}, {
+		path: '/deck',
+		name: 'deck',
+		component: page(() => import('@/pages/settings/deck.vue')),
+	}, {
+		path: '/preferences-backups',
+		name: 'preferences-backups',
+		component: page(() => import('@/pages/settings/preferences-backups.vue')),
+	}, {
+		path: '/migration',
+		name: 'migration',
+		component: page(() => import('@/pages/settings/migration.vue')),
+	}, {
+		path: '/custom-css',
+		name: 'general',
+		component: page(() => import('@/pages/settings/custom-css.vue')),
+	}, {
+		path: '/accounts',
+		name: 'profile',
+		component: page(() => import('@/pages/settings/accounts.vue')),
+	}, {
+		path: '/other',
+		name: 'other',
+		component: page(() => import('@/pages/settings/other.vue')),
+	}, {
+		path: '/',
+		component: page(() => import('@/pages/_empty_.vue')),
+	}],
+}, {
+	path: '/reset-password/:token?',
+	component: page(() => import('@/pages/reset-password.vue')),
+}, {
+	path: '/signup-complete/:code',
+	component: page(() => import('@/pages/signup-complete.vue')),
+}, {
+	path: '/announcements',
+	component: page(() => import('@/pages/announcements.vue')),
+}, {
+	path: '/about',
+	component: page(() => import('@/pages/about.vue')),
+	hash: 'initialTab',
+}, {
+	path: '/about-misskey',
+	component: page(() => import('@/pages/about-misskey.vue')),
+}, {
+	path: '/invite',
+	name: 'invite',
+	component: page(() => import('@/pages/invite.vue')),
+}, {
+	path: '/ads',
+	component: page(() => import('@/pages/ads.vue')),
+}, {
+	path: '/theme-editor',
+	component: page(() => import('@/pages/theme-editor.vue')),
+	loginRequired: true,
+}, {
+	path: '/roles/:role',
+	component: page(() => import('@/pages/role.vue')),
+}, {
+	path: '/user-tags/:tag',
+	component: page(() => import('@/pages/user-tag.vue')),
+}, {
+	path: '/explore',
+	component: page(() => import('@/pages/explore.vue')),
+	hash: 'initialTab',
+}, {
+	path: '/search',
+	component: page(() => import('@/pages/search.vue')),
+	query: {
+		q: 'query',
+		channel: 'channel',
+		type: 'type',
+		origin: 'origin',
+	},
+}, {
+	path: '/authorize-follow',
+	component: page(() => import('@/pages/follow.vue')),
+	loginRequired: true,
+}, {
+	path: '/share',
+	component: page(() => import('@/pages/share.vue')),
+	loginRequired: true,
+}, {
+	path: '/api-console',
+	component: page(() => import('@/pages/api-console.vue')),
+	loginRequired: true,
+}, {
+	path: '/scratchpad',
+	component: page(() => import('@/pages/scratchpad.vue')),
+}, {
+	path: '/auth/:token',
+	component: page(() => import('@/pages/auth.vue')),
+}, {
+	path: '/miauth/:session',
+	component: page(() => import('@/pages/miauth.vue')),
+	query: {
+		callback: 'callback',
+		name: 'name',
+		icon: 'icon',
+		permission: 'permission',
+	},
+}, {
+	path: '/oauth/authorize',
+	component: page(() => import('@/pages/oauth.vue')),
+}, {
+	path: '/tags/:tag',
+	component: page(() => import('@/pages/tag.vue')),
+}, {
+	path: '/pages/new',
+	component: page(() => import('@/pages/page-editor/page-editor.vue')),
+	loginRequired: true,
+}, {
+	path: '/pages/edit/:initPageId',
+	component: page(() => import('@/pages/page-editor/page-editor.vue')),
+	loginRequired: true,
+}, {
+	path: '/pages',
+	component: page(() => import('@/pages/pages.vue')),
+}, {
+	path: '/play/:id/edit',
+	component: page(() => import('@/pages/flash/flash-edit.vue')),
+	loginRequired: true,
+}, {
+	path: '/play/new',
+	component: page(() => import('@/pages/flash/flash-edit.vue')),
+	loginRequired: true,
+}, {
+	path: '/play/:id',
+	component: page(() => import('@/pages/flash/flash.vue')),
+}, {
+	path: '/play',
+	component: page(() => import('@/pages/flash/flash-index.vue')),
+}, {
+	path: '/gallery/:postId/edit',
+	component: page(() => import('@/pages/gallery/edit.vue')),
+	loginRequired: true,
+}, {
+	path: '/gallery/new',
+	component: page(() => import('@/pages/gallery/edit.vue')),
+	loginRequired: true,
+}, {
+	path: '/gallery/:postId',
+	component: page(() => import('@/pages/gallery/post.vue')),
+}, {
+	path: '/gallery',
+	component: page(() => import('@/pages/gallery/index.vue')),
+}, {
+	path: '/channels/:channelId/edit',
+	component: page(() => import('@/pages/channel-editor.vue')),
+	loginRequired: true,
+}, {
+	path: '/channels/new',
+	component: page(() => import('@/pages/channel-editor.vue')),
+	loginRequired: true,
+}, {
+	path: '/channels/:channelId',
+	component: page(() => import('@/pages/channel.vue')),
+}, {
+	path: '/channels',
+	component: page(() => import('@/pages/channels.vue')),
+}, {
+	path: '/custom-emojis-manager',
+	component: page(() => import('@/pages/custom-emojis-manager.vue')),
+}, {
+	path: '/avatar-decorations',
+	name: 'avatarDecorations',
+	component: page(() => import('@/pages/avatar-decorations.vue')),
+}, {
+	path: '/registry/keys/:domain/:path(*)?',
+	component: page(() => import('@/pages/registry.keys.vue')),
+}, {
+	path: '/registry/value/:domain/:path(*)?',
+	component: page(() => import('@/pages/registry.value.vue')),
+}, {
+	path: '/registry',
+	component: page(() => import('@/pages/registry.vue')),
+}, {
+	path: '/install-extentions',
+	component: page(() => import('@/pages/install-extentions.vue')),
+	loginRequired: true,
+}, {
+	path: '/admin/user/:userId',
+	component: iAmModerator ? page(() => import('@/pages/admin-user.vue')) : page(() => import('@/pages/not-found.vue')),
+}, {
+	path: '/admin/file/:fileId',
+	component: iAmModerator ? page(() => import('@/pages/admin-file.vue')) : page(() => import('@/pages/not-found.vue')),
+}, {
+	path: '/admin',
+	component: iAmModerator ? page(() => import('@/pages/admin/index.vue')) : page(() => import('@/pages/not-found.vue')),
+	children: [{
+		path: '/overview',
+		name: 'overview',
+		component: page(() => import('@/pages/admin/overview.vue')),
+	}, {
+		path: '/users',
+		name: 'users',
+		component: page(() => import('@/pages/admin/users.vue')),
+	}, {
+		path: '/emojis',
+		name: 'emojis',
+		component: page(() => import('@/pages/custom-emojis-manager.vue')),
+	}, {
+		path: '/avatar-decorations',
+		name: 'avatarDecorations',
+		component: page(() => import('@/pages/avatar-decorations.vue')),
+	}, {
+		path: '/queue',
+		name: 'queue',
+		component: page(() => import('@/pages/admin/queue.vue')),
+	}, {
+		path: '/files',
+		name: 'files',
+		component: page(() => import('@/pages/admin/files.vue')),
+	}, {
+		path: '/federation',
+		name: 'federation',
+		component: page(() => import('@/pages/admin/federation.vue')),
+	}, {
+		path: '/announcements',
+		name: 'announcements',
+		component: page(() => import('@/pages/admin/announcements.vue')),
+	}, {
+		path: '/ads',
+		name: 'ads',
+		component: page(() => import('@/pages/admin/ads.vue')),
+	}, {
+		path: '/roles/:id/edit',
+		name: 'roles',
+		component: page(() => import('@/pages/admin/roles.edit.vue')),
+	}, {
+		path: '/roles/new',
+		name: 'roles',
+		component: page(() => import('@/pages/admin/roles.edit.vue')),
+	}, {
+		path: '/roles/:id',
+		name: 'roles',
+		component: page(() => import('@/pages/admin/roles.role.vue')),
+	}, {
+		path: '/roles',
+		name: 'roles',
+		component: page(() => import('@/pages/admin/roles.vue')),
+	}, {
+		path: '/database',
+		name: 'database',
+		component: page(() => import('@/pages/admin/database.vue')),
+	}, {
+		path: '/abuses',
+		name: 'abuses',
+		component: page(() => import('@/pages/admin/abuses.vue')),
+	}, {
+		path: '/modlog',
+		name: 'modlog',
+		component: page(() => import('@/pages/admin/modlog.vue')),
+	}, {
+		path: '/settings',
+		name: 'settings',
+		component: page(() => import('@/pages/admin/settings.vue')),
+	}, {
+		path: '/branding',
+		name: 'branding',
+		component: page(() => import('@/pages/admin/branding.vue')),
+	}, {
+		path: '/moderation',
+		name: 'moderation',
+		component: page(() => import('@/pages/admin/moderation.vue')),
+	}, {
+		path: '/email-settings',
+		name: 'email-settings',
+		component: page(() => import('@/pages/admin/email-settings.vue')),
+	}, {
+		path: '/object-storage',
+		name: 'object-storage',
+		component: page(() => import('@/pages/admin/object-storage.vue')),
+	}, {
+		path: '/security',
+		name: 'security',
+		component: page(() => import('@/pages/admin/security.vue')),
+	}, {
+		path: '/relays',
+		name: 'relays',
+		component: page(() => import('@/pages/admin/relays.vue')),
+	}, {
+		path: '/instance-block',
+		name: 'instance-block',
+		component: page(() => import('@/pages/admin/instance-block.vue')),
+	}, {
+		path: '/proxy-account',
+		name: 'proxy-account',
+		component: page(() => import('@/pages/admin/proxy-account.vue')),
+	}, {
+		path: '/external-services',
+		name: 'external-services',
+		component: page(() => import('@/pages/admin/external-services.vue')),
+	}, {
+		path: '/other-settings',
+		name: 'other-settings',
+		component: page(() => import('@/pages/admin/other-settings.vue')),
+	}, {
+		path: '/server-rules',
+		name: 'server-rules',
+		component: page(() => import('@/pages/admin/server-rules.vue')),
+	}, {
+		path: '/invites',
+		name: 'invites',
+		component: page(() => import('@/pages/admin/invites.vue')),
+	}, {
+		path: '/',
+		component: page(() => import('@/pages/_empty_.vue')),
+	}],
+}, {
+	path: '/my/notifications',
+	component: page(() => import('@/pages/notifications.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/favorites',
+	component: page(() => import('@/pages/favorites.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/achievements',
+	component: page(() => import('@/pages/achievements.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/drive/folder/:folder',
+	component: page(() => import('@/pages/drive.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/drive',
+	component: page(() => import('@/pages/drive.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/drive/file/:fileId',
+	component: page(() => import('@/pages/drive.file.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/follow-requests',
+	component: page(() => import('@/pages/follow-requests.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/lists/:listId',
+	component: page(() => import('@/pages/my-lists/list.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/lists',
+	component: page(() => import('@/pages/my-lists/index.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/clips',
+	component: page(() => import('@/pages/my-clips/index.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/antennas/create',
+	component: page(() => import('@/pages/my-antennas/create.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/antennas/:antennaId',
+	component: page(() => import('@/pages/my-antennas/edit.vue')),
+	loginRequired: true,
+}, {
+	path: '/my/antennas',
+	component: page(() => import('@/pages/my-antennas/index.vue')),
+	loginRequired: true,
+}, {
+	path: '/timeline/list/:listId',
+	component: page(() => import('@/pages/user-list-timeline.vue')),
+	loginRequired: true,
+}, {
+	path: '/timeline/antenna/:antennaId',
+	component: page(() => import('@/pages/antenna-timeline.vue')),
+	loginRequired: true,
+}, {
+	path: '/clicker',
+	component: page(() => import('@/pages/clicker.vue')),
+	loginRequired: true,
+}, {
+	path: '/bubble-game',
+	component: page(() => import('@/pages/drop-and-fusion.vue')),
+	loginRequired: true,
+}, {
+	path: '/timeline',
+	component: page(() => import('@/pages/timeline.vue')),
+}, {
+	name: 'index',
+	path: '/',
+	component: $i ? page(() => import('@/pages/timeline.vue')) : page(() => import('@/pages/welcome.vue')),
+	globalCacheKey: 'index',
+}, {
+	path: '/:(*)',
+	component: page(() => import('@/pages/not-found.vue')),
+}];
+
+function createRouterImpl(path: string): IRouter {
+	return new Router(routes, path, !!$i, page(() => import('@/pages/not-found.vue')));
+}
+
+/**
+ * {@link Router}による画面遷移を可能とするために{@link mainRouter}をセットアップする。
+ * また、{@link Router}のインスタンスを作成するためのファクトリも{@link provide}経由で公開する(`routerFactory`というキーで取得可能)
+ */
+export function setupRouter(app: App) {
+	app.provide('routerFactory', createRouterImpl);
+
+	const mainRouter = createRouterImpl(location.pathname + location.search + location.hash);
+
+	window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href);
+
+	window.addEventListener('popstate', (event) => {
+		mainRouter.replace(location.pathname + location.search + location.hash, event.state?.key);
+	});
+
+	mainRouter.addListener('push', ctx => {
+		window.history.pushState({ key: ctx.key }, '', ctx.path);
+	});
+
+	setMainRouter(mainRouter);
+}
diff --git a/packages/frontend/src/global/router/main.ts b/packages/frontend/src/global/router/main.ts
new file mode 100644
index 0000000000..5adb3f606f
--- /dev/null
+++ b/packages/frontend/src/global/router/main.ts
@@ -0,0 +1,163 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { ShallowRef } from 'vue';
+import { EventEmitter } from 'eventemitter3';
+import { IRouter, Resolved, RouteDef, RouterEvent } from '@/nirax.js';
+
+function getMainRouter(): IRouter {
+	const router = mainRouterHolder;
+	if (!router) {
+		throw new Error('mainRouter is not found.');
+	}
+
+	return router;
+}
+
+/**
+ * メインルータを設定する。一度設定すると、それ以降は変更できない。
+ * {@link setupRouter}から呼び出されることのみを想定している。
+ */
+export function setMainRouter(router: IRouter) {
+	if (mainRouterHolder) {
+		throw new Error('mainRouter is already exists.');
+	}
+
+	mainRouterHolder = router;
+}
+
+/**
+ * {@link mainRouter}用のプロキシ実装。
+ * {@link mainRouter}は起動シーケンスの一部にて初期化されるため、僅かにundefinedになる期間がある。
+ * その僅かな期間のためだけに型をundefined込みにしたくないのでこのクラスを緩衝材として使用する。
+ */
+class MainRouterProxy implements IRouter {
+	private supplier: () => IRouter;
+
+	constructor(supplier: () => IRouter) {
+		this.supplier = supplier;
+	}
+
+	get current(): Resolved {
+		return this.supplier().current;
+	}
+
+	get currentRef(): ShallowRef<Resolved> {
+		return this.supplier().currentRef;
+	}
+
+	get currentRoute(): ShallowRef<RouteDef> {
+		return this.supplier().currentRoute;
+	}
+
+	get navHook(): ((path: string, flag?: any) => boolean) | null {
+		return this.supplier().navHook;
+	}
+
+	set navHook(value) {
+		this.supplier().navHook = value;
+	}
+
+	getCurrentKey(): string {
+		return this.supplier().getCurrentKey();
+	}
+
+	getCurrentPath(): any {
+		return this.supplier().getCurrentPath();
+	}
+
+	push(path: string, flag?: any): void {
+		this.supplier().push(path, flag);
+	}
+
+	replace(path: string, key?: string | null): void {
+		this.supplier().replace(path, key);
+	}
+
+	resolve(path: string): Resolved | null {
+		return this.supplier().resolve(path);
+	}
+
+	eventNames(): Array<EventEmitter.EventNames<RouterEvent>> {
+		return this.supplier().eventNames();
+	}
+
+	listeners<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+	): Array<EventEmitter.EventListener<RouterEvent, T>> {
+		return this.supplier().listeners(event);
+	}
+
+	listenerCount(
+		event: EventEmitter.EventNames<RouterEvent>,
+	): number {
+		return this.supplier().listenerCount(event);
+	}
+
+	emit<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		...args: EventEmitter.EventArgs<RouterEvent, T>
+	): boolean {
+		return this.supplier().emit(event, ...args);
+	}
+
+	on<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any,
+	): this {
+		this.supplier().on(event, fn, context);
+		return this;
+	}
+
+	addListener<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any,
+	): this {
+		this.supplier().addListener(event, fn, context);
+		return this;
+	}
+
+	once<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any,
+	): this {
+		this.supplier().once(event, fn, context);
+		return this;
+	}
+
+	removeListener<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn?: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any,
+		once?: boolean,
+	): this {
+		this.supplier().removeListener(event, fn, context, once);
+		return this;
+	}
+
+	off<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn?: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any,
+		once?: boolean,
+	): this {
+		this.supplier().off(event, fn, context, once);
+		return this;
+	}
+
+	removeAllListeners(
+		event?: EventEmitter.EventNames<RouterEvent>,
+	): this {
+		this.supplier().removeAllListeners(event);
+		return this;
+	}
+}
+
+let mainRouterHolder: IRouter | null = null;
+
+export const mainRouter: IRouter = new MainRouterProxy(getMainRouter);
diff --git a/packages/frontend/src/global/router/supplier.ts b/packages/frontend/src/global/router/supplier.ts
new file mode 100644
index 0000000000..1e321ef21f
--- /dev/null
+++ b/packages/frontend/src/global/router/supplier.ts
@@ -0,0 +1,30 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { inject } from 'vue';
+import { IRouter, Router } from '@/nirax.js';
+import { mainRouter } from '@/global/router/main.js';
+
+/**
+ * メインの{@link Router}を取得する。
+ * あらかじめ{@link setupRouter}を実行しておく必要がある({@link provide}により{@link IRouter}のインスタンスを注入可能であるならばこの限りではない)
+ */
+export function useRouter(): IRouter {
+	return inject<Router | null>('router', null) ?? mainRouter;
+}
+
+/**
+ * 任意の{@link Router}を取得するためのファクトリを取得する。
+ * あらかじめ{@link setupRouter}を実行しておく必要がある。
+ */
+export function useRouterFactory(): (path: string) => IRouter {
+	const factory = inject<(path: string) => IRouter>('routerFactory');
+	if (!factory) {
+		console.error('routerFactory is not defined.');
+		throw new Error('routerFactory is not defined.');
+	}
+
+	return factory;
+}
diff --git a/packages/frontend/src/index.html b/packages/frontend/src/index.html
index 8de01e4802..11555ea18a 100644
--- a/packages/frontend/src/index.html
+++ b/packages/frontend/src/index.html
@@ -16,13 +16,13 @@
 	<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
 	<meta
 		http-equiv="Content-Security-Policy"
-		content="default-src 'self';
+		content="default-src 'self' https://newassets.hcaptcha.com/ https://challenges.cloudflare.com/ http://localhost:7493/;
 			worker-src 'self';
-			script-src 'self' 'unsafe-eval';
+			script-src 'self' 'unsafe-eval' https://*.hcaptcha.com https://challenges.cloudflare.com;
 			style-src 'self' 'unsafe-inline';
-			img-src 'self' data: www.google.com xn--931a.moe localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000;
+			img-src 'self' data: blob: www.google.com xn--931a.moe localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000;
 			media-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000;
-			connect-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000;"
+			connect-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000 https://newassets.hcaptcha.com;"
 	/>
 	<meta property="og:site_name" content="[DEV BUILD] Misskey" />
 	<meta name="viewport" content="width=device-width, initial-scale=1">
diff --git a/packages/frontend/src/nirax.ts b/packages/frontend/src/nirax.ts
index 9755bdcb18..a56aa6419e 100644
--- a/packages/frontend/src/nirax.ts
+++ b/packages/frontend/src/nirax.ts
@@ -5,11 +5,11 @@
 
 // NIRAX --- A lightweight router
 
-import { EventEmitter } from 'eventemitter3';
 import { Component, onMounted, shallowRef, ShallowRef } from 'vue';
+import { EventEmitter } from 'eventemitter3';
 import { safeURIDecode } from '@/scripts/safe-uri-decode.js';
 
-type RouteDef = {
+export type RouteDef = {
 	path: string;
 	component: Component;
 	query?: Record<string, string>;
@@ -27,6 +27,27 @@ type ParsedPath = (string | {
 	optional?: boolean;
 })[];
 
+export type RouterEvent = {
+	change: (ctx: {
+		beforePath: string;
+		path: string;
+		resolved: Resolved;
+		key: string;
+	}) => void;
+	replace: (ctx: {
+		path: string;
+		key: string;
+	}) => void;
+	push: (ctx: {
+		beforePath: string;
+		path: string;
+		route: RouteDef | null;
+		props: Map<string, string> | null;
+		key: string;
+	}) => void;
+	same: () => void;
+}
+
 export type Resolved = { route: RouteDef; props: Map<string, string | boolean>; child?: Resolved; };
 
 function parsePath(path: string): ParsedPath {
@@ -54,26 +75,85 @@ function parsePath(path: string): ParsedPath {
 	return res;
 }
 
-export class Router extends EventEmitter<{
-	change: (ctx: {
-		beforePath: string;
-		path: string;
-		resolved: Resolved;
-		key: string;
-	}) => void;
-	replace: (ctx: {
-		path: string;
-		key: string;
-	}) => void;
-	push: (ctx: {
-		beforePath: string;
-		path: string;
-		route: RouteDef | null;
-		props: Map<string, string> | null;
-		key: string;
-	}) => void;
-	same: () => void;
-}> {
+export interface IRouter extends EventEmitter<RouterEvent> {
+	current: Resolved;
+	currentRef: ShallowRef<Resolved>;
+	currentRoute: ShallowRef<RouteDef>;
+	navHook: ((path: string, flag?: any) => boolean) | null;
+
+	resolve(path: string): Resolved | null;
+
+	getCurrentPath(): any;
+
+	getCurrentKey(): string;
+
+	push(path: string, flag?: any): void;
+
+	replace(path: string, key?: string | null): void;
+
+	/** @see EventEmitter */
+	eventNames(): Array<EventEmitter.EventNames<RouterEvent>>;
+
+	/** @see EventEmitter */
+	listeners<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T
+	): Array<EventEmitter.EventListener<RouterEvent, T>>;
+
+	/** @see EventEmitter */
+	listenerCount(
+		event: EventEmitter.EventNames<RouterEvent>
+	): number;
+
+	/** @see EventEmitter */
+	emit<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		...args: EventEmitter.EventArgs<RouterEvent, T>
+	): boolean;
+
+	/** @see EventEmitter */
+	on<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any
+	): this;
+
+	/** @see EventEmitter */
+	addListener<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any
+	): this;
+
+	/** @see EventEmitter */
+	once<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any
+	): this;
+
+	/** @see EventEmitter */
+	removeListener<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn?: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any,
+		once?: boolean | undefined
+	): this;
+
+	/** @see EventEmitter */
+	off<T extends EventEmitter.EventNames<RouterEvent>>(
+		event: T,
+		fn?: EventEmitter.EventListener<RouterEvent, T>,
+		context?: any,
+		once?: boolean | undefined
+	): this;
+
+	/** @see EventEmitter */
+	removeAllListeners(
+		event?: EventEmitter.EventNames<RouterEvent>
+	): this;
+}
+
+export class Router extends EventEmitter<RouterEvent> implements IRouter {
 	private routes: RouteDef[];
 	public current: Resolved;
 	public currentRef: ShallowRef<Resolved> = shallowRef();
@@ -277,7 +357,7 @@ export class Router extends EventEmitter<{
 	}
 }
 
-export function useScrollPositionManager(getScrollContainer: () => HTMLElement, router: Router) {
+export function useScrollPositionManager(getScrollContainer: () => HTMLElement, router: IRouter) {
 	const scrollPosStore = new Map<string, number>();
 
 	onMounted(() => {
diff --git a/packages/frontend/src/pages/admin/bot-protection.vue b/packages/frontend/src/pages/admin/bot-protection.vue
index 99b8070b71..37f8227485 100644
--- a/packages/frontend/src/pages/admin/bot-protection.vue
+++ b/packages/frontend/src/pages/admin/bot-protection.vue
@@ -10,6 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkRadios v-model="provider">
 				<option :value="null">{{ i18n.ts.none }} ({{ i18n.ts.notRecommended }})</option>
 				<option value="hcaptcha">hCaptcha</option>
+				<option value="mcaptcha">mCaptcha</option>
 				<option value="recaptcha">reCAPTCHA</option>
 				<option value="turnstile">Turnstile</option>
 			</MkRadios>
@@ -28,6 +29,24 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkCaptcha provider="hcaptcha" :sitekey="hcaptchaSiteKey || '10000000-ffff-ffff-ffff-000000000001'"/>
 				</FormSlot>
 			</template>
+			<template v-else-if="provider === 'mcaptcha'">
+				<MkInput v-model="mcaptchaSiteKey">
+					<template #prefix><i class="ti ti-key"></i></template>
+					<template #label>{{ i18n.ts.mcaptchaSiteKey }}</template>
+				</MkInput>
+				<MkInput v-model="mcaptchaSecretKey">
+					<template #prefix><i class="ti ti-key"></i></template>
+					<template #label>{{ i18n.ts.mcaptchaSecretKey }}</template>
+				</MkInput>
+				<MkInput v-model="mcaptchaInstanceUrl">
+					<template #prefix><i class="ti ti-link"></i></template>
+					<template #label>{{ i18n.ts.mcaptchaInstanceUrl }}</template>
+				</MkInput>
+				<FormSlot v-if="mcaptchaSiteKey && mcaptchaInstanceUrl">
+					<template #label>{{ i18n.ts.preview }}</template>
+					<MkCaptcha provider="mcaptcha" :sitekey="mcaptchaSiteKey" :instanceUrl="mcaptchaInstanceUrl"/>
+				</FormSlot>
+			</template>
 			<template v-else-if="provider === 'recaptcha'">
 				<MkInput v-model="recaptchaSiteKey">
 					<template #prefix><i class="ti ti-key"></i></template>
@@ -81,6 +100,9 @@ const MkCaptcha = defineAsyncComponent(() => import('@/components/MkCaptcha.vue'
 const provider = ref<CaptchaProvider | null>(null);
 const hcaptchaSiteKey = ref<string | null>(null);
 const hcaptchaSecretKey = ref<string | null>(null);
+const mcaptchaSiteKey = ref<string | null>(null);
+const mcaptchaSecretKey = ref<string | null>(null);
+const mcaptchaInstanceUrl = ref<string | null>(null);
 const recaptchaSiteKey = ref<string | null>(null);
 const recaptchaSecretKey = ref<string | null>(null);
 const turnstileSiteKey = ref<string | null>(null);
@@ -90,12 +112,18 @@ async function init() {
 	const meta = await misskeyApi('admin/meta');
 	hcaptchaSiteKey.value = meta.hcaptchaSiteKey;
 	hcaptchaSecretKey.value = meta.hcaptchaSecretKey;
+	mcaptchaSiteKey.value = meta.mcaptchaSiteKey;
+	mcaptchaSecretKey.value = meta.mcaptchaSecretKey;
+	mcaptchaInstanceUrl.value = meta.mcaptchaInstanceUrl;
 	recaptchaSiteKey.value = meta.recaptchaSiteKey;
 	recaptchaSecretKey.value = meta.recaptchaSecretKey;
 	turnstileSiteKey.value = meta.turnstileSiteKey;
 	turnstileSecretKey.value = meta.turnstileSecretKey;
 
-	provider.value = meta.enableHcaptcha ? 'hcaptcha' : meta.enableRecaptcha ? 'recaptcha' : meta.enableTurnstile ? 'turnstile' : null;
+	provider.value = meta.enableHcaptcha ? 'hcaptcha' :
+		meta.enableRecaptcha ? 'recaptcha' :
+		meta.enableTurnstile ? 'turnstile' :
+		meta.enableMcaptcha ? 'mcaptcha' : null;
 }
 
 function save() {
@@ -103,6 +131,10 @@ function save() {
 		enableHcaptcha: provider.value === 'hcaptcha',
 		hcaptchaSiteKey: hcaptchaSiteKey.value,
 		hcaptchaSecretKey: hcaptchaSecretKey.value,
+		enableMcaptcha: provider.value === 'mcaptcha',
+		mcaptchaSiteKey: mcaptchaSiteKey.value,
+		mcaptchaSecretKey: mcaptchaSecretKey.value,
+		mcaptchaInstanceUrl: mcaptchaInstanceUrl.value,
 		enableRecaptcha: provider.value === 'recaptcha',
 		recaptchaSiteKey: recaptchaSiteKey.value,
 		recaptchaSecretKey: recaptchaSecretKey.value,
diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue
index 333bac724b..7106ed7438 100644
--- a/packages/frontend/src/pages/admin/index.vue
+++ b/packages/frontend/src/pages/admin/index.vue
@@ -36,8 +36,8 @@ import { instance } from '@/instance.js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { lookupUser, lookupUserByEmail } from '@/scripts/lookup-user.js';
-import { useRouter } from '@/router.js';
 import { PageMetadata, definePageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const isEmpty = (x: string | null) => x == null || x === '';
 
diff --git a/packages/frontend/src/pages/admin/roles.edit.vue b/packages/frontend/src/pages/admin/roles.edit.vue
index db0acae24a..82e230d6a6 100644
--- a/packages/frontend/src/pages/admin/roles.edit.vue
+++ b/packages/frontend/src/pages/admin/roles.edit.vue
@@ -31,9 +31,9 @@ import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
-import { useRouter } from '@/router.js';
 import MkButton from '@/components/MkButton.vue';
 import { rolesCache } from '@/cache.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/admin/roles.role.vue b/packages/frontend/src/pages/admin/roles.role.vue
index d5ce190ef2..ff29f4ec1f 100644
--- a/packages/frontend/src/pages/admin/roles.role.vue
+++ b/packages/frontend/src/pages/admin/roles.role.vue
@@ -70,12 +70,12 @@ import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
-import { useRouter } from '@/router.js';
 import MkButton from '@/components/MkButton.vue';
 import MkUserCardMini from '@/components/MkUserCardMini.vue';
 import MkInfo from '@/components/MkInfo.vue';
 import MkPagination from '@/components/MkPagination.vue';
 import { infoImageUrl } from '@/instance.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index f7c4048b23..732affd77d 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -237,9 +237,9 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { instance } from '@/instance.js';
-import { useRouter } from '@/router.js';
 import MkFoldableSection from '@/components/MkFoldableSection.vue';
 import { ROLE_POLICIES } from '@/const.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 const baseRoleQ = ref('');
diff --git a/packages/frontend/src/pages/admin/security.vue b/packages/frontend/src/pages/admin/security.vue
index ec0c6166d0..a691d8ea1e 100644
--- a/packages/frontend/src/pages/admin/security.vue
+++ b/packages/frontend/src/pages/admin/security.vue
@@ -13,6 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<template #icon><i class="ti ti-shield"></i></template>
 					<template #label>{{ i18n.ts.botProtection }}</template>
 					<template v-if="enableHcaptcha" #suffix>hCaptcha</template>
+					<template v-else-if="enableMcaptcha" #suffix>mCaptcha</template>
 					<template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template>
 					<template v-else-if="enableTurnstile" #suffix>Turnstile</template>
 					<template v-else #suffix>{{ i18n.ts.none }} ({{ i18n.ts.notRecommended }})</template>
@@ -155,6 +156,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
 
 const summalyProxy = ref<string>('');
 const enableHcaptcha = ref<boolean>(false);
+const enableMcaptcha = ref<boolean>(false);
 const enableRecaptcha = ref<boolean>(false);
 const enableTurnstile = ref<boolean>(false);
 const sensitiveMediaDetection = ref<string>('none');
@@ -174,6 +176,7 @@ async function init() {
 	const meta = await misskeyApi('admin/meta');
 	summalyProxy.value = meta.summalyProxy;
 	enableHcaptcha.value = meta.enableHcaptcha;
+	enableMcaptcha.value = meta.enableMcaptcha;
 	enableRecaptcha.value = meta.enableRecaptcha;
 	enableTurnstile.value = meta.enableTurnstile;
 	sensitiveMediaDetection.value = meta.sensitiveMediaDetection;
diff --git a/packages/frontend/src/pages/antenna-timeline.vue b/packages/frontend/src/pages/antenna-timeline.vue
index d96ca4208b..7f07ac4987 100644
--- a/packages/frontend/src/pages/antenna-timeline.vue
+++ b/packages/frontend/src/pages/antenna-timeline.vue
@@ -30,9 +30,9 @@ import MkTimeline from '@/components/MkTimeline.vue';
 import { scroll } from '@/scripts/scroll.js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { useRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/channel-editor.vue b/packages/frontend/src/pages/channel-editor.vue
index 727778b6e6..99b93444db 100644
--- a/packages/frontend/src/pages/channel-editor.vue
+++ b/packages/frontend/src/pages/channel-editor.vue
@@ -77,12 +77,12 @@ import MkColorInput from '@/components/MkColorInput.vue';
 import { selectFile } from '@/scripts/select-file.js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { useRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
 import MkFolder from '@/components/MkFolder.vue';
 import MkSwitch from '@/components/MkSwitch.vue';
 import MkTextarea from '@/components/MkTextarea.vue';
+import { useRouter } from '@/global/router/supplier.js';
 
 const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
 
diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue
index 667563bd16..e698098f35 100644
--- a/packages/frontend/src/pages/channel.vue
+++ b/packages/frontend/src/pages/channel.vue
@@ -75,7 +75,6 @@ import MkTimeline from '@/components/MkTimeline.vue';
 import XChannelFollowButton from '@/components/MkChannelFollowButton.vue';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { useRouter } from '@/router.js';
 import { $i, iAmModerator } from '@/account.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
@@ -92,6 +91,7 @@ import { PageHeaderItem } from '@/types/page-header.js';
 import { isSupportShare } from '@/scripts/navigator.js';
 import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 import { miLocalStorage } from '@/local-storage.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/channels.vue b/packages/frontend/src/pages/channels.vue
index b7cc5cd36e..80a401eee7 100644
--- a/packages/frontend/src/pages/channels.vue
+++ b/packages/frontend/src/pages/channels.vue
@@ -58,9 +58,9 @@ import MkInput from '@/components/MkInput.vue';
 import MkRadios from '@/components/MkRadios.vue';
 import MkButton from '@/components/MkButton.vue';
 import MkFoldableSection from '@/components/MkFoldableSection.vue';
-import { useRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/drive.file.info.vue b/packages/frontend/src/pages/drive.file.info.vue
index 4c635028f3..64c3ad70ba 100644
--- a/packages/frontend/src/pages/drive.file.info.vue
+++ b/packages/frontend/src/pages/drive.file.info.vue
@@ -80,7 +80,7 @@ import { infoImageUrl } from '@/instance.js';
 import { i18n } from '@/i18n.js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { useRouter } from '@/router.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
new file mode 100644
index 0000000000..0ddee55f5f
--- /dev/null
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -0,0 +1,825 @@
+<!--
+SPDX-FileCopyrightText: syuilo and other misskey contributors
+SPDX-License-Identifier: AGPL-3.0-only
+-->
+
+<template>
+<MkStickyContainer>
+	<template #header><MkPageHeader/></template>
+	<MkSpacer :contentMax="800">
+		<div v-show="!gameStarted" :class="$style.root">
+			<div style="text-align: center;" class="_gaps">
+				<div :class="$style.frame">
+					<div :class="$style.frameInner">
+						<img src="/client-assets/drop-and-fusion/logo.png" style="display: block; max-width: 100%; max-height: 200px; margin: auto;"/>
+					</div>
+				</div>
+				<div :class="$style.frame">
+					<div :class="$style.frameInner">
+						<div class="_gaps" style="padding: 16px;">
+							<MkSelect v-model="gameMode">
+								<option value="normal">NORMAL</option>
+								<option value="square">SQUARE</option>
+							</MkSelect>
+							<MkButton primary gradate large rounded inline @click="start">{{ i18n.ts.start }}</MkButton>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+		<div v-show="gameStarted" class="_gaps_s" :class="$style.root">
+			<div style="display: flex;">
+				<div :class="$style.frame" style="flex: 1; margin-right: 10px;">
+					<div :class="$style.frameInner">
+						<b>BUBBLE GAME</b>
+						<div>- {{ gameMode }} -</div>
+					</div>
+				</div>
+				<div :class="[$style.frame, $style.stock]" style="margin-left: auto;">
+					<div :class="$style.frameInner" style="text-align: center;">
+						NEXT >>>
+						<TransitionGroup
+							:enterActiveClass="$style.transition_stock_enterActive"
+							:leaveActiveClass="$style.transition_stock_leaveActive"
+							:enterFromClass="$style.transition_stock_enterFrom"
+							:leaveToClass="$style.transition_stock_leaveTo"
+							:moveClass="$style.transition_stock_move"
+						>
+							<div v-for="x in stock" :key="x.id" style="display: inline-block;">
+								<img :src="game.getTextureImageUrl(x.mono)" style="width: 32px;"/>
+							</div>
+						</TransitionGroup>
+					</div>
+				</div>
+			</div>
+			<div :class="$style.main" @contextmenu.stop.prevent>
+				<div ref="containerEl" :class="[$style.container, { [$style.gameOver]: gameOver }]" @click.stop.prevent="onClick" @touchmove.stop.prevent="onTouchmove" @touchend="onTouchend" @mousemove="onMousemove">
+					<img v-if="defaultStore.state.darkMode" src="/client-assets/drop-and-fusion/frame-dark.svg" :class="$style.mainFrameImg"/>
+					<img v-else src="/client-assets/drop-and-fusion/frame-light.svg" :class="$style.mainFrameImg"/>
+					<canvas ref="canvasEl" :class="$style.canvas"/>
+					<Transition
+						:enterActiveClass="$style.transition_combo_enterActive"
+						:leaveActiveClass="$style.transition_combo_leaveActive"
+						:enterFromClass="$style.transition_combo_enterFrom"
+						:leaveToClass="$style.transition_combo_leaveTo"
+						:moveClass="$style.transition_combo_move"
+					>
+						<div v-show="combo > 1" :class="$style.combo" :style="{ fontSize: `${100 + ((comboPrev - 2) * 15)}%` }">{{ comboPrev }} Chain!</div>
+					</Transition>
+					<img v-if="currentPick" src="/client-assets/drop-and-fusion/dropper.png" :class="$style.dropper" :style="{ left: dropperX + 'px' }"/>
+					<Transition
+						:enterActiveClass="$style.transition_picked_enterActive"
+						:leaveActiveClass="$style.transition_picked_leaveActive"
+						:enterFromClass="$style.transition_picked_enterFrom"
+						:leaveToClass="$style.transition_picked_leaveTo"
+						:moveClass="$style.transition_picked_move"
+						mode="out-in"
+					>
+						<img v-if="currentPick" :key="currentPick.id" :src="game.getTextureImageUrl(currentPick.mono)" :class="$style.currentMono" :style="{ top: -(currentPick?.mono.size / 2) + 'px', left: (dropperX - (currentPick?.mono.size / 2)) + 'px', width: `${currentPick?.mono.size}px` }"/>
+					</Transition>
+					<template v-if="dropReady && currentPick">
+						<img src="/client-assets/drop-and-fusion/drop-arrow.svg" :class="$style.currentMonoArrow" :style="{ top: (currentPick.mono.size / 2) + 10 + 'px', left: (dropperX - 10) + 'px', width: `20px` }"/>
+						<div :class="$style.dropGuide" :style="{ left: (dropperX - 2) + 'px' }"/>
+					</template>
+					<div v-if="gameOver" :class="$style.gameOverLabel">
+						<div class="_gaps_s">
+							<img src="/client-assets/drop-and-fusion/gameover.png" style="width: 200px; max-width: 100%; display: block; margin: auto; margin-bottom: -5px;"/>
+							<div>SCORE: <MkNumber :value="score"/></div>
+							<div>MAX CHAIN: <MkNumber :value="maxCombo"/></div>
+							<div class="_buttonsCenter">
+								<MkButton primary rounded @click="restart">Restart</MkButton>
+								<MkButton primary rounded @click="share">Share</MkButton>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+			<div style="display: flex;">
+				<div :class="$style.frame" style="flex: 1; margin-right: 10px;">
+					<div :class="$style.frameInner">
+						<div>SCORE: <b><MkNumber :value="score"/></b> (MAX CHAIN: <b><MkNumber :value="maxCombo"/></b>)</div>
+						<div>HIGH SCORE: <b v-if="highScore"><MkNumber :value="highScore"/></b><b v-else>-</b></div>
+					</div>
+				</div>
+				<div :class="[$style.frame]" style="margin-left: auto;">
+					<div :class="$style.frameInner" style="text-align: center;">
+						<div @click="showConfig = !showConfig"><i class="ti ti-settings"></i></div>
+					</div>
+				</div>
+			</div>
+			<div v-if="showConfig" :class="$style.frame">
+				<div :class="$style.frameInner">
+					<MkRange v-model="bgmVolume" :min="0" :max="1" :step="0.0025" :textConverter="(v) => `${Math.floor(v * 100)}%`" :continuousUpdate="true">
+						<template #label>BGM {{ i18n.ts.volume }}</template>
+					</MkRange>
+				</div>
+			</div>
+			<div v-if="showConfig" :class="$style.frame">
+				<div :class="$style.frameInner">
+					<div>Credit</div>
+					<div>BGM: @ys@misskey.design</div>
+				</div>
+			</div>
+			<div :class="$style.frame">
+				<div :class="$style.frameInner">
+					<MkButton @click="restart">Restart</MkButton>
+				</div>
+			</div>
+		</div>
+	</MkSpacer>
+</MkStickyContainer>
+</template>
+
+<script lang="ts" setup>
+import { onDeactivated, ref, shallowRef, watch } from 'vue';
+import * as Misskey from 'misskey-js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import MkRippleEffect from '@/components/MkRippleEffect.vue';
+import * as os from '@/os.js';
+import MkNumber from '@/components/MkNumber.vue';
+import MkPlusOneEffect from '@/components/MkPlusOneEffect.vue';
+import MkButton from '@/components/MkButton.vue';
+import { claimAchievement } from '@/scripts/achievements.js';
+import { defaultStore } from '@/store.js';
+import { misskeyApi } from '@/scripts/misskey-api.js';
+import { i18n } from '@/i18n.js';
+import { useInterval } from '@/scripts/use-interval.js';
+import MkSelect from '@/components/MkSelect.vue';
+import { apiUrl } from '@/config.js';
+import { $i } from '@/account.js';
+import { DropAndFusionGame, Mono } from '@/scripts/drop-and-fusion-engine.js';
+import * as sound from '@/scripts/sound.js';
+import MkRange from '@/components/MkRange.vue';
+
+const containerEl = shallowRef<HTMLElement>();
+const canvasEl = shallowRef<HTMLCanvasElement>();
+const dropperX = ref(0);
+
+const NORMAL_BASE_SIZE = 30;
+const NORAML_MONOS: Mono[] = [{
+	id: '9377076d-c980-4d83-bdaf-175bc58275b7',
+	level: 10,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'circle',
+	score: 512,
+	dropCandidate: false,
+	sfxPitch: 0.25,
+	img: '/client-assets/drop-and-fusion/exploding_head.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: 'be9f38d2-b267-4b1a-b420-904e22e80568',
+	level: 9,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'circle',
+	score: 256,
+	dropCandidate: false,
+	sfxPitch: 0.5,
+	img: '/client-assets/drop-and-fusion/face_with_symbols_on_mouth.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: 'beb30459-b064-4888-926b-f572e4e72e0c',
+	level: 8,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'circle',
+	score: 128,
+	dropCandidate: false,
+	sfxPitch: 0.75,
+	img: '/client-assets/drop-and-fusion/cold_face.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: 'feab6426-d9d8-49ae-849c-048cdbb6cdf0',
+	level: 7,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'circle',
+	score: 64,
+	dropCandidate: false,
+	sfxPitch: 1,
+	img: '/client-assets/drop-and-fusion/zany_face.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: 'd6d8fed6-6d18-4726-81a1-6cf2c974df8a',
+	level: 6,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'circle',
+	score: 32,
+	dropCandidate: false,
+	sfxPitch: 1.5,
+	img: '/client-assets/drop-and-fusion/pleading_face.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '249c728e-230f-4332-bbbf-281c271c75b2',
+	level: 5,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'circle',
+	score: 16,
+	dropCandidate: true,
+	sfxPitch: 2,
+	img: '/client-assets/drop-and-fusion/face_with_open_mouth.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '23d67613-d484-4a93-b71e-3e81b19d6186',
+	level: 4,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25 * 1.25,
+	shape: 'circle',
+	score: 8,
+	dropCandidate: true,
+	sfxPitch: 2.5,
+	img: '/client-assets/drop-and-fusion/smiling_face_with_sunglasses.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '3cbd0add-ad7d-4685-bad0-29f6dddc0b99',
+	level: 3,
+	size: NORMAL_BASE_SIZE * 1.25 * 1.25,
+	shape: 'circle',
+	score: 4,
+	dropCandidate: true,
+	sfxPitch: 3,
+	img: '/client-assets/drop-and-fusion/grinning_squinting_face.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '8f86d4f4-ee02-41bf-ad38-1ce0ae457fb5',
+	level: 2,
+	size: NORMAL_BASE_SIZE * 1.25,
+	shape: 'circle',
+	score: 2,
+	dropCandidate: true,
+	sfxPitch: 3.5,
+	img: '/client-assets/drop-and-fusion/smiling_face_with_hearts.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '64ec4add-ce39-42b4-96cb-33908f3f118d',
+	level: 1,
+	size: NORMAL_BASE_SIZE,
+	shape: 'circle',
+	score: 1,
+	dropCandidate: true,
+	sfxPitch: 4,
+	img: '/client-assets/drop-and-fusion/heart_suit.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}];
+
+const SQUARE_BASE_SIZE = 28;
+const SQUARE_MONOS: Mono[] = [{
+	id: 'f75fd0ba-d3d4-40a4-9712-b470e45b0525',
+	level: 10,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 512,
+	dropCandidate: false,
+	sfxPitch: 0.25,
+	img: '/client-assets/drop-and-fusion/keycap_10.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '7b70f4af-1c01-45fd-af72-61b1f01e03d1',
+	level: 9,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 256,
+	dropCandidate: false,
+	sfxPitch: 0.5,
+	img: '/client-assets/drop-and-fusion/keycap_9.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '41607ef3-b6d6-4829-95b6-3737bf8bb956',
+	level: 8,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 128,
+	dropCandidate: false,
+	sfxPitch: 0.75,
+	img: '/client-assets/drop-and-fusion/keycap_8.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '8a8310d2-0374-460f-bb50-ca9cd3ee3416',
+	level: 7,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 64,
+	dropCandidate: false,
+	sfxPitch: 1,
+	img: '/client-assets/drop-and-fusion/keycap_7.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '1092e069-fe1a-450b-be97-b5d477ec398c',
+	level: 6,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 32,
+	dropCandidate: false,
+	sfxPitch: 1.5,
+	img: '/client-assets/drop-and-fusion/keycap_6.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '2294734d-7bb8-4781-bb7b-ef3820abf3d0',
+	level: 5,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25 * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 16,
+	dropCandidate: true,
+	sfxPitch: 2,
+	img: '/client-assets/drop-and-fusion/keycap_5.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: 'ea8a61af-e350-45f7-ba6a-366fcd65692a',
+	level: 4,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 8,
+	dropCandidate: true,
+	sfxPitch: 2.5,
+	img: '/client-assets/drop-and-fusion/keycap_4.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: 'd0c74815-fc1c-4fbe-9953-c92e4b20f919',
+	level: 3,
+	size: SQUARE_BASE_SIZE * 1.25 * 1.25,
+	shape: 'rectangle',
+	score: 4,
+	dropCandidate: true,
+	sfxPitch: 3,
+	img: '/client-assets/drop-and-fusion/keycap_3.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: 'd8fbd70e-611d-402d-87da-1a7fd8cd2c8d',
+	level: 2,
+	size: SQUARE_BASE_SIZE * 1.25,
+	shape: 'rectangle',
+	score: 2,
+	dropCandidate: true,
+	sfxPitch: 3.5,
+	img: '/client-assets/drop-and-fusion/keycap_2.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}, {
+	id: '35e476ee-44bd-4711-ad42-87be245d3efd',
+	level: 1,
+	size: SQUARE_BASE_SIZE,
+	shape: 'rectangle',
+	score: 1,
+	dropCandidate: true,
+	sfxPitch: 4,
+	img: '/client-assets/drop-and-fusion/keycap_1.png',
+	imgSize: 256,
+	spriteScale: 1.12,
+}];
+
+const GAME_WIDTH = 450;
+const GAME_HEIGHT = 600;
+
+let viewScaleX = 1;
+let viewScaleY = 1;
+const currentPick = shallowRef<{ id: string; mono: Mono } | null>(null);
+const stock = shallowRef<{ id: string; mono: Mono }[]>([]);
+const score = ref(0);
+const combo = ref(0);
+const comboPrev = ref(0);
+const maxCombo = ref(0);
+const dropReady = ref(true);
+const gameMode = ref<'normal' | 'square'>('normal');
+const gameOver = ref(false);
+const gameStarted = ref(false);
+const highScore = ref<number | null>(null);
+const showConfig = ref(false);
+const bgmVolume = ref(0.1);
+
+let game: DropAndFusionGame;
+let containerElRect: DOMRect | null = null;
+
+function onClick(ev: MouseEvent) {
+	if (!containerElRect) return;
+	const x = (ev.clientX - containerElRect.left) / viewScaleX;
+	game.drop(x);
+}
+
+function onTouchend(ev: TouchEvent) {
+	if (!containerElRect) return;
+	const x = (ev.changedTouches[0].clientX - containerElRect.left) / viewScaleX;
+	game.drop(x);
+}
+
+function onMousemove(ev: MouseEvent) {
+	if (!containerElRect) return;
+	const x = (ev.clientX - containerElRect.left);
+	moveDropper(containerElRect, x);
+}
+
+function onTouchmove(ev: TouchEvent) {
+	if (!containerElRect) return;
+	const x = (ev.touches[0].clientX - containerElRect.left);
+	moveDropper(containerElRect, x);
+}
+
+function moveDropper(rect: DOMRect, x: number) {
+	dropperX.value = Math.min(rect.width * ((GAME_WIDTH - game.PLAYAREA_MARGIN) / GAME_WIDTH), Math.max(rect.width * (game.PLAYAREA_MARGIN / GAME_WIDTH), x));
+}
+
+function restart() {
+	game.dispose();
+	gameOver.value = false;
+	currentPick.value = null;
+	dropReady.value = true;
+	stock.value = [];
+	score.value = 0;
+	combo.value = 0;
+	comboPrev.value = 0;
+	gameStarted.value = false;
+}
+
+function attachGameEvents() {
+	game.addListener('changeScore', value => {
+		score.value = value;
+	});
+
+	game.addListener('changeCombo', value => {
+		if (value === 0) {
+			comboPrev.value = combo.value;
+		} else {
+			comboPrev.value = value;
+		}
+		maxCombo.value = Math.max(maxCombo.value, value);
+		combo.value = value;
+	});
+
+	game.addListener('changeStock', value => {
+		currentPick.value = JSON.parse(JSON.stringify(value[0]));
+		stock.value = JSON.parse(JSON.stringify(value.slice(1)));
+	});
+
+	game.addListener('dropped', () => {
+		dropReady.value = false;
+		window.setTimeout(() => {
+			if (!gameOver.value) {
+				dropReady.value = true;
+			}
+		}, game.DROP_INTERVAL);
+	});
+
+	game.addListener('fusioned', (x, y, scoreDelta) => {
+		if (!canvasEl.value) return;
+
+		const rect = canvasEl.value.getBoundingClientRect();
+		const domX = rect.left + (x * viewScaleX);
+		const domY = rect.top + (y * viewScaleY);
+		os.popup(MkRippleEffect, { x: domX, y: domY }, {}, 'end');
+		os.popup(MkPlusOneEffect, { x: domX, y: domY, value: scoreDelta }, {}, 'end');
+	});
+
+	game.addListener('monoAdded', (mono) => {
+		// 実績関連
+		if (mono.level === 10) {
+			claimAchievement('bubbleGameExplodingHead');
+
+			const monos = game.getActiveMonos();
+			if (monos.filter(x => x.level === 10).length >= 2) {
+				claimAchievement('bubbleGameDoubleExplodingHead');
+			}
+		}
+	});
+
+	game.addListener('gameOver', () => {
+		currentPick.value = null;
+		dropReady.value = false;
+		gameOver.value = true;
+
+		if (score.value > (highScore.value ?? 0)) {
+			highScore.value = score.value;
+
+			misskeyApi('i/registry/set', {
+				scope: ['dropAndFusionGame'],
+				key: 'highScore:' + gameMode.value,
+				value: highScore.value,
+			});
+		}
+	});
+}
+
+let bgmNodes: ReturnType<typeof sound.createSourceNode> = null;
+
+async function start() {
+	try {
+		highScore.value = await misskeyApi('i/registry/get', {
+			scope: ['dropAndFusionGame'],
+			key: 'highScore:' + gameMode.value,
+		});
+	} catch (err) {
+		highScore.value = null;
+	}
+
+	game = new DropAndFusionGame({
+		width: GAME_WIDTH,
+		height: GAME_HEIGHT,
+		canvas: canvasEl.value!,
+		...(
+			gameMode.value === 'normal' ? {
+				monoDefinitions: NORAML_MONOS,
+			} : {
+				monoDefinitions: SQUARE_MONOS,
+			}
+		),
+	});
+	attachGameEvents();
+	os.promiseDialog(game.load(), async () => {
+		game.start();
+		gameStarted.value = true;
+
+		if (bgmNodes) {
+			bgmNodes.soundSource.stop();
+			bgmNodes = null;
+		}
+		const bgmBuffer = await sound.loadAudio('/client-assets/drop-and-fusion/bgm_1.mp3');
+		if (!bgmBuffer) return;
+		bgmNodes = sound.createSourceNode(bgmBuffer, bgmVolume.value);
+		if (!bgmNodes) return;
+		bgmNodes.soundSource.loop = true;
+		bgmNodes.soundSource.start();
+	});
+}
+
+watch(bgmVolume, (value) => {
+	if (bgmNodes) {
+		bgmNodes.gainNode.gain.value = value;
+	}
+});
+
+function getGameImageDriveFile() {
+	return new Promise<Misskey.entities.DriveFile | null>(res => {
+		const dcanvas = document.createElement('canvas');
+		dcanvas.width = GAME_WIDTH;
+		dcanvas.height = GAME_HEIGHT;
+		const ctx = dcanvas.getContext('2d');
+		if (!ctx || !canvasEl.value) return res(null);
+		const dimage = new Image();
+		dimage.src = '/client-assets/drop-and-fusion/frame-light.svg';
+		dimage.addEventListener('load', () => {
+			ctx.fillStyle = '#fff';
+			ctx.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
+			ctx.drawImage(dimage, 0, 0, GAME_WIDTH, GAME_HEIGHT);
+			ctx.drawImage(canvasEl.value!, 0, 0, GAME_WIDTH, GAME_HEIGHT);
+
+			dcanvas.toBlob(blob => {
+				if (!blob) return res(null);
+				if ($i == null) return res(null);
+				const formData = new FormData();
+				formData.append('file', blob);
+				formData.append('name', `bubble-game-${Date.now()}.png`);
+				formData.append('isSensitive', 'false');
+				formData.append('comment', 'null');
+				formData.append('i', $i.token);
+				if (defaultStore.state.uploadFolder) {
+					formData.append('folderId', defaultStore.state.uploadFolder);
+				}
+
+				window.fetch(apiUrl + '/drive/files/create', {
+					method: 'POST',
+					body: formData,
+				})
+					.then(response => response.json())
+					.then(f => {
+						res(f);
+					});
+			}, 'image/png');
+
+			dcanvas.remove();
+		});
+	});
+}
+
+async function share() {
+	const uploading = getGameImageDriveFile();
+	os.promiseDialog(uploading);
+	const file = await uploading;
+	if (!file) return;
+	os.post({
+		initialText: `#BubbleGame
+MODE: ${gameMode.value}
+SCORE: ${score.value} (MAX CHAIN: ${maxCombo.value})})`,
+		initialFiles: [file],
+	});
+}
+
+useInterval(() => {
+	if (!canvasEl.value) return;
+	const actualCanvasWidth = canvasEl.value.getBoundingClientRect().width;
+	const actualCanvasHeight = canvasEl.value.getBoundingClientRect().height;
+	viewScaleX = actualCanvasWidth / GAME_WIDTH;
+	viewScaleY = actualCanvasHeight / GAME_HEIGHT;
+	containerElRect = containerEl.value?.getBoundingClientRect() ?? null;
+}, 1000, { immediate: false, afterMounted: true });
+
+onDeactivated(() => {
+	game.dispose();
+});
+
+definePageMetadata({
+	title: i18n.ts.bubbleGame,
+	icon: 'ti ti-apple',
+});
+</script>
+
+<style lang="scss" module>
+.transition_stock_move,
+.transition_stock_enterActive,
+.transition_stock_leaveActive {
+	transition: opacity 0.4s cubic-bezier(0,.5,.5,1), transform 0.4s cubic-bezier(0,.5,.5,1) !important;
+}
+.transition_stock_enterFrom,
+.transition_stock_leaveTo {
+	opacity: 0;
+	transform: scale(0.7);
+}
+.transition_stock_leaveActive {
+	position: absolute;
+}
+
+.transition_picked_move,
+.transition_picked_enterActive {
+	transition: opacity 0.5s cubic-bezier(0,.5,.5,1), transform 0.5s cubic-bezier(0,.5,.5,1) !important;
+}
+.transition_picked_leaveActive {
+	transition: all 0s !important;
+}
+.transition_picked_enterFrom,
+.transition_picked_leaveTo {
+	opacity: 0;
+	transform: translateY(-50px);
+}
+.transition_picked_leaveActive {
+	position: absolute;
+}
+
+.transition_combo_move,
+.transition_combo_enterActive {
+	transition: all 0s !important;
+}
+.transition_combo_leaveActive {
+	transition: opacity 0.4s cubic-bezier(0,.5,.5,1), transform 0.4s cubic-bezier(0,.5,.5,1) !important;
+}
+.transition_combo_enterFrom,
+.transition_combo_leaveTo {
+	opacity: 0;
+	transform: scale(0.7);
+}
+.transition_combo_leaveActive {
+	position: absolute;
+}
+
+.root {
+	margin: 0 auto;
+	max-width: 600px;
+	user-select: none;
+
+	* {
+		user-select: none;
+	}
+}
+
+.frame {
+	padding: 7px;
+	background: #8C4F26;
+	box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
+	border-radius: 10px;
+}
+.frameInner {
+	padding: 4px 8px;
+	background: #F1E8DC;
+	box-shadow: 0 0 2px 1px #ce8a5c, inset 0 0 1px 1px #693410;
+	border-radius: 6px;
+	color: #693410;
+}
+
+.main {
+	position: relative;
+}
+
+.mainFrameImg {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	// なんかiOSでちらつく
+	//filter: drop-shadow(0 6px 16px #0007);
+	pointer-events: none;
+	user-select: none;
+}
+
+.canvas {
+	position: relative;
+	display: block;
+	z-index: 1;
+	margin-top: -50px;
+	width: 100% !important;
+	height: auto !important;
+	pointer-events: none;
+	user-select: none;
+}
+
+.container {
+	position: relative;
+}
+
+.stock {
+	pointer-events: none;
+	user-select: none;
+}
+
+.combo {
+	position: absolute;
+	z-index: 3;
+	top: 50%;
+	width: 100%;
+	text-align: center;
+	font-weight: bold;
+	font-style: oblique;
+	color: #fff;
+	-webkit-text-stroke: 1px rgb(255, 145, 0);
+	text-shadow: 0 0 6px #0005;
+	pointer-events: none;
+	user-select: none;
+}
+
+.currentMono {
+	position: absolute;
+	margin-top: 80px;
+	z-index: 2;
+	filter: drop-shadow(0 6px 16px #0007);
+	pointer-events: none;
+	user-select: none;
+}
+
+.dropper {
+	position: absolute;
+	top: 0;
+	width: 70px;
+	margin-top: -10px;
+	margin-left: -30px;
+	z-index: 2;
+	filter: drop-shadow(0 6px 16px #0007);
+	pointer-events: none;
+	user-select: none;
+}
+
+.currentMonoArrow {
+	position: absolute;
+	margin-top: 100px;
+	z-index: 3;
+	animation: currentMonoArrow 2s ease infinite;
+	pointer-events: none;
+	user-select: none;
+}
+
+.dropGuide {
+	position: absolute;
+	top: 120px;
+	z-index: 3;
+	width: 3px;
+	height: calc(100% - 120px);
+	background: #f002;
+	pointer-events: none;
+	user-select: none;
+}
+
+.gameOverLabel {
+	position: absolute;
+	z-index: 10;
+	top: 50%;
+	width: 100%;
+	padding: 16px;
+	box-sizing: border-box;
+	background: #0007;
+	color: #fff;
+	text-align: center;
+	font-weight: bold;
+}
+
+.gameOver {
+	.canvas {
+		filter: grayscale(1);
+	}
+}
+
+@keyframes currentMonoArrow {
+	0% { transform: translateY(0); }
+	25% { transform: translateY(-8px); }
+	50% { transform: translateY(0); }
+	75% { transform: translateY(-8px); }
+	100% { transform: translateY(0); }
+}
+</style>
diff --git a/packages/frontend/src/pages/flash/flash-edit.vue b/packages/frontend/src/pages/flash/flash-edit.vue
index ce077779c8..8298dc6d79 100644
--- a/packages/frontend/src/pages/flash/flash-edit.vue
+++ b/packages/frontend/src/pages/flash/flash-edit.vue
@@ -45,7 +45,7 @@ import MkTextarea from '@/components/MkTextarea.vue';
 import MkCodeEditor from '@/components/MkCodeEditor.vue';
 import MkInput from '@/components/MkInput.vue';
 import MkSelect from '@/components/MkSelect.vue';
-import { useRouter } from '@/router.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const PRESET_DEFAULT = `/// @ 0.16.0
 
diff --git a/packages/frontend/src/pages/flash/flash-index.vue b/packages/frontend/src/pages/flash/flash-index.vue
index e0b9f87d46..7852018894 100644
--- a/packages/frontend/src/pages/flash/flash-index.vue
+++ b/packages/frontend/src/pages/flash/flash-index.vue
@@ -42,9 +42,9 @@ import { computed, ref } from 'vue';
 import MkFlashPreview from '@/components/MkFlashPreview.vue';
 import MkPagination from '@/components/MkPagination.vue';
 import MkButton from '@/components/MkButton.vue';
-import { useRouter } from '@/router.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/follow.vue b/packages/frontend/src/pages/follow.vue
index 5a21604080..eefef828bd 100644
--- a/packages/frontend/src/pages/follow.vue
+++ b/packages/frontend/src/pages/follow.vue
@@ -13,9 +13,9 @@ import { } from 'vue';
 import * as Misskey from 'misskey-js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { mainRouter } from '@/router.js';
 import { i18n } from '@/i18n.js';
 import { defaultStore } from '@/store.js';
+import { mainRouter } from '@/global/router/main.js';
 
 async function follow(user): Promise<void> {
 	const { canceled } = await os.confirm({
diff --git a/packages/frontend/src/pages/gallery/edit.vue b/packages/frontend/src/pages/gallery/edit.vue
index e0c7654531..f7db01ce95 100644
--- a/packages/frontend/src/pages/gallery/edit.vue
+++ b/packages/frontend/src/pages/gallery/edit.vue
@@ -48,9 +48,9 @@ import FormSuspense from '@/components/form/suspense.vue';
 import { selectFiles } from '@/scripts/select-file.js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { useRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/gallery/index.vue b/packages/frontend/src/pages/gallery/index.vue
index 8d9ac07805..0198ab9700 100644
--- a/packages/frontend/src/pages/gallery/index.vue
+++ b/packages/frontend/src/pages/gallery/index.vue
@@ -53,7 +53,7 @@ import MkPagination from '@/components/MkPagination.vue';
 import MkGalleryPostPreview from '@/components/MkGalleryPostPreview.vue';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
-import { useRouter } from '@/router.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/gallery/post.vue b/packages/frontend/src/pages/gallery/post.vue
index f71fe0f260..dcd427d6b4 100644
--- a/packages/frontend/src/pages/gallery/post.vue
+++ b/packages/frontend/src/pages/gallery/post.vue
@@ -72,13 +72,13 @@ import MkPagination from '@/components/MkPagination.vue';
 import MkGalleryPostPreview from '@/components/MkGalleryPostPreview.vue';
 import MkFollowButton from '@/components/MkFollowButton.vue';
 import { url } from '@/config.js';
-import { useRouter } from '@/router.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { defaultStore } from '@/store.js';
 import { $i } from '@/account.js';
 import { isSupportShare } from '@/scripts/navigator.js';
 import copyToClipboard from '@/scripts/copy-to-clipboard.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/my-antennas/create.vue b/packages/frontend/src/pages/my-antennas/create.vue
index c5b1b54222..61b9424bdd 100644
--- a/packages/frontend/src/pages/my-antennas/create.vue
+++ b/packages/frontend/src/pages/my-antennas/create.vue
@@ -14,8 +14,8 @@ import { ref } from 'vue';
 import XAntenna from './editor.vue';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
-import { useRouter } from '@/router.js';
 import { antennasCache } from '@/cache.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/my-antennas/edit.vue b/packages/frontend/src/pages/my-antennas/edit.vue
index 0648f5340f..b4ca7cc9f8 100644
--- a/packages/frontend/src/pages/my-antennas/edit.vue
+++ b/packages/frontend/src/pages/my-antennas/edit.vue
@@ -15,9 +15,9 @@ import * as Misskey from 'misskey-js';
 import XAntenna from './editor.vue';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { i18n } from '@/i18n.js';
-import { useRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { antennasCache } from '@/cache.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/my-lists/list.vue b/packages/frontend/src/pages/my-lists/list.vue
index 5798070ad8..85775a2fdd 100644
--- a/packages/frontend/src/pages/my-lists/list.vue
+++ b/packages/frontend/src/pages/my-lists/list.vue
@@ -58,7 +58,6 @@ import * as Misskey from 'misskey-js';
 import MkButton from '@/components/MkButton.vue';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { mainRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
 import { userPage } from '@/filters/user.js';
@@ -70,6 +69,7 @@ import { userListsCache } from '@/cache.js';
 import { signinRequired } from '@/account.js';
 import { defaultStore } from '@/store.js';
 import MkPagination from '@/components/MkPagination.vue';
+import { mainRouter } from '@/global/router/main.js';
 
 const $i = signinRequired();
 
diff --git a/packages/frontend/src/pages/page-editor/page-editor.vue b/packages/frontend/src/pages/page-editor/page-editor.vue
index 496a8c3274..6db72dccba 100644
--- a/packages/frontend/src/pages/page-editor/page-editor.vue
+++ b/packages/frontend/src/pages/page-editor/page-editor.vue
@@ -73,10 +73,10 @@ import { url } from '@/config.js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { selectFile } from '@/scripts/select-file.js';
-import { mainRouter } from '@/router.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { $i } from '@/account.js';
+import { mainRouter } from '@/global/router/main.js';
 
 const props = defineProps<{
 	initPageId?: string;
diff --git a/packages/frontend/src/pages/pages.vue b/packages/frontend/src/pages/pages.vue
index bc51b55c7f..22ab9ced09 100644
--- a/packages/frontend/src/pages/pages.vue
+++ b/packages/frontend/src/pages/pages.vue
@@ -40,9 +40,9 @@ import { computed, ref } from 'vue';
 import MkPagePreview from '@/components/MkPagePreview.vue';
 import MkPagination from '@/components/MkPagination.vue';
 import MkButton from '@/components/MkButton.vue';
-import { useRouter } from '@/router.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/reset-password.vue b/packages/frontend/src/pages/reset-password.vue
index c9d193b787..d8dec27513 100644
--- a/packages/frontend/src/pages/reset-password.vue
+++ b/packages/frontend/src/pages/reset-password.vue
@@ -25,8 +25,8 @@ import MkInput from '@/components/MkInput.vue';
 import MkButton from '@/components/MkButton.vue';
 import * as os from '@/os.js';
 import { i18n } from '@/i18n.js';
-import { mainRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { mainRouter } from '@/global/router/main.js';
 
 const props = defineProps<{
 	token?: string;
diff --git a/packages/frontend/src/pages/search.note.vue b/packages/frontend/src/pages/search.note.vue
index 1b12910a38..811218faf5 100644
--- a/packages/frontend/src/pages/search.note.vue
+++ b/packages/frontend/src/pages/search.note.vue
@@ -51,8 +51,8 @@ import { i18n } from '@/i18n.js';
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import MkFoldableSection from '@/components/MkFoldableSection.vue';
-import { useRouter } from '@/router.js';
 import MkFolder from '@/components/MkFolder.vue';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/search.user.vue b/packages/frontend/src/pages/search.user.vue
index 5e9048ee57..82cedc9833 100644
--- a/packages/frontend/src/pages/search.user.vue
+++ b/packages/frontend/src/pages/search.user.vue
@@ -34,7 +34,7 @@ import { i18n } from '@/i18n.js';
 import * as os from '@/os.js';
 import MkFoldableSection from '@/components/MkFoldableSection.vue';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { useRouter } from '@/router.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/settings/import-export.vue b/packages/frontend/src/pages/settings/import-export.vue
index 990eff99c1..70d718f1ab 100644
--- a/packages/frontend/src/pages/settings/import-export.vue
+++ b/packages/frontend/src/pages/settings/import-export.vue
@@ -21,6 +21,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkButton primary :class="$style.button" inline @click="exportFavorites()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
 		</MkFolder>
 	</FormSection>
+	<FormSection>
+		<template #label><i class="ti ti-star"></i> {{ i18n.ts._exportOrImport.clips }}</template>
+		<MkFolder>
+			<template #label>{{ i18n.ts.export }}</template>
+			<template #icon><i class="ti ti-download"></i></template>
+			<MkButton primary :class="$style.button" inline @click="exportClips()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
+		</MkFolder>
+	</FormSection>
 	<FormSection>
 		<template #label><i class="ti ti-users"></i> {{ i18n.ts._exportOrImport.followingList }}</template>
 		<div class="_gaps_s">
@@ -157,6 +165,10 @@ const exportFavorites = () => {
 	misskeyApi('i/export-favorites', {}).then(onExportSuccess).catch(onError);
 };
 
+const exportClips = () => {
+	misskeyApi('i/export-clips', {}).then(onExportSuccess).catch(onError);
+};
+
 const exportFollowing = () => {
 	misskeyApi('i/export-following', {
 		excludeMuting: excludeMutingUsers.value,
diff --git a/packages/frontend/src/pages/settings/index.vue b/packages/frontend/src/pages/settings/index.vue
index ee0188873e..be443033bc 100644
--- a/packages/frontend/src/pages/settings/index.vue
+++ b/packages/frontend/src/pages/settings/index.vue
@@ -35,9 +35,9 @@ import MkSuperMenu from '@/components/MkSuperMenu.vue';
 import { signout, $i } from '@/account.js';
 import { clearCache } from '@/scripts/clear-cache.js';
 import { instance } from '@/instance.js';
-import { useRouter } from '@/router.js';
 import { PageMetadata, definePageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import * as os from '@/os.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const indexInfo = {
 	title: i18n.ts.settings,
diff --git a/packages/frontend/src/pages/settings/webhook.edit.vue b/packages/frontend/src/pages/settings/webhook.edit.vue
index 9eb344bd46..a122c4c819 100644
--- a/packages/frontend/src/pages/settings/webhook.edit.vue
+++ b/packages/frontend/src/pages/settings/webhook.edit.vue
@@ -51,7 +51,7 @@ import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
-import { useRouter } from '@/router.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/user-list-timeline.vue b/packages/frontend/src/pages/user-list-timeline.vue
index 19c376c77b..10a21ef20d 100644
--- a/packages/frontend/src/pages/user-list-timeline.vue
+++ b/packages/frontend/src/pages/user-list-timeline.vue
@@ -29,9 +29,9 @@ import * as Misskey from 'misskey-js';
 import MkTimeline from '@/components/MkTimeline.vue';
 import { scroll } from '@/scripts/scroll.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
-import { useRouter } from '@/router.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 const router = useRouter();
 
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index 5258165d7c..ed9722b7ed 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -166,13 +166,13 @@ import { getUserMenu } from '@/scripts/get-user-menu.js';
 import number from '@/filters/number.js';
 import { userPage } from '@/filters/user.js';
 import * as os from '@/os.js';
-import { useRouter } from '@/router.js';
 import { i18n } from '@/i18n.js';
 import { $i, iAmModerator } from '@/account.js';
 import { dateString } from '@/filters/date.js';
 import { confetti } from '@/scripts/confetti.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { isFollowingVisibleForMe, isFollowersVisibleForMe } from '@/scripts/isFfVisibleForMe.js';
+import { useRouter } from '@/global/router/supplier.js';
 
 function calcAge(birthdate: string): number {
 	const date = new Date(birthdate);
diff --git a/packages/frontend/src/router.ts b/packages/frontend/src/router.ts
deleted file mode 100644
index baee85866c..0000000000
--- a/packages/frontend/src/router.ts
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * SPDX-FileCopyrightText: syuilo and other misskey contributors
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-import { AsyncComponentLoader, defineAsyncComponent, inject } from 'vue';
-import { Router } from '@/nirax.js';
-import { $i, iAmModerator } from '@/account.js';
-import MkLoading from '@/pages/_loading_.vue';
-import MkError from '@/pages/_error_.vue';
-
-export const page = (loader: AsyncComponentLoader<any>) => defineAsyncComponent({
-	loader: loader,
-	loadingComponent: MkLoading,
-	errorComponent: MkError,
-});
-
-export const routes = [{
-	path: '/@:initUser/pages/:initPageName/view-source',
-	component: page(() => import('./pages/page-editor/page-editor.vue')),
-}, {
-	path: '/@:username/pages/:pageName',
-	component: page(() => import('./pages/page.vue')),
-}, {
-	path: '/@:acct/following',
-	component: page(() => import('./pages/user/following.vue')),
-}, {
-	path: '/@:acct/followers',
-	component: page(() => import('./pages/user/followers.vue')),
-}, {
-	name: 'user',
-	path: '/@:acct/:page?',
-	component: page(() => import('./pages/user/index.vue')),
-}, {
-	name: 'note',
-	path: '/notes/:noteId',
-	component: page(() => import('./pages/note.vue')),
-}, {
-	name: 'list',
-	path: '/list/:listId',
-	component: page(() => import('./pages/list.vue')),
-}, {
-	path: '/clips/:clipId',
-	component: page(() => import('./pages/clip.vue')),
-}, {
-	path: '/instance-info/:host',
-	component: page(() => import('./pages/instance-info.vue')),
-}, {
-	name: 'settings',
-	path: '/settings',
-	component: page(() => import('./pages/settings/index.vue')),
-	loginRequired: true,
-	children: [{
-		path: '/profile',
-		name: 'profile',
-		component: page(() => import('./pages/settings/profile.vue')),
-	}, {
-		path: '/avatar-decoration',
-		name: 'avatarDecoration',
-		component: page(() => import('./pages/settings/avatar-decoration.vue')),
-	}, {
-		path: '/roles',
-		name: 'roles',
-		component: page(() => import('./pages/settings/roles.vue')),
-	}, {
-		path: '/privacy',
-		name: 'privacy',
-		component: page(() => import('./pages/settings/privacy.vue')),
-	}, {
-		path: '/emoji-picker',
-		name: 'emojiPicker',
-		component: page(() => import('./pages/settings/emoji-picker.vue')),
-	}, {
-		path: '/drive',
-		name: 'drive',
-		component: page(() => import('./pages/settings/drive.vue')),
-	}, {
-		path: '/drive/cleaner',
-		name: 'drive',
-		component: page(() => import('./pages/settings/drive-cleaner.vue')),
-	}, {
-		path: '/notifications',
-		name: 'notifications',
-		component: page(() => import('./pages/settings/notifications.vue')),
-	}, {
-		path: '/email',
-		name: 'email',
-		component: page(() => import('./pages/settings/email.vue')),
-	}, {
-		path: '/security',
-		name: 'security',
-		component: page(() => import('./pages/settings/security.vue')),
-	}, {
-		path: '/general',
-		name: 'general',
-		component: page(() => import('./pages/settings/general.vue')),
-	}, {
-		path: '/theme/install',
-		name: 'theme',
-		component: page(() => import('./pages/settings/theme.install.vue')),
-	}, {
-		path: '/theme/manage',
-		name: 'theme',
-		component: page(() => import('./pages/settings/theme.manage.vue')),
-	}, {
-		path: '/theme',
-		name: 'theme',
-		component: page(() => import('./pages/settings/theme.vue')),
-	}, {
-		path: '/navbar',
-		name: 'navbar',
-		component: page(() => import('./pages/settings/navbar.vue')),
-	}, {
-		path: '/statusbar',
-		name: 'statusbar',
-		component: page(() => import('./pages/settings/statusbar.vue')),
-	}, {
-		path: '/sounds',
-		name: 'sounds',
-		component: page(() => import('./pages/settings/sounds.vue')),
-	}, {
-		path: '/plugin/install',
-		name: 'plugin',
-		component: page(() => import('./pages/settings/plugin.install.vue')),
-	}, {
-		path: '/plugin',
-		name: 'plugin',
-		component: page(() => import('./pages/settings/plugin.vue')),
-	}, {
-		path: '/import-export',
-		name: 'import-export',
-		component: page(() => import('./pages/settings/import-export.vue')),
-	}, {
-		path: '/mute-block',
-		name: 'mute-block',
-		component: page(() => import('./pages/settings/mute-block.vue')),
-	}, {
-		path: '/api',
-		name: 'api',
-		component: page(() => import('./pages/settings/api.vue')),
-	}, {
-		path: '/apps',
-		name: 'api',
-		component: page(() => import('./pages/settings/apps.vue')),
-	}, {
-		path: '/webhook/edit/:webhookId',
-		name: 'webhook',
-		component: page(() => import('./pages/settings/webhook.edit.vue')),
-	}, {
-		path: '/webhook/new',
-		name: 'webhook',
-		component: page(() => import('./pages/settings/webhook.new.vue')),
-	}, {
-		path: '/webhook',
-		name: 'webhook',
-		component: page(() => import('./pages/settings/webhook.vue')),
-	}, {
-		path: '/deck',
-		name: 'deck',
-		component: page(() => import('./pages/settings/deck.vue')),
-	}, {
-		path: '/preferences-backups',
-		name: 'preferences-backups',
-		component: page(() => import('./pages/settings/preferences-backups.vue')),
-	}, {
-		path: '/migration',
-		name: 'migration',
-		component: page(() => import('./pages/settings/migration.vue')),
-	}, {
-		path: '/custom-css',
-		name: 'general',
-		component: page(() => import('./pages/settings/custom-css.vue')),
-	}, {
-		path: '/accounts',
-		name: 'profile',
-		component: page(() => import('./pages/settings/accounts.vue')),
-	}, {
-		path: '/other',
-		name: 'other',
-		component: page(() => import('./pages/settings/other.vue')),
-	}, {
-		path: '/',
-		component: page(() => import('./pages/_empty_.vue')),
-	}],
-}, {
-	path: '/reset-password/:token?',
-	component: page(() => import('./pages/reset-password.vue')),
-}, {
-	path: '/signup-complete/:code',
-	component: page(() => import('./pages/signup-complete.vue')),
-}, {
-	path: '/announcements',
-	component: page(() => import('./pages/announcements.vue')),
-}, {
-	path: '/about',
-	component: page(() => import('./pages/about.vue')),
-	hash: 'initialTab',
-}, {
-	path: '/about-misskey',
-	component: page(() => import('./pages/about-misskey.vue')),
-}, {
-	path: '/invite',
-	name: 'invite',
-	component: page(() => import('./pages/invite.vue')),
-}, {
-	path: '/ads',
-	component: page(() => import('./pages/ads.vue')),
-}, {
-	path: '/theme-editor',
-	component: page(() => import('./pages/theme-editor.vue')),
-	loginRequired: true,
-}, {
-	path: '/roles/:role',
-	component: page(() => import('./pages/role.vue')),
-}, {
-	path: '/user-tags/:tag',
-	component: page(() => import('./pages/user-tag.vue')),
-}, {
-	path: '/explore',
-	component: page(() => import('./pages/explore.vue')),
-	hash: 'initialTab',
-}, {
-	path: '/search',
-	component: page(() => import('./pages/search.vue')),
-	query: {
-		q: 'query',
-		channel: 'channel',
-		type: 'type',
-		origin: 'origin',
-	},
-}, {
-	path: '/authorize-follow',
-	component: page(() => import('./pages/follow.vue')),
-	loginRequired: true,
-}, {
-	path: '/share',
-	component: page(() => import('./pages/share.vue')),
-	loginRequired: true,
-}, {
-	path: '/api-console',
-	component: page(() => import('./pages/api-console.vue')),
-	loginRequired: true,
-}, {
-	path: '/scratchpad',
-	component: page(() => import('./pages/scratchpad.vue')),
-}, {
-	path: '/auth/:token',
-	component: page(() => import('./pages/auth.vue')),
-}, {
-	path: '/miauth/:session',
-	component: page(() => import('./pages/miauth.vue')),
-	query: {
-		callback: 'callback',
-		name: 'name',
-		icon: 'icon',
-		permission: 'permission',
-	},
-}, {
-	path: '/oauth/authorize',
-	component: page(() => import('./pages/oauth.vue')),
-}, {
-	path: '/tags/:tag',
-	component: page(() => import('./pages/tag.vue')),
-}, {
-	path: '/pages/new',
-	component: page(() => import('./pages/page-editor/page-editor.vue')),
-	loginRequired: true,
-}, {
-	path: '/pages/edit/:initPageId',
-	component: page(() => import('./pages/page-editor/page-editor.vue')),
-	loginRequired: true,
-}, {
-	path: '/pages',
-	component: page(() => import('./pages/pages.vue')),
-}, {
-	path: '/play/:id/edit',
-	component: page(() => import('./pages/flash/flash-edit.vue')),
-	loginRequired: true,
-}, {
-	path: '/play/new',
-	component: page(() => import('./pages/flash/flash-edit.vue')),
-	loginRequired: true,
-}, {
-	path: '/play/:id',
-	component: page(() => import('./pages/flash/flash.vue')),
-}, {
-	path: '/play',
-	component: page(() => import('./pages/flash/flash-index.vue')),
-}, {
-	path: '/gallery/:postId/edit',
-	component: page(() => import('./pages/gallery/edit.vue')),
-	loginRequired: true,
-}, {
-	path: '/gallery/new',
-	component: page(() => import('./pages/gallery/edit.vue')),
-	loginRequired: true,
-}, {
-	path: '/gallery/:postId',
-	component: page(() => import('./pages/gallery/post.vue')),
-}, {
-	path: '/gallery',
-	component: page(() => import('./pages/gallery/index.vue')),
-}, {
-	path: '/channels/:channelId/edit',
-	component: page(() => import('./pages/channel-editor.vue')),
-	loginRequired: true,
-}, {
-	path: '/channels/new',
-	component: page(() => import('./pages/channel-editor.vue')),
-	loginRequired: true,
-}, {
-	path: '/channels/:channelId',
-	component: page(() => import('./pages/channel.vue')),
-}, {
-	path: '/channels',
-	component: page(() => import('./pages/channels.vue')),
-}, {
-	path: '/custom-emojis-manager',
-	component: page(() => import('./pages/custom-emojis-manager.vue')),
-}, {
-	path: '/avatar-decorations',
-	name: 'avatarDecorations',
-	component: page(() => import('./pages/avatar-decorations.vue')),
-}, {
-	path: '/registry/keys/:domain/:path(*)?',
-	component: page(() => import('./pages/registry.keys.vue')),
-}, {
-	path: '/registry/value/:domain/:path(*)?',
-	component: page(() => import('./pages/registry.value.vue')),
-}, {
-	path: '/registry',
-	component: page(() => import('./pages/registry.vue')),
-}, {
-	path: '/install-extentions',
-	component: page(() => import('./pages/install-extentions.vue')),
-	loginRequired: true,
-}, {
-	path: '/admin/user/:userId',
-	component: iAmModerator ? page(() => import('./pages/admin-user.vue')) : page(() => import('./pages/not-found.vue')),
-}, {
-	path: '/admin/file/:fileId',
-	component: iAmModerator ? page(() => import('./pages/admin-file.vue')) : page(() => import('./pages/not-found.vue')),
-}, {
-	path: '/admin',
-	component: iAmModerator ? page(() => import('./pages/admin/index.vue')) : page(() => import('./pages/not-found.vue')),
-	children: [{
-		path: '/overview',
-		name: 'overview',
-		component: page(() => import('./pages/admin/overview.vue')),
-	}, {
-		path: '/users',
-		name: 'users',
-		component: page(() => import('./pages/admin/users.vue')),
-	}, {
-		path: '/emojis',
-		name: 'emojis',
-		component: page(() => import('./pages/custom-emojis-manager.vue')),
-	}, {
-		path: '/avatar-decorations',
-		name: 'avatarDecorations',
-		component: page(() => import('./pages/avatar-decorations.vue')),
-	}, {
-		path: '/queue',
-		name: 'queue',
-		component: page(() => import('./pages/admin/queue.vue')),
-	}, {
-		path: '/files',
-		name: 'files',
-		component: page(() => import('./pages/admin/files.vue')),
-	}, {
-		path: '/federation',
-		name: 'federation',
-		component: page(() => import('./pages/admin/federation.vue')),
-	}, {
-		path: '/announcements',
-		name: 'announcements',
-		component: page(() => import('./pages/admin/announcements.vue')),
-	}, {
-		path: '/ads',
-		name: 'ads',
-		component: page(() => import('./pages/admin/ads.vue')),
-	}, {
-		path: '/roles/:id/edit',
-		name: 'roles',
-		component: page(() => import('./pages/admin/roles.edit.vue')),
-	}, {
-		path: '/roles/new',
-		name: 'roles',
-		component: page(() => import('./pages/admin/roles.edit.vue')),
-	}, {
-		path: '/roles/:id',
-		name: 'roles',
-		component: page(() => import('./pages/admin/roles.role.vue')),
-	}, {
-		path: '/roles',
-		name: 'roles',
-		component: page(() => import('./pages/admin/roles.vue')),
-	}, {
-		path: '/database',
-		name: 'database',
-		component: page(() => import('./pages/admin/database.vue')),
-	}, {
-		path: '/abuses',
-		name: 'abuses',
-		component: page(() => import('./pages/admin/abuses.vue')),
-	}, {
-		path: '/modlog',
-		name: 'modlog',
-		component: page(() => import('./pages/admin/modlog.vue')),
-	}, {
-		path: '/settings',
-		name: 'settings',
-		component: page(() => import('./pages/admin/settings.vue')),
-	}, {
-		path: '/branding',
-		name: 'branding',
-		component: page(() => import('./pages/admin/branding.vue')),
-	}, {
-		path: '/moderation',
-		name: 'moderation',
-		component: page(() => import('./pages/admin/moderation.vue')),
-	}, {
-		path: '/email-settings',
-		name: 'email-settings',
-		component: page(() => import('./pages/admin/email-settings.vue')),
-	}, {
-		path: '/object-storage',
-		name: 'object-storage',
-		component: page(() => import('./pages/admin/object-storage.vue')),
-	}, {
-		path: '/security',
-		name: 'security',
-		component: page(() => import('./pages/admin/security.vue')),
-	}, {
-		path: '/relays',
-		name: 'relays',
-		component: page(() => import('./pages/admin/relays.vue')),
-	}, {
-		path: '/instance-block',
-		name: 'instance-block',
-		component: page(() => import('./pages/admin/instance-block.vue')),
-	}, {
-		path: '/proxy-account',
-		name: 'proxy-account',
-		component: page(() => import('./pages/admin/proxy-account.vue')),
-	}, {
-		path: '/external-services',
-		name: 'external-services',
-		component: page(() => import('./pages/admin/external-services.vue')),
-	}, {
-		path: '/other-settings',
-		name: 'other-settings',
-		component: page(() => import('./pages/admin/other-settings.vue')),
-	}, {
-		path: '/server-rules',
-		name: 'server-rules',
-		component: page(() => import('./pages/admin/server-rules.vue')),
-	}, {
-		path: '/invites',
-		name: 'invites',
-		component: page(() => import('./pages/admin/invites.vue')),
-	}, {
-		path: '/',
-		component: page(() => import('./pages/_empty_.vue')),
-	}],
-}, {
-	path: '/my/notifications',
-	component: page(() => import('./pages/notifications.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/favorites',
-	component: page(() => import('./pages/favorites.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/achievements',
-	component: page(() => import('./pages/achievements.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/drive/folder/:folder',
-	component: page(() => import('./pages/drive.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/drive',
-	component: page(() => import('./pages/drive.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/drive/file/:fileId',
-	component: page(() => import('./pages/drive.file.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/follow-requests',
-	component: page(() => import('./pages/follow-requests.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/lists/:listId',
-	component: page(() => import('./pages/my-lists/list.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/lists',
-	component: page(() => import('./pages/my-lists/index.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/clips',
-	component: page(() => import('./pages/my-clips/index.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/antennas/create',
-	component: page(() => import('./pages/my-antennas/create.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/antennas/:antennaId',
-	component: page(() => import('./pages/my-antennas/edit.vue')),
-	loginRequired: true,
-}, {
-	path: '/my/antennas',
-	component: page(() => import('./pages/my-antennas/index.vue')),
-	loginRequired: true,
-}, {
-	path: '/timeline/list/:listId',
-	component: page(() => import('./pages/user-list-timeline.vue')),
-	loginRequired: true,
-}, {
-	path: '/timeline/antenna/:antennaId',
-	component: page(() => import('./pages/antenna-timeline.vue')),
-	loginRequired: true,
-}, {
-	path: '/clicker',
-	component: page(() => import('./pages/clicker.vue')),
-	loginRequired: true,
-}, {
-	path: '/timeline',
-	component: page(() => import('./pages/timeline.vue')),
-}, {
-	name: 'index',
-	path: '/',
-	component: $i ? page(() => import('./pages/timeline.vue')) : page(() => import('./pages/welcome.vue')),
-	globalCacheKey: 'index',
-}, {
-	path: '/:(*)',
-	component: page(() => import('./pages/not-found.vue')),
-}];
-
-export const mainRouter = new Router(routes, location.pathname + location.search + location.hash, !!$i, page(() => import('@/pages/not-found.vue')));
-
-window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href);
-
-mainRouter.addListener('push', ctx => {
-	window.history.pushState({ key: ctx.key }, '', ctx.path);
-});
-
-window.addEventListener('popstate', (event) => {
-	mainRouter.replace(location.pathname + location.search + location.hash, event.state?.key);
-});
-
-export function useRouter(): Router {
-	return inject<Router | null>('router', null) ?? mainRouter;
-}
diff --git a/packages/frontend/src/scripts/achievements.ts b/packages/frontend/src/scripts/achievements.ts
index 4b6b044d8b..67d997f09b 100644
--- a/packages/frontend/src/scripts/achievements.ts
+++ b/packages/frontend/src/scripts/achievements.ts
@@ -83,6 +83,8 @@ export const ACHIEVEMENT_TYPES = [
 	'brainDiver',
 	'smashTestNotificationButton',
 	'tutorialCompleted',
+	'bubbleGameExplodingHead',
+	'bubbleGameDoubleExplodingHead',
 ] as const;
 
 export const ACHIEVEMENT_BADGES = {
@@ -466,6 +468,16 @@ export const ACHIEVEMENT_BADGES = {
 		bg: 'linear-gradient(0deg, rgb(220 223 225), rgb(172 192 207))',
 		frame: 'bronze',
 	},
+	'bubbleGameExplodingHead': {
+		img: '/fluent-emoji/1f92f.png',
+		bg: 'linear-gradient(0deg, rgb(255 77 77), rgb(247 155 214))',
+		frame: 'bronze',
+	},
+	'bubbleGameDoubleExplodingHead': {
+		img: '/fluent-emoji/1f92f.png',
+		bg: 'linear-gradient(0deg, rgb(255 77 77), rgb(247 155 214))',
+		frame: 'silver',
+	},
 /* @see <https://github.com/misskey-dev/misskey/pull/10365#discussion_r1155511107>
 } as const satisfies Record<typeof ACHIEVEMENT_TYPES[number], {
 	img: string;
diff --git a/packages/frontend/src/scripts/aiscript/ui.ts b/packages/frontend/src/scripts/aiscript/ui.ts
index 08ba1e6d9b..215ac4cc69 100644
--- a/packages/frontend/src/scripts/aiscript/ui.ts
+++ b/packages/frontend/src/scripts/aiscript/ui.ts
@@ -218,7 +218,7 @@ function getTextOptions(def: values.Value | undefined): Omit<AsUiText, 'id' | 't
 	};
 }
 
-function getMfmOptions(def: values.Value | undefined): Omit<AsUiMfm, 'id' | 'type'> {
+function getMfmOptions(def: values.Value | undefined, call: (fn: values.VFn, args: values.Value[]) => Promise<values.Value>): Omit<AsUiMfm, 'id' | 'type'> {
 	utils.assertObject(def);
 
 	const text = def.value.get('text');
@@ -241,7 +241,7 @@ function getMfmOptions(def: values.Value | undefined): Omit<AsUiMfm, 'id' | 'typ
 		color: color?.value,
 		font: font?.value,
 		onClickEv: (evId: string) => {
-			if (onClickEv) call(onClickEv, values.STR(evId));
+			if (onClickEv) call(onClickEv, [values.STR(evId)]);
 		},
 	};
 }
diff --git a/packages/frontend/src/scripts/drop-and-fusion-engine.ts b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
new file mode 100644
index 0000000000..b6e735ddf2
--- /dev/null
+++ b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
@@ -0,0 +1,400 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { EventEmitter } from 'eventemitter3';
+import * as Matter from 'matter-js';
+import * as sound from '@/scripts/sound.js';
+
+export type Mono = {
+	id: string;
+	level: number;
+	size: number;
+	shape: 'circle' | 'rectangle';
+	score: number;
+	dropCandidate: boolean;
+	sfxPitch: number;
+	img: string;
+	imgSize: number;
+	spriteScale: number;
+};
+
+const PHYSICS_QUALITY_FACTOR = 16; // 低いほどパフォーマンスが高いがガタガタして安定しなくなる、逆に高すぎても何故か不安定になる
+
+export class DropAndFusionGame extends EventEmitter<{
+	changeScore: (newScore: number) => void;
+	changeCombo: (newCombo: number) => void;
+	changeStock: (newStock: { id: string; mono: Mono }[]) => void;
+	dropped: () => void;
+	fusioned: (x: number, y: number, scoreDelta: number) => void;
+	monoAdded: (mono: Mono) => void;
+	gameOver: () => void;
+}> {
+	private COMBO_INTERVAL = 1000;
+	public readonly DROP_INTERVAL = 500;
+	public readonly PLAYAREA_MARGIN = 25;
+	private STOCK_MAX = 4;
+	private loaded = false;
+	private engine: Matter.Engine;
+	private render: Matter.Render;
+	private runner: Matter.Runner;
+	private overflowCollider: Matter.Body;
+	private isGameOver = false;
+
+	private gameWidth: number;
+	private gameHeight: number;
+	private monoDefinitions: Mono[] = [];
+	private monoTextures: Record<string, Blob> = {};
+	private monoTextureUrls: Record<string, string> = {};
+
+	/**
+	 * フィールドに出ていて、かつ合体の対象となるアイテム
+	 */
+	private activeBodyIds: Matter.Body['id'][] = [];
+
+	private latestDroppedBodyId: Matter.Body['id'] | null = null;
+
+	private latestDroppedAt = 0;
+	private latestFusionedAt = 0;
+	private stock: { id: string; mono: Mono }[] = [];
+
+	private _combo = 0;
+	private get combo() {
+		return this._combo;
+	}
+	private set combo(value: number) {
+		this._combo = value;
+		this.emit('changeCombo', value);
+	}
+
+	private _score = 0;
+	private get score() {
+		return this._score;
+	}
+	private set score(value: number) {
+		this._score = value;
+		this.emit('changeScore', value);
+	}
+
+	private comboIntervalId: number | null = null;
+
+	constructor(opts: {
+		canvas: HTMLCanvasElement;
+		width: number;
+		height: number;
+		monoDefinitions: Mono[];
+	}) {
+		super();
+
+		this.gameWidth = opts.width;
+		this.gameHeight = opts.height;
+		this.monoDefinitions = opts.monoDefinitions;
+
+		this.engine = Matter.Engine.create({
+			constraintIterations: 2 * PHYSICS_QUALITY_FACTOR,
+			positionIterations: 6 * PHYSICS_QUALITY_FACTOR,
+			velocityIterations: 4 * PHYSICS_QUALITY_FACTOR,
+			gravity: {
+				x: 0,
+				y: 1,
+			},
+			timing: {
+				timeScale: 2,
+			},
+			enableSleeping: false,
+		});
+
+		this.render = Matter.Render.create({
+			engine: this.engine,
+			canvas: opts.canvas,
+			options: {
+				width: this.gameWidth,
+				height: this.gameHeight,
+				background: 'transparent', // transparent to hide
+				wireframeBackground: 'transparent', // transparent to hide
+				wireframes: false,
+				showSleeping: false,
+				pixelRatio: Math.max(2, window.devicePixelRatio),
+			},
+		});
+
+		Matter.Render.run(this.render);
+
+		this.runner = Matter.Runner.create();
+		Matter.Runner.run(this.runner, this.engine);
+
+		this.engine.world.bodies = [];
+
+		//#region walls
+		const WALL_OPTIONS: Matter.IChamferableBodyDefinition = {
+			isStatic: true,
+			friction: 0.7,
+			slop: 1.0,
+			render: {
+				strokeStyle: 'transparent',
+				fillStyle: 'transparent',
+			},
+		};
+
+		const thickness = 100;
+		Matter.Composite.add(this.engine.world, [
+			Matter.Bodies.rectangle(this.gameWidth / 2, this.gameHeight + (thickness / 2) - this.PLAYAREA_MARGIN, this.gameWidth, thickness, WALL_OPTIONS),
+			Matter.Bodies.rectangle(this.gameWidth + (thickness / 2) - this.PLAYAREA_MARGIN, this.gameHeight / 2, thickness, this.gameHeight, WALL_OPTIONS),
+			Matter.Bodies.rectangle(-((thickness / 2) - this.PLAYAREA_MARGIN), this.gameHeight / 2, thickness, this.gameHeight, WALL_OPTIONS),
+		]);
+		//#endregion
+
+		this.overflowCollider = Matter.Bodies.rectangle(this.gameWidth / 2, 0, this.gameWidth, 200, {
+			isStatic: true,
+			isSensor: true,
+			render: {
+				strokeStyle: 'transparent',
+				fillStyle: 'transparent',
+			},
+		});
+		Matter.Composite.add(this.engine.world, this.overflowCollider);
+
+		// fit the render viewport to the scene
+		Matter.Render.lookAt(this.render, {
+			min: { x: 0, y: 0 },
+			max: { x: this.gameWidth, y: this.gameHeight },
+		});
+	}
+
+	private createBody(mono: Mono, x: number, y: number) {
+		const options: Matter.IBodyDefinition = {
+			label: mono.id,
+			//density: 0.0005,
+			density: mono.size / 1000,
+			restitution: 0.2,
+			frictionAir: 0.01,
+			friction: 0.7,
+			frictionStatic: 5,
+			slop: 1.0,
+			//mass: 0,
+			render: {
+				sprite: {
+					texture: mono.img,
+					xScale: (mono.size / mono.imgSize) * mono.spriteScale,
+					yScale: (mono.size / mono.imgSize) * mono.spriteScale,
+				},
+			},
+		};
+		if (mono.shape === 'circle') {
+			return Matter.Bodies.circle(x, y, mono.size / 2, options);
+		} else if (mono.shape === 'rectangle') {
+			return Matter.Bodies.rectangle(x, y, mono.size, mono.size, options);
+		} else {
+			throw new Error('unrecognized shape');
+		}
+	}
+
+	private fusion(bodyA: Matter.Body, bodyB: Matter.Body) {
+		const now = Date.now();
+		if (this.latestFusionedAt > now - this.COMBO_INTERVAL) {
+			this.combo++;
+		} else {
+			this.combo = 1;
+		}
+		this.latestFusionedAt = now;
+
+		// TODO: 単に位置だけでなくそれぞれの動きベクトルも融合する?
+		const newX = (bodyA.position.x + bodyB.position.x) / 2;
+		const newY = (bodyA.position.y + bodyB.position.y) / 2;
+
+		Matter.Composite.remove(this.engine.world, [bodyA, bodyB]);
+		this.activeBodyIds = this.activeBodyIds.filter(x => x !== bodyA.id && x !== bodyB.id);
+
+		const currentMono = this.monoDefinitions.find(y => y.id === bodyA.label)!;
+		const nextMono = this.monoDefinitions.find(x => x.level === currentMono.level + 1);
+
+		if (nextMono) {
+			const body = this.createBody(nextMono, newX, newY);
+			Matter.Composite.add(this.engine.world, body);
+
+			// 連鎖してfusionした場合の分かりやすさのため少し間を置いてからfusion対象になるようにする
+			window.setTimeout(() => {
+				this.activeBodyIds.push(body.id);
+			}, 100);
+
+			const comboBonus = 1 + ((this.combo - 1) / 5);
+			const additionalScore = Math.round(currentMono.score * comboBonus);
+			this.score += additionalScore;
+
+			// TODO: 効果音再生はコンポーネント側の責務なので移動する
+			const pan = ((newX / this.gameWidth) - 0.5) * 2;
+			sound.playUrl('/client-assets/drop-and-fusion/bubble2.mp3', 1, pan, nextMono.sfxPitch);
+
+			this.emit('monoAdded', nextMono);
+			this.emit('fusioned', newX, newY, additionalScore);
+		} else {
+			//const VELOCITY = 30;
+			//for (let i = 0; i < 10; i++) {
+			//	const body = createBody(FRUITS.find(x => x.level === (1 + Math.floor(Math.random() * 3)))!, x + ((Math.random() * VELOCITY) - (VELOCITY / 2)), y + ((Math.random() * VELOCITY) - (VELOCITY / 2)));
+			//	Matter.Composite.add(world, body);
+			//	bodies.push(body);
+			//}
+			//sound.playUrl({
+			//	type: 'syuilo/bubble2',
+			//	volume: 1,
+			//});
+		}
+	}
+
+	private gameOver() {
+		this.isGameOver = true;
+		Matter.Runner.stop(this.runner);
+		this.emit('gameOver');
+	}
+
+	/** テクスチャをすべてキャッシュする */
+	private async loadMonoTextures() {
+		async function loadSingleMonoTexture(mono: Mono, game: DropAndFusionGame) {
+			// Matter-js内にキャッシュがある場合はスキップ
+			if (game.render.textures[mono.img]) return;
+			console.log('loading', mono.img);
+
+			let src = mono.img;
+			// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+			if (game.monoTextureUrls[mono.img]) {
+				src = game.monoTextureUrls[mono.img];
+			// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+			} else if (game.monoTextures[mono.img]) {
+				src = URL.createObjectURL(game.monoTextures[mono.img]);
+				game.monoTextureUrls[mono.img] = src;
+			} else {
+				const res = await fetch(mono.img);
+				const blob = await res.blob();
+				game.monoTextures[mono.img] = blob;
+				src = URL.createObjectURL(blob);
+				game.monoTextureUrls[mono.img] = src;
+			}
+
+			const image = new Image();
+			image.src = src;
+			game.render.textures[mono.img] = image;
+		}
+
+		return Promise.all(this.monoDefinitions.map(x => loadSingleMonoTexture(x, this)));
+	}
+
+	public start() {
+		if (!this.loaded) throw new Error('game is not loaded yet');
+
+		for (let i = 0; i < this.STOCK_MAX; i++) {
+			this.stock.push({
+				id: Math.random().toString(),
+				mono: this.monoDefinitions.filter(x => x.dropCandidate)[Math.floor(Math.random() * this.monoDefinitions.filter(x => x.dropCandidate).length)],
+			});
+		}
+		this.emit('changeStock', this.stock);
+
+		// TODO: fusion予約状態のアイテムは光らせるなどの演出をすると楽しそう
+		let fusionReservedPairs: { bodyA: Matter.Body; bodyB: Matter.Body }[] = [];
+
+		const minCollisionEnergyForSound = 2.5;
+		const maxCollisionEnergyForSound = 9;
+		const soundPitchMax = 4;
+		const soundPitchMin = 0.5;
+
+		Matter.Events.on(this.engine, 'collisionStart', (event) => {
+			for (const pairs of event.pairs) {
+				const { bodyA, bodyB } = pairs;
+				if (bodyA.id === this.overflowCollider.id || bodyB.id === this.overflowCollider.id) {
+					if (bodyA.id === this.latestDroppedBodyId || bodyB.id === this.latestDroppedBodyId) {
+						continue;
+					}
+					this.gameOver();
+					break;
+				}
+				const shouldFusion = (bodyA.label === bodyB.label) && !fusionReservedPairs.some(x => x.bodyA.id === bodyA.id || x.bodyA.id === bodyB.id || x.bodyB.id === bodyA.id || x.bodyB.id === bodyB.id);
+				if (shouldFusion) {
+					if (this.activeBodyIds.includes(bodyA.id) && this.activeBodyIds.includes(bodyB.id)) {
+						this.fusion(bodyA, bodyB);
+					} else {
+						fusionReservedPairs.push({ bodyA, bodyB });
+						window.setTimeout(() => {
+							fusionReservedPairs = fusionReservedPairs.filter(x => x.bodyA.id !== bodyA.id && x.bodyB.id !== bodyB.id);
+							this.fusion(bodyA, bodyB);
+						}, 100);
+					}
+				} else {
+					const energy = pairs.collision.depth;
+					if (energy > minCollisionEnergyForSound) {
+						// TODO: 効果音再生はコンポーネント側の責務なので移動する
+						const vol = (Math.min(maxCollisionEnergyForSound, energy - minCollisionEnergyForSound) / maxCollisionEnergyForSound) / 4;
+						const pan = ((((bodyA.position.x + bodyB.position.x) / 2) / this.gameWidth) - 0.5) * 2;
+						const pitch = soundPitchMin + ((soundPitchMax - soundPitchMin) * (1 - (Math.min(10, energy) / 10)));
+						sound.playUrl('/client-assets/drop-and-fusion/poi1.mp3', vol, pan, pitch);
+					}
+				}
+			}
+		});
+
+		this.comboIntervalId = window.setInterval(() => {
+			if (this.latestFusionedAt < Date.now() - this.COMBO_INTERVAL) {
+				this.combo = 0;
+			}
+		}, 500);
+	}
+
+	public async load() {
+		await this.loadMonoTextures();
+		this.loaded = true;
+	}
+
+	public getTextureImageUrl(mono: Mono) {
+		// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+		if (this.monoTextureUrls[mono.img]) {
+			return this.monoTextureUrls[mono.img];
+
+		// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+		} else if (this.monoTextures[mono.img]) {
+			// Gameクラス内にキャッシュがある場合はそれを使う
+			const out = URL.createObjectURL(this.monoTextures[mono.img]);
+			this.monoTextureUrls[mono.img] = out;
+			return out;
+		} else {
+			return mono.img;
+		}
+	}
+
+	public getActiveMonos() {
+		return this.engine.world.bodies.map(x => this.monoDefinitions.find((mono) => mono.id === x.label)!).filter(x => x !== undefined);
+	}
+
+	public drop(_x: number) {
+		if (this.isGameOver) return;
+		if (Date.now() - this.latestDroppedAt < this.DROP_INTERVAL) {
+			return;
+		}
+		const st = this.stock.shift()!;
+		this.stock.push({
+			id: Math.random().toString(),
+			mono: this.monoDefinitions.filter(x => x.dropCandidate)[Math.floor(Math.random() * this.monoDefinitions.filter(x => x.dropCandidate).length)],
+		});
+		this.emit('changeStock', this.stock);
+
+		const x = Math.min(this.gameWidth - this.PLAYAREA_MARGIN - (st.mono.size / 2), Math.max(this.PLAYAREA_MARGIN + (st.mono.size / 2), _x));
+		const body = this.createBody(st.mono, x, 50 + st.mono.size / 2);
+		Matter.Composite.add(this.engine.world, body);
+		this.activeBodyIds.push(body.id);
+		this.latestDroppedBodyId = body.id;
+		this.latestDroppedAt = Date.now();
+		this.emit('dropped');
+		this.emit('monoAdded', st.mono);
+
+		// TODO: 効果音再生はコンポーネント側の責務なので移動する
+		const pan = ((x / this.gameWidth) - 0.5) * 2;
+		sound.playUrl('/client-assets/drop-and-fusion/poi2.mp3', 1, pan);
+	}
+
+	public dispose() {
+		if (this.comboIntervalId) window.clearInterval(this.comboIntervalId);
+		Matter.Render.stop(this.render);
+		Matter.Runner.stop(this.runner);
+		Matter.World.clear(this.engine.world, false);
+		Matter.Engine.clear(this.engine);
+	}
+}
diff --git a/packages/frontend/src/scripts/emojilist.ts b/packages/frontend/src/scripts/emojilist.ts
index 8885bf4b7f..4bd8bf94be 100644
--- a/packages/frontend/src/scripts/emojilist.ts
+++ b/packages/frontend/src/scripts/emojilist.ts
@@ -36,7 +36,8 @@ for (let i = 0; i < emojilist.length; i++) {
 export const emojiCharByCategory = _charGroupByCategory;
 
 export function getEmojiName(char: string): string | null {
-	const idx = _indexByChar.get(char);
+	// Colorize it because emojilist.json assumes that
+	const idx = _indexByChar.get(colorizeEmoji(char));
 	if (idx == null) {
 		return null;
 	} else {
@@ -44,6 +45,10 @@ export function getEmojiName(char: string): string | null {
 	}
 }
 
+export function colorizeEmoji(char: string) {
+	return char.length === 1 ? `${char}\uFE0F` : char;
+}
+
 export interface CustomEmojiFolderTree {
 	value: string;
 	category: string;
diff --git a/packages/frontend/src/scripts/get-user-menu.ts b/packages/frontend/src/scripts/get-user-menu.ts
index 2735253b36..d9a52c3741 100644
--- a/packages/frontend/src/scripts/get-user-menu.ts
+++ b/packages/frontend/src/scripts/get-user-menu.ts
@@ -13,11 +13,11 @@ import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { defaultStore, userActions } from '@/store.js';
 import { $i, iAmModerator } from '@/account.js';
-import { mainRouter } from '@/router.js';
-import { Router } from '@/nirax.js';
+import { IRouter } from '@/nirax.js';
 import { antennasCache, rolesCache, userListsCache } from '@/cache.js';
+import { mainRouter } from '@/global/router/main.js';
 
-export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router = mainRouter) {
+export function getUserMenu(user: Misskey.entities.UserDetailed, router: IRouter = mainRouter) {
 	const meId = $i ? $i.id : null;
 
 	const cleanups = [] as (() => void)[];
diff --git a/packages/frontend/src/scripts/lookup.ts b/packages/frontend/src/scripts/lookup.ts
index ff438af24f..ddcfd8852e 100644
--- a/packages/frontend/src/scripts/lookup.ts
+++ b/packages/frontend/src/scripts/lookup.ts
@@ -6,8 +6,8 @@
 import * as os from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { i18n } from '@/i18n.js';
-import { mainRouter } from '@/router.js';
 import { Router } from '@/nirax.js';
+import { mainRouter } from '@/global/router/main.js';
 
 export async function lookup(router?: Router) {
 	const _router = router ?? mainRouter;
diff --git a/packages/frontend/src/scripts/misskey-api.ts b/packages/frontend/src/scripts/misskey-api.ts
index e71c5dd592..337fa15113 100644
--- a/packages/frontend/src/scripts/misskey-api.ts
+++ b/packages/frontend/src/scripts/misskey-api.ts
@@ -10,12 +10,17 @@ import { $i } from '@/account.js';
 export const pendingApiRequestsCount = ref(0);
 
 // Implements Misskey.api.ApiClient.request
-export function misskeyApi<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(
+export function misskeyApi<
+	ResT = void,
+	E extends keyof Misskey.Endpoints = keyof Misskey.Endpoints,
+	P extends Misskey.Endpoints[E]['req'] = Misskey.Endpoints[E]['req'],
+	_ResT = ResT extends void ? Misskey.api.SwitchCaseResponseType<E, P> : ResT,
+>(
 	endpoint: E,
 	data: P = {} as any,
 	token?: string | null | undefined,
 	signal?: AbortSignal,
-): Promise<Misskey.api.SwitchCaseResponseType<E, P>> {
+): Promise<_ResT> {
 	if (endpoint.includes('://')) throw new Error('invalid endpoint');
 	pendingApiRequestsCount.value++;
 
@@ -23,7 +28,7 @@ export function misskeyApi<E extends keyof Misskey.Endpoints, P extends Misskey.
 		pendingApiRequestsCount.value--;
 	};
 
-	const promise = new Promise<Misskey.Endpoints[E]['res'] | void>((resolve, reject) => {
+	const promise = new Promise<_ResT>((resolve, reject) => {
 		// Append a credential
 		if ($i) (data as any).i = $i.token;
 		if (token !== undefined) (data as any).i = token;
@@ -44,7 +49,7 @@ export function misskeyApi<E extends keyof Misskey.Endpoints, P extends Misskey.
 			if (res.status === 200) {
 				resolve(body);
 			} else if (res.status === 204) {
-				resolve();
+				resolve(undefined as _ResT); // void -> undefined
 			} else {
 				reject(body.error);
 			}
@@ -57,10 +62,15 @@ export function misskeyApi<E extends keyof Misskey.Endpoints, P extends Misskey.
 }
 
 // Implements Misskey.api.ApiClient.request
-export function misskeyApiGet<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(
+export function misskeyApiGet<
+	ResT = void,
+	E extends keyof Misskey.Endpoints = keyof Misskey.Endpoints,
+	P extends Misskey.Endpoints[E]['req'] = Misskey.Endpoints[E]['req'],
+	_ResT = ResT extends void ? Misskey.api.SwitchCaseResponseType<E, P> : ResT,
+>(
 	endpoint: E,
 	data: P = {} as any,
-): Promise<Misskey.api.SwitchCaseResponseType<E, P>> {
+): Promise<_ResT> {
 	pendingApiRequestsCount.value++;
 
 	const onFinally = () => {
@@ -69,7 +79,7 @@ export function misskeyApiGet<E extends keyof Misskey.Endpoints, P extends Missk
 
 	const query = new URLSearchParams(data as any);
 
-	const promise = new Promise<Misskey.Endpoints[E]['res'] | void>((resolve, reject) => {
+	const promise = new Promise<_ResT>((resolve, reject) => {
 		// Send request
 		window.fetch(`${apiUrl}/${endpoint}?${query}`, {
 			method: 'GET',
@@ -81,7 +91,7 @@ export function misskeyApiGet<E extends keyof Misskey.Endpoints, P extends Missk
 			if (res.status === 200) {
 				resolve(body);
 			} else if (res.status === 204) {
-				resolve();
+				resolve(undefined as _ResT); // void -> undefined
 			} else {
 				reject(body.error);
 			}
diff --git a/packages/frontend/src/scripts/sound.ts b/packages/frontend/src/scripts/sound.ts
index 0b966ff199..690c342c85 100644
--- a/packages/frontend/src/scripts/sound.ts
+++ b/packages/frontend/src/scripts/sound.ts
@@ -5,7 +5,6 @@
 
 import type { SoundStore } from '@/store.js';
 import { defaultStore } from '@/store.js';
-import { misskeyApi } from '@/scripts/misskey-api.js';
 
 let ctx: AudioContext;
 const cache = new Map<string, AudioBuffer>();
@@ -89,63 +88,35 @@ export type OperationType = typeof operationTypes[number];
 
 /**
  * 音声を読み込む
- * @param soundStore サウンド設定
+ * @param url url
  * @param options `useCache`: デフォルトは`true` 一度再生した音声はキャッシュする
  */
-export async function loadAudio(soundStore: SoundStore, options?: { useCache?: boolean; }) {
+export async function loadAudio(url: string, options?: { useCache?: boolean; }) {
 	if (_DEV_) console.log('loading audio. opts:', options);
 	// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
-	if (soundStore.type === null || (soundStore.type === '_driveFile_' && !soundStore.fileUrl)) {
-		return;
-	}
-	// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
 	if (ctx == null) {
 		ctx = new AudioContext();
 	}
 	if (options?.useCache ?? true) {
-		if (soundStore.type === '_driveFile_' && cache.has(soundStore.fileId)) {
+		if (cache.has(url)) {
 			if (_DEV_) console.log('use cache');
-			return cache.get(soundStore.fileId) as AudioBuffer;
-		} else if (cache.has(soundStore.type)) {
-			if (_DEV_) console.log('use cache');
-			return cache.get(soundStore.type) as AudioBuffer;
+			return cache.get(url) as AudioBuffer;
 		}
 	}
 
 	let response: Response;
 
-	if (soundStore.type === '_driveFile_') {
-		try {
-			response = await fetch(soundStore.fileUrl);
-		} catch (err) {
-			try {
-				// URLが変わっている可能性があるのでドライブ側からURLを取得するフォールバック
-				const apiRes = await misskeyApi('drive/files/show', {
-					fileId: soundStore.fileId,
-				});
-				response = await fetch(apiRes.url);
-			} catch (fbErr) {
-				// それでも無理なら諦める
-				return;
-			}
-		}
-	} else {
-		try {
-			response = await fetch(`/client-assets/sounds/${soundStore.type}.mp3`);
-		} catch (err) {
-			return;
-		}
+	try {
+		response = await fetch(url);
+	} catch (err) {
+		return;
 	}
 
 	const arrayBuffer = await response.arrayBuffer();
 	const audioBuffer = await ctx.decodeAudioData(arrayBuffer);
 
 	if (options?.useCache ?? true) {
-		if (soundStore.type === '_driveFile_') {
-			cache.set(soundStore.fileId, audioBuffer);
-		} else {
-			cache.set(soundStore.type, audioBuffer);
-		}
+		cache.set(url, audioBuffer);
 	}
 
 	return audioBuffer;
@@ -174,25 +145,46 @@ export function play(operationType: OperationType) {
  * @param soundStore サウンド設定
  */
 export async function playFile(soundStore: SoundStore) {
-	const buffer = await loadAudio(soundStore);
+	if (soundStore.type === null || (soundStore.type === '_driveFile_' && !soundStore.fileUrl)) {
+		return;
+	}
+	const url = soundStore.type === '_driveFile_' ? soundStore.fileUrl : `/client-assets/sounds/${soundStore.type}.mp3`;
+	const buffer = await loadAudio(url);
 	if (!buffer) return;
-	createSourceNode(buffer, soundStore.volume)?.start();
+	createSourceNode(buffer, soundStore.volume)?.soundSource.start();
 }
 
-export function createSourceNode(buffer: AudioBuffer, volume: number) : AudioBufferSourceNode | null {
+export async function playUrl(url: string, volume = 1, pan = 0, playbackRate = 1) {
+	const buffer = await loadAudio(url);
+	if (!buffer) return;
+	createSourceNode(buffer, volume, pan, playbackRate)?.soundSource.start();
+}
+
+export function createSourceNode(buffer: AudioBuffer, volume: number, pan = 0, playbackRate = 1): {
+	soundSource: AudioBufferSourceNode;
+	panNode: StereoPannerNode;
+	gainNode: GainNode;
+} | null {
 	const masterVolume = defaultStore.state.sound_masterVolume;
 	if (isMute() || masterVolume === 0 || volume === 0) {
 		return null;
 	}
 
+	const panNode = ctx.createStereoPanner();
+	panNode.pan.value = pan;
+
 	const gainNode = ctx.createGain();
 	gainNode.gain.value = masterVolume * volume;
 
 	const soundSource = ctx.createBufferSource();
 	soundSource.buffer = buffer;
-	soundSource.connect(gainNode).connect(ctx.destination);
+	soundSource.playbackRate.value = playbackRate;
+	soundSource
+		.connect(panNode)
+		.connect(gainNode)
+		.connect(ctx.destination);
 
-	return soundSource;
+	return { soundSource, panNode, gainNode };
 }
 
 /**
diff --git a/packages/frontend/src/ui/_common_/common.ts b/packages/frontend/src/ui/_common_/common.ts
index b970ff1df4..9930b321f7 100644
--- a/packages/frontend/src/ui/_common_/common.ts
+++ b/packages/frontend/src/ui/_common_/common.ts
@@ -27,6 +27,11 @@ function toolsMenuItems(): MenuItem[] {
 		to: '/clicker',
 		text: '🍪👈',
 		icon: 'ti ti-cookie',
+	}, {
+		type: 'link',
+		to: '/bubble-game',
+		text: i18n.ts.bubbleGame,
+		icon: 'ti ti-apple',
 	}, ($i && ($i.isAdmin || $i.policies.canManageCustomEmojis)) ? {
 		type: 'link',
 		to: '/custom-emojis-manager',
diff --git a/packages/frontend/src/ui/_common_/sw-inject.ts b/packages/frontend/src/ui/_common_/sw-inject.ts
index 504484f8de..4c77465eb1 100644
--- a/packages/frontend/src/ui/_common_/sw-inject.ts
+++ b/packages/frontend/src/ui/_common_/sw-inject.ts
@@ -7,8 +7,8 @@ import { post } from '@/os.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { $i, login } from '@/account.js';
 import { getAccountFromId } from '@/scripts/get-account-from-id.js';
-import { mainRouter } from '@/router.js';
 import { deepClone } from '@/scripts/clone.js';
+import { mainRouter } from '@/global/router/main.js';
 
 export function swInject() {
 	navigator.serviceWorker.addEventListener('message', async ev => {
diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue
index e0985fdb11..fdddc0bb69 100644
--- a/packages/frontend/src/ui/classic.vue
+++ b/packages/frontend/src/ui/classic.vue
@@ -52,11 +52,11 @@ import XCommon from './_common_/common.vue';
 import { instanceName } from '@/config.js';
 import { StickySidebar } from '@/scripts/sticky-sidebar.js';
 import * as os from '@/os.js';
-import { mainRouter } from '@/router.js';
 import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import { defaultStore } from '@/store.js';
 import { i18n } from '@/i18n.js';
 import { miLocalStorage } from '@/local-storage.js';
+import { mainRouter } from '@/global/router/main.js';
 const XHeaderMenu = defineAsyncComponent(() => import('./classic.header.vue'));
 const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue'));
 
diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index d184764b82..304ebbf0b2 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -103,7 +103,6 @@ import * as os from '@/os.js';
 import { navbarItemDef } from '@/navbar.js';
 import { $i } from '@/account.js';
 import { i18n } from '@/i18n.js';
-import { mainRouter } from '@/router.js';
 import { unisonReload } from '@/scripts/unison-reload.js';
 import { deviceKind } from '@/scripts/device-kind.js';
 import { defaultStore } from '@/store.js';
@@ -117,6 +116,7 @@ import XWidgetsColumn from '@/ui/deck/widgets-column.vue';
 import XMentionsColumn from '@/ui/deck/mentions-column.vue';
 import XDirectColumn from '@/ui/deck/direct-column.vue';
 import XRoleTimelineColumn from '@/ui/deck/role-timeline-column.vue';
+import { mainRouter } from '@/global/router/main.js';
 const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
 const XAnnouncements = defineAsyncComponent(() => import('@/ui/_common_/announcements.vue'));
 
diff --git a/packages/frontend/src/ui/deck/main-column.vue b/packages/frontend/src/ui/deck/main-column.vue
index c2b8f19079..674132e0d7 100644
--- a/packages/frontend/src/ui/deck/main-column.vue
+++ b/packages/frontend/src/ui/deck/main-column.vue
@@ -24,10 +24,10 @@ import XColumn from './column.vue';
 import { deckStore, Column } from '@/ui/deck/deck-store.js';
 import * as os from '@/os.js';
 import { i18n } from '@/i18n.js';
-import { mainRouter } from '@/router.js';
 import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import { useScrollPositionManager } from '@/nirax.js';
 import { getScrollContainer } from '@/scripts/scroll.js';
+import { mainRouter } from '@/global/router/main.js';
 
 defineProps<{
 	column: Column;
diff --git a/packages/frontend/src/ui/minimum.vue b/packages/frontend/src/ui/minimum.vue
index f32f2de3df..b0a2aa35f9 100644
--- a/packages/frontend/src/ui/minimum.vue
+++ b/packages/frontend/src/ui/minimum.vue
@@ -16,9 +16,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 <script lang="ts" setup>
 import { provide, ComputedRef, ref } from 'vue';
 import XCommon from './_common_/common.vue';
-import { mainRouter } from '@/router.js';
 import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import { instanceName } from '@/config.js';
+import { mainRouter } from '@/global/router/main.js';
 
 const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
 
diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue
index f46f55d988..6f13f3fe87 100644
--- a/packages/frontend/src/ui/universal.vue
+++ b/packages/frontend/src/ui/universal.vue
@@ -105,12 +105,12 @@ import { defaultStore } from '@/store.js';
 import { navbarItemDef } from '@/navbar.js';
 import { i18n } from '@/i18n.js';
 import { $i } from '@/account.js';
-import { mainRouter } from '@/router.js';
 import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import { deviceKind } from '@/scripts/device-kind.js';
 import { miLocalStorage } from '@/local-storage.js';
 import { CURRENT_STICKY_BOTTOM } from '@/const.js';
 import { useScrollPositionManager } from '@/nirax.js';
+import { mainRouter } from '@/global/router/main.js';
 
 const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue'));
 const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/navbar.vue'));
diff --git a/packages/frontend/src/ui/visitor.vue b/packages/frontend/src/ui/visitor.vue
index 5af6bc30a8..d97c786d4a 100644
--- a/packages/frontend/src/ui/visitor.vue
+++ b/packages/frontend/src/ui/visitor.vue
@@ -79,10 +79,10 @@ import { instance } from '@/instance.js';
 import XSigninDialog from '@/components/MkSigninDialog.vue';
 import XSignupDialog from '@/components/MkSignupDialog.vue';
 import { ColdDeviceStorage, defaultStore } from '@/store.js';
-import { mainRouter } from '@/router.js';
 import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import { i18n } from '@/i18n.js';
 import MkVisitorDashboard from '@/components/MkVisitorDashboard.vue';
+import { mainRouter } from '@/global/router/main.js';
 
 const DESKTOP_THRESHOLD = 1100;
 
diff --git a/packages/frontend/src/ui/zen.vue b/packages/frontend/src/ui/zen.vue
index b819b6ca0a..957044c52b 100644
--- a/packages/frontend/src/ui/zen.vue
+++ b/packages/frontend/src/ui/zen.vue
@@ -24,10 +24,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 <script lang="ts" setup>
 import { provide, ComputedRef, ref } from 'vue';
 import XCommon from './_common_/common.vue';
-import { mainRouter } from '@/router.js';
 import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
 import { instanceName, ui } from '@/config.js';
 import { i18n } from '@/i18n.js';
+import { mainRouter } from '@/global/router/main.js';
 
 const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
 
diff --git a/packages/frontend/src/widgets/WidgetJobQueue.vue b/packages/frontend/src/widgets/WidgetJobQueue.vue
index 91983d8474..89ad3bf323 100644
--- a/packages/frontend/src/widgets/WidgetJobQueue.vue
+++ b/packages/frontend/src/widgets/WidgetJobQueue.vue
@@ -104,10 +104,7 @@ const jammedAudioBuffer = ref<AudioBuffer | null>(null);
 const jammedSoundNodePlaying = ref<boolean>(false);
 
 if (defaultStore.state.sound_masterVolume) {
-	sound.loadAudio({
-		type: 'syuilo/queue-jammed',
-		volume: 1,
-	}).then(buf => {
+	sound.loadAudio('/client-assets/sounds/syuilo/queue-jammed.mp3').then(buf => {
 		if (!buf) throw new Error('[WidgetJobQueue] Failed to initialize AudioBuffer');
 		jammedAudioBuffer.value = buf;
 	});
@@ -126,7 +123,7 @@ const onStats = (stats) => {
 		current[domain].delayed = stats[domain].delayed;
 
 		if (current[domain].waiting > 0 && widgetProps.sound && jammedAudioBuffer.value && !jammedSoundNodePlaying.value) {
-			const soundNode = sound.createSourceNode(jammedAudioBuffer.value, 1);
+			const soundNode = sound.createSourceNode(jammedAudioBuffer.value, 1)?.soundSource;
 			if (soundNode) {
 				jammedSoundNodePlaying.value = true;
 				soundNode.onended = () => jammedSoundNodePlaying.value = false;
diff --git a/packages/frontend/src/widgets/server-metric/cpu-mem.vue b/packages/frontend/src/widgets/server-metric/cpu-mem.vue
index f13b6a370d..ee720bd9d7 100644
--- a/packages/frontend/src/widgets/server-metric/cpu-mem.vue
+++ b/packages/frontend/src/widgets/server-metric/cpu-mem.vue
@@ -80,13 +80,13 @@ import * as Misskey from 'misskey-js';
 import { v4 as uuid } from 'uuid';
 
 const props = defineProps<{
-	connection: any,
+	connection: Misskey.ChannelConnection<Misskey.Channels['serverStats']>,
 	meta: Misskey.entities.ServerInfoResponse
 }>();
 
 const viewBoxX = ref<number>(50);
 const viewBoxY = ref<number>(30);
-const stats = ref<any[]>([]);
+const stats = ref<Misskey.entities.ServerStats[]>([]);
 const cpuGradientId = uuid();
 const cpuMaskId = uuid();
 const memGradientId = uuid();
@@ -107,6 +107,7 @@ onMounted(() => {
 	props.connection.on('statsLog', onStatsLog);
 	props.connection.send('requestLog', {
 		id: Math.random().toString().substring(2, 10),
+		length: 50,
 	});
 });
 
@@ -115,7 +116,7 @@ onBeforeUnmount(() => {
 	props.connection.off('statsLog', onStatsLog);
 });
 
-function onStats(connStats) {
+function onStats(connStats: Misskey.entities.ServerStats) {
 	stats.value.push(connStats);
 	if (stats.value.length > 50) stats.value.shift();
 
@@ -136,8 +137,8 @@ function onStats(connStats) {
 	memP.value = (connStats.mem.active / props.meta.mem.total * 100).toFixed(0);
 }
 
-function onStatsLog(statsLog) {
-	for (const revStats of [...statsLog].reverse()) {
+function onStatsLog(statsLog: Misskey.entities.ServerStatsLog) {
+	for (const revStats of statsLog.reverse()) {
 		onStats(revStats);
 	}
 }
diff --git a/packages/frontend/src/widgets/server-metric/cpu.vue b/packages/frontend/src/widgets/server-metric/cpu.vue
index c7fd0e9023..3778c4318e 100644
--- a/packages/frontend/src/widgets/server-metric/cpu.vue
+++ b/packages/frontend/src/widgets/server-metric/cpu.vue
@@ -20,13 +20,13 @@ import * as Misskey from 'misskey-js';
 import XPie from './pie.vue';
 
 const props = defineProps<{
-	connection: any,
+	connection: Misskey.ChannelConnection<Misskey.Channels['serverStats']>,
 	meta: Misskey.entities.ServerInfoResponse
 }>();
 
 const usage = ref<number>(0);
 
-function onStats(stats) {
+function onStats(stats: Misskey.entities.ServerStats) {
 	usage.value = stats.cpu;
 }
 
diff --git a/packages/frontend/src/widgets/server-metric/index.vue b/packages/frontend/src/widgets/server-metric/index.vue
index f5e80b0d21..990590e0d1 100644
--- a/packages/frontend/src/widgets/server-metric/index.vue
+++ b/packages/frontend/src/widgets/server-metric/index.vue
@@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <script lang="ts" setup>
 import { onUnmounted, ref } from 'vue';
 import * as Misskey from 'misskey-js';
-import { useWidgetPropsManager, Widget, WidgetComponentExpose } from '../widget.js';
+import { useWidgetPropsManager, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from '../widget.js';
 import XCpuMemory from './cpu-mem.vue';
 import XNet from './net.vue';
 import XCpu from './cpu.vue';
@@ -54,11 +54,8 @@ const widgetPropsDef = {
 
 type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 
-// 現時点ではvueの制限によりimportしたtypeをジェネリックに渡せない
-//const props = defineProps<WidgetComponentProps<WidgetProps>>();
-//const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
-const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
+const props = defineProps<WidgetComponentProps<WidgetProps>>();
+const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 
 const { widgetProps, configure, save } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/frontend/src/widgets/server-metric/mem.vue b/packages/frontend/src/widgets/server-metric/mem.vue
index f51b2af390..6c9e3efe67 100644
--- a/packages/frontend/src/widgets/server-metric/mem.vue
+++ b/packages/frontend/src/widgets/server-metric/mem.vue
@@ -22,7 +22,7 @@ import XPie from './pie.vue';
 import bytes from '@/filters/bytes.js';
 
 const props = defineProps<{
-	connection: any,
+	connection: Misskey.ChannelConnection<Misskey.Channels['serverStats']>,
 	meta: Misskey.entities.ServerInfoResponse
 }>();
 
@@ -31,7 +31,7 @@ const total = ref<number>(0);
 const used = ref<number>(0);
 const free = ref<number>(0);
 
-function onStats(stats) {
+function onStats(stats: Misskey.entities.ServerStats) {
 	usage.value = stats.mem.active / props.meta.mem.total;
 	total.value = props.meta.mem.total;
 	used.value = stats.mem.active;
diff --git a/packages/frontend/src/widgets/server-metric/net.vue b/packages/frontend/src/widgets/server-metric/net.vue
index 7af88a94eb..d33c2c577d 100644
--- a/packages/frontend/src/widgets/server-metric/net.vue
+++ b/packages/frontend/src/widgets/server-metric/net.vue
@@ -54,13 +54,13 @@ import * as Misskey from 'misskey-js';
 import bytes from '@/filters/bytes.js';
 
 const props = defineProps<{
-	connection: any,
+	connection: Misskey.ChannelConnection<Misskey.Channels['serverStats']>,
 	meta: Misskey.entities.ServerInfoResponse
 }>();
 
 const viewBoxX = ref<number>(50);
 const viewBoxY = ref<number>(30);
-const stats = ref<any[]>([]);
+const stats = ref<Misskey.entities.ServerStats[]>([]);
 const inPolylinePoints = ref<string>('');
 const outPolylinePoints = ref<string>('');
 const inPolygonPoints = ref<string>('');
@@ -77,6 +77,7 @@ onMounted(() => {
 	props.connection.on('statsLog', onStatsLog);
 	props.connection.send('requestLog', {
 		id: Math.random().toString().substring(2, 10),
+		length: 50,
 	});
 });
 
@@ -85,7 +86,7 @@ onBeforeUnmount(() => {
 	props.connection.off('statsLog', onStatsLog);
 });
 
-function onStats(connStats) {
+function onStats(connStats: Misskey.entities.ServerStats) {
 	stats.value.push(connStats);
 	if (stats.value.length > 50) stats.value.shift();
 
@@ -109,8 +110,8 @@ function onStats(connStats) {
 	outRecent.value = connStats.net.tx;
 }
 
-function onStatsLog(statsLog) {
-	for (const revStats of [...statsLog].reverse()) {
+function onStatsLog(statsLog: Misskey.entities.ServerStatsLog) {
+	for (const revStats of statsLog.reverse()) {
 		onStats(revStats);
 	}
 }
diff --git a/packages/frontend/test/emoji.test.ts b/packages/frontend/test/emoji.test.ts
new file mode 100644
index 0000000000..a1782a4913
--- /dev/null
+++ b/packages/frontend/test/emoji.test.ts
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { describe, test, assert, afterEach } from 'vitest';
+import { render, cleanup, type RenderResult } from '@testing-library/vue';
+import { defaultStoreState } from './init.js';
+import { getEmojiName } from '@/scripts/emojilist.js';
+import { components } from '@/components/index.js';
+import { directives } from '@/directives/index.js';
+import MkEmoji from '@/components/global/MkEmoji.vue';
+
+describe('Emoji', () => {
+	const renderEmoji = (emoji: string): RenderResult => {
+		return render(MkEmoji, {
+			props: { emoji },
+			global: { directives, components },
+		});
+	};
+
+	afterEach(() => {
+		cleanup();
+		defaultStoreState.emojiStyle = '';
+	});
+
+	describe('MkEmoji', () => {
+		test('Should render selector-less heart with color in native mode', async () => {
+			defaultStoreState.emojiStyle = 'native';
+			const mkEmoji = await renderEmoji('\u2764'); // monochrome heart
+			assert.ok(mkEmoji.queryByText('\u2764\uFE0F')); // colored heart
+			assert.ok(!mkEmoji.queryByText('\u2764'));
+		});
+	});
+
+	describe('Emoji list', () => {
+		test('Should get the name of the heart', () => {
+			assert.strictEqual(getEmojiName('\u2764'), 'heart');
+		});
+	});
+});
diff --git a/packages/frontend/test/init.ts b/packages/frontend/test/init.ts
index 6d93ff8cb0..f21248cfee 100644
--- a/packages/frontend/test/init.ts
+++ b/packages/frontend/test/init.ts
@@ -17,21 +17,23 @@ updateI18n(locales['en-US']);
 // XXX: misskey-js panics if WebSocket is not defined
 vi.stubGlobal('WebSocket', class WebSocket extends EventTarget { static CLOSING = 2; });
 
+export const defaultStoreState: Record<string, unknown> = {
+
+	// なんかtestがうまいこと動かないのでここに書く
+	dataSaver: {
+		media: false,
+		avatar: false,
+		urlPreview: false,
+		code: false,
+	},
+
+};
+
 // XXX: defaultStore somehow becomes undefined in vitest?
 vi.mock('@/store.js', () => {
 	return {
 		defaultStore: {
-			state: {
-
-				// なんかtestがうまいこと動かないのでここに書く
-				dataSaver: {
-					media: false,
-					avatar: false,
-					urlPreview: false,
-					code: false,
-				},
-
-			},
+			state: defaultStoreState,
 		},
 	};
 });
diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md
index cd099be1ef..b7f597f0c0 100644
--- a/packages/misskey-js/etc/misskey-js.api.md
+++ b/packages/misskey-js/etc/misskey-js.api.md
@@ -2558,7 +2558,7 @@ type QueueStats = {
 };
 
 // @public (undocumented)
-type QueueStatsLog = string[];
+type QueueStatsLog = QueueStats[];
 
 // @public (undocumented)
 type RenoteMuteCreateRequest = operations['renote-mute/create']['requestBody']['content']['application/json'];
@@ -2632,7 +2632,7 @@ type ServerStats = {
 };
 
 // @public (undocumented)
-type ServerStatsLog = string[];
+type ServerStatsLog = ServerStats[];
 
 // @public (undocumented)
 type Signin = components['schemas']['Signin'];
diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts
index d6a2e712df..86e83448ec 100644
--- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts
+++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts
@@ -1,6 +1,6 @@
 /*
  * version: 2023.12.2
- * generatedAt: 2024-01-02T08:53:57.449Z
+ * generatedAt: 2024-01-07T15:22:15.630Z
  */
 
 import type { SwitchCaseResponseType } from '../api.js';
@@ -2255,6 +2255,18 @@ declare module '../api.js' {
      * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
      * **Credential required**: *Yes*
      */
+    request<E extends 'i/export-clips', P extends Endpoints[E]['req']>(
+      endpoint: E,
+      params: P,
+      credential?: string | null,
+    ): Promise<SwitchCaseResponseType<E, P>>;
+
+    /**
+     * No description provided.
+     * 
+     * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
+     * **Credential required**: *Yes*
+     */
     request<E extends 'i/export-favorites', P extends Endpoints[E]['req']>(
       endpoint: E,
       params: P,
diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts
index 192a1a31e0..cc4d251f4d 100644
--- a/packages/misskey-js/src/autogen/endpoint.ts
+++ b/packages/misskey-js/src/autogen/endpoint.ts
@@ -1,6 +1,6 @@
 /*
  * version: 2023.12.2
- * generatedAt: 2024-01-02T08:53:57.445Z
+ * generatedAt: 2024-01-07T15:22:15.626Z
  */
 
 import type {
@@ -745,6 +745,7 @@ export type Endpoints = {
 	'i/export-following': { req: IExportFollowingRequest; res: EmptyResponse };
 	'i/export-mute': { req: EmptyRequest; res: EmptyResponse };
 	'i/export-notes': { req: EmptyRequest; res: EmptyResponse };
+	'i/export-clips': { req: EmptyRequest; res: EmptyResponse };
 	'i/export-favorites': { req: EmptyRequest; res: EmptyResponse };
 	'i/export-user-lists': { req: EmptyRequest; res: EmptyResponse };
 	'i/export-antennas': { req: EmptyRequest; res: EmptyResponse };
diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts
index fd4d7372cc..1f3f55b2fd 100644
--- a/packages/misskey-js/src/autogen/entities.ts
+++ b/packages/misskey-js/src/autogen/entities.ts
@@ -1,6 +1,6 @@
 /*
  * version: 2023.12.2
- * generatedAt: 2024-01-02T08:53:57.443Z
+ * generatedAt: 2024-01-07T15:22:15.624Z
  */
 
 import { operations } from './types.js';
diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts
index 5c07e963b0..1f49debe67 100644
--- a/packages/misskey-js/src/autogen/models.ts
+++ b/packages/misskey-js/src/autogen/models.ts
@@ -1,6 +1,6 @@
 /*
  * version: 2023.12.2
- * generatedAt: 2024-01-06T10:58:05.668Z
+ * generatedAt: 2024-01-07T15:22:15.623Z
  */
 
 import { components } from './types.js';
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index c48ff1d28f..bcfa5ea01b 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -3,7 +3,7 @@
 
 /*
  * version: 2023.12.2
- * generatedAt: 2024-01-02T08:53:56.447Z
+ * generatedAt: 2024-01-07T15:22:15.494Z
  */
 
 /**
@@ -1966,6 +1966,16 @@ export type paths = {
      */
     post: operations['i/export-notes'];
   };
+  '/i/export-clips': {
+    /**
+     * i/export-clips
+     * @description No description provided.
+     *
+     * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
+     * **Credential required**: *Yes*
+     */
+    post: operations['i/export-clips'];
+  };
   '/i/export-favorites': {
     /**
      * i/export-favorites
@@ -4424,6 +4434,9 @@ export type operations = {
             emailRequiredForSignup: boolean;
             enableHcaptcha: boolean;
             hcaptchaSiteKey: string | null;
+            enableMcaptcha: boolean;
+            mcaptchaSiteKey: string | null;
+            mcaptchaInstanceUrl: string | null;
             enableRecaptcha: boolean;
             recaptchaSiteKey: string | null;
             enableTurnstile: boolean;
@@ -4449,6 +4462,7 @@ export type operations = {
             bannedEmailDomains?: string[];
             preservedUsernames: string[];
             hcaptchaSecretKey: string | null;
+            mcaptchaSecretKey: string | null;
             recaptchaSecretKey: string | null;
             turnstileSecretKey: string | null;
             sensitiveMediaDetection: string;
@@ -8221,6 +8235,10 @@ export type operations = {
           enableHcaptcha?: boolean;
           hcaptchaSiteKey?: string | null;
           hcaptchaSecretKey?: string | null;
+          enableMcaptcha?: boolean;
+          mcaptchaSiteKey?: string | null;
+          mcaptchaInstanceUrl?: string | null;
+          mcaptchaSecretKey?: string | null;
           enableRecaptcha?: boolean;
           recaptchaSiteKey?: string | null;
           recaptchaSecretKey?: string | null;
@@ -15949,7 +15967,7 @@ export type operations = {
       content: {
         'application/json': {
           /** @enum {string} */
-          name: 'notes1' | 'notes10' | 'notes100' | 'notes500' | 'notes1000' | 'notes5000' | 'notes10000' | 'notes20000' | 'notes30000' | 'notes40000' | 'notes50000' | 'notes60000' | 'notes70000' | 'notes80000' | 'notes90000' | 'notes100000' | 'login3' | 'login7' | 'login15' | 'login30' | 'login60' | 'login100' | 'login200' | 'login300' | 'login400' | 'login500' | 'login600' | 'login700' | 'login800' | 'login900' | 'login1000' | 'passedSinceAccountCreated1' | 'passedSinceAccountCreated2' | 'passedSinceAccountCreated3' | 'loggedInOnBirthday' | 'loggedInOnNewYearsDay' | 'noteClipped1' | 'noteFavorited1' | 'myNoteFavorited1' | 'profileFilled' | 'markedAsCat' | 'following1' | 'following10' | 'following50' | 'following100' | 'following300' | 'followers1' | 'followers10' | 'followers50' | 'followers100' | 'followers300' | 'followers500' | 'followers1000' | 'collectAchievements30' | 'viewAchievements3min' | 'iLoveMisskey' | 'foundTreasure' | 'client30min' | 'client60min' | 'noteDeletedWithin1min' | 'postedAtLateNight' | 'postedAt0min0sec' | 'selfQuote' | 'htl20npm' | 'viewInstanceChart' | 'outputHelloWorldOnScratchpad' | 'open3windows' | 'driveFolderCircularReference' | 'reactWithoutRead' | 'clickedClickHere' | 'justPlainLucky' | 'setNameToSyuilo' | 'cookieClicked' | 'brainDiver' | 'smashTestNotificationButton' | 'tutorialCompleted';
+          name: 'notes1' | 'notes10' | 'notes100' | 'notes500' | 'notes1000' | 'notes5000' | 'notes10000' | 'notes20000' | 'notes30000' | 'notes40000' | 'notes50000' | 'notes60000' | 'notes70000' | 'notes80000' | 'notes90000' | 'notes100000' | 'login3' | 'login7' | 'login15' | 'login30' | 'login60' | 'login100' | 'login200' | 'login300' | 'login400' | 'login500' | 'login600' | 'login700' | 'login800' | 'login900' | 'login1000' | 'passedSinceAccountCreated1' | 'passedSinceAccountCreated2' | 'passedSinceAccountCreated3' | 'loggedInOnBirthday' | 'loggedInOnNewYearsDay' | 'noteClipped1' | 'noteFavorited1' | 'myNoteFavorited1' | 'profileFilled' | 'markedAsCat' | 'following1' | 'following10' | 'following50' | 'following100' | 'following300' | 'followers1' | 'followers10' | 'followers50' | 'followers100' | 'followers300' | 'followers500' | 'followers1000' | 'collectAchievements30' | 'viewAchievements3min' | 'iLoveMisskey' | 'foundTreasure' | 'client30min' | 'client60min' | 'noteDeletedWithin1min' | 'postedAtLateNight' | 'postedAt0min0sec' | 'selfQuote' | 'htl20npm' | 'viewInstanceChart' | 'outputHelloWorldOnScratchpad' | 'open3windows' | 'driveFolderCircularReference' | 'reactWithoutRead' | 'clickedClickHere' | 'justPlainLucky' | 'setNameToSyuilo' | 'cookieClicked' | 'brainDiver' | 'smashTestNotificationButton' | 'tutorialCompleted' | 'bubbleGameExplodingHead' | 'bubbleGameDoubleExplodingHead';
         };
       };
     };
@@ -16311,6 +16329,57 @@ export type operations = {
       };
     };
   };
+  /**
+   * i/export-clips
+   * @description No description provided.
+   *
+   * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
+   * **Credential required**: *Yes*
+   */
+  'i/export-clips': {
+    responses: {
+      /** @description OK (without any results) */
+      204: {
+        content: never;
+      };
+      /** @description Client error */
+      400: {
+        content: {
+          'application/json': components['schemas']['Error'];
+        };
+      };
+      /** @description Authentication error */
+      401: {
+        content: {
+          'application/json': components['schemas']['Error'];
+        };
+      };
+      /** @description Forbidden error */
+      403: {
+        content: {
+          'application/json': components['schemas']['Error'];
+        };
+      };
+      /** @description I'm Ai */
+      418: {
+        content: {
+          'application/json': components['schemas']['Error'];
+        };
+      };
+      /** @description To many requests */
+      429: {
+        content: {
+          'application/json': components['schemas']['Error'];
+        };
+      };
+      /** @description Internal server error */
+      500: {
+        content: {
+          'application/json': components['schemas']['Error'];
+        };
+      };
+    };
+  };
   /**
    * i/export-favorites
    * @description No description provided.
@@ -18780,6 +18849,9 @@ export type operations = {
             emailRequiredForSignup: boolean;
             enableHcaptcha: boolean;
             hcaptchaSiteKey: string | null;
+            enableMcaptcha: boolean;
+            mcaptchaSiteKey: string | null;
+            mcaptchaInstanceUrl: string | null;
             enableRecaptcha: boolean;
             recaptchaSiteKey: string | null;
             enableTurnstile: boolean;
diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts
index 6314c88e0b..e00e192e0d 100644
--- a/packages/misskey-js/src/entities.ts
+++ b/packages/misskey-js/src/entities.ts
@@ -149,7 +149,7 @@ export type ServerStats = {
 	}
 };
 
-export type ServerStatsLog = string[];
+export type ServerStatsLog = ServerStats[];
 
 export type QueueStats = {
 	deliver: {
@@ -166,7 +166,7 @@ export type QueueStats = {
 	};
 };
 
-export type QueueStatsLog = string[];
+export type QueueStatsLog = QueueStats[];
 
 export type EmojiAdded = {
 	emoji: EmojiDetailed
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 562c90595e..28cfe3222f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -661,6 +661,9 @@ importers:
       '@github/webauthn-json':
         specifier: 2.1.1
         version: 2.1.1
+      '@mcaptcha/vanilla-glue':
+        specifier: 0.1.0-alpha-3
+        version: 0.1.0-alpha-3
       '@misskey-dev/browser-image-resizer':
         specifier: 2.2.1-misskey.10
         version: 2.2.1-misskey.10
@@ -1820,7 +1823,7 @@ packages:
       '@babel/traverse': 7.22.11
       '@babel/types': 7.22.17
       convert-source-map: 1.9.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       gensync: 1.0.0-beta.2
       json5: 2.2.3
       semver: 6.3.1
@@ -1843,7 +1846,7 @@ packages:
       '@babel/traverse': 7.23.5
       '@babel/types': 7.23.5
       convert-source-map: 2.0.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       gensync: 1.0.0-beta.2
       json5: 2.2.3
       semver: 6.3.1
@@ -1945,7 +1948,7 @@ packages:
       '@babel/core': 7.23.5
       '@babel/helper-compilation-targets': 7.22.15
       '@babel/helper-plugin-utils': 7.22.5
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       lodash.debounce: 4.0.8
       resolve: 1.22.8
     transitivePeerDependencies:
@@ -3345,7 +3348,7 @@ packages:
       '@babel/helper-split-export-declaration': 7.22.6
       '@babel/parser': 7.23.5
       '@babel/types': 7.22.17
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
@@ -3363,7 +3366,7 @@ packages:
       '@babel/helper-split-export-declaration': 7.22.6
       '@babel/parser': 7.23.5
       '@babel/types': 7.23.5
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
@@ -4242,7 +4245,7 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
       ajv: 6.12.6
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       espree: 9.6.1
       globals: 13.19.0
       ignore: 5.2.4
@@ -4259,7 +4262,7 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
       ajv: 6.12.6
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       espree: 9.6.1
       globals: 13.19.0
       ignore: 5.2.4
@@ -4524,7 +4527,7 @@ packages:
     engines: {node: '>=10.10.0'}
     dependencies:
       '@humanwhocodes/object-schema': 2.0.1
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       minimatch: 3.1.2
     transitivePeerDependencies:
       - supports-color
@@ -4902,6 +4905,16 @@ packages:
     dev: false
     optional: true
 
+  /@mcaptcha/core-glue@0.1.0-alpha-5:
+    resolution: {integrity: sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==}
+    dev: false
+
+  /@mcaptcha/vanilla-glue@0.1.0-alpha-3:
+    resolution: {integrity: sha512-GT6TJBgmViGXcXiT5VOr+h/6iOnThSlZuCoOWncubyTZU9R3cgU5vWPkF7G6Ob6ee2CBe3yqBxxk24CFVGTVXw==}
+    dependencies:
+      '@mcaptcha/core-glue': 0.1.0-alpha-5
+    dev: false
+
   /@mdx-js/react@2.3.0(react@18.2.0):
     resolution: {integrity: sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==}
     peerDependencies:
@@ -5084,7 +5097,7 @@ packages:
       '@open-draft/until': 1.0.3
       '@types/debug': 4.1.7
       '@xmldom/xmldom': 0.8.6
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       headers-polyfill: 3.2.5
       outvariant: 1.4.0
       strict-event-emitter: 0.2.8
@@ -7365,7 +7378,7 @@ packages:
     hasBin: true
     peerDependencies:
       '@swc/core': ^1.2.66
-      chokidar: 3.5.3
+      chokidar: ^3.5.1
     peerDependenciesMeta:
       chokidar:
         optional: true
@@ -8493,7 +8506,7 @@ packages:
       '@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3)
       '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3)
       '@typescript-eslint/visitor-keys': 6.11.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       eslint: 8.53.0
       graphemer: 1.4.0
       ignore: 5.2.4
@@ -8522,7 +8535,7 @@ packages:
       '@typescript-eslint/type-utils': 6.14.0(eslint@8.56.0)(typescript@5.3.3)
       '@typescript-eslint/utils': 6.14.0(eslint@8.56.0)(typescript@5.3.3)
       '@typescript-eslint/visitor-keys': 6.14.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       eslint: 8.56.0
       graphemer: 1.4.0
       ignore: 5.2.4
@@ -8548,7 +8561,7 @@ packages:
       '@typescript-eslint/types': 6.11.0
       '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3)
       '@typescript-eslint/visitor-keys': 6.11.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       eslint: 8.53.0
       typescript: 5.3.3
     transitivePeerDependencies:
@@ -8569,7 +8582,7 @@ packages:
       '@typescript-eslint/types': 6.14.0
       '@typescript-eslint/typescript-estree': 6.14.0(typescript@5.3.3)
       '@typescript-eslint/visitor-keys': 6.14.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       eslint: 8.56.0
       typescript: 5.3.3
     transitivePeerDependencies:
@@ -8604,7 +8617,7 @@ packages:
     dependencies:
       '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3)
       '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3)
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       eslint: 8.53.0
       ts-api-utils: 1.0.1(typescript@5.3.3)
       typescript: 5.3.3
@@ -8624,7 +8637,7 @@ packages:
     dependencies:
       '@typescript-eslint/typescript-estree': 6.14.0(typescript@5.3.3)
       '@typescript-eslint/utils': 6.14.0(eslint@8.56.0)(typescript@5.3.3)
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       eslint: 8.56.0
       ts-api-utils: 1.0.1(typescript@5.3.3)
       typescript: 5.3.3
@@ -8653,7 +8666,7 @@ packages:
     dependencies:
       '@typescript-eslint/types': 6.11.0
       '@typescript-eslint/visitor-keys': 6.11.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       globby: 11.1.0
       is-glob: 4.0.3
       semver: 7.5.4
@@ -8674,7 +8687,7 @@ packages:
     dependencies:
       '@typescript-eslint/types': 6.14.0
       '@typescript-eslint/visitor-keys': 6.14.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       globby: 11.1.0
       is-glob: 4.0.3
       semver: 7.5.4
@@ -9131,7 +9144,7 @@ packages:
     engines: {node: '>= 6.0.0'}
     requiresBuild: true
     dependencies:
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
 
@@ -9139,7 +9152,7 @@ packages:
     resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
     engines: {node: '>= 14'}
     dependencies:
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -9514,7 +9527,7 @@ packages:
     resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==}
     dependencies:
       archy: 1.0.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       fastq: 1.15.0
     transitivePeerDependencies:
       - supports-color
@@ -10948,7 +10961,6 @@ packages:
     dependencies:
       ms: 2.1.2
       supports-color: 5.5.0
-    dev: true
 
   /debug@4.3.4(supports-color@8.1.1):
     resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
@@ -10961,6 +10973,7 @@ packages:
     dependencies:
       ms: 2.1.2
       supports-color: 8.1.1
+    dev: true
 
   /decamelize-keys@1.1.1:
     resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==}
@@ -11177,7 +11190,7 @@ packages:
     hasBin: true
     dependencies:
       address: 1.2.2
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -11501,7 +11514,7 @@ packages:
     peerDependencies:
       esbuild: '>=0.12 <1'
     dependencies:
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       esbuild: 0.18.20
     transitivePeerDependencies:
       - supports-color
@@ -11840,7 +11853,7 @@ packages:
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.3
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       doctrine: 3.0.0
       escape-string-regexp: 4.0.0
       eslint-scope: 7.2.2
@@ -11887,7 +11900,7 @@ packages:
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.3
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       doctrine: 3.0.0
       escape-string-regexp: 4.0.0
       eslint-scope: 7.2.2
@@ -12491,7 +12504,7 @@ packages:
       debug:
         optional: true
     dependencies:
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
 
   /for-each@0.3.3:
     resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@@ -13043,7 +13056,6 @@ packages:
   /has-flag@3.0.0:
     resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
     engines: {node: '>=4'}
-    dev: true
 
   /has-flag@4.0.0:
     resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
@@ -13181,7 +13193,7 @@ packages:
     engines: {node: '>= 14'}
     dependencies:
       agent-base: 7.1.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -13243,7 +13255,7 @@ packages:
     engines: {node: '>= 6.0.0'}
     dependencies:
       agent-base: 5.1.1
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -13253,7 +13265,7 @@ packages:
     engines: {node: '>= 6'}
     dependencies:
       agent-base: 6.0.2
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
 
@@ -13262,7 +13274,7 @@ packages:
     engines: {node: '>= 14'}
     dependencies:
       agent-base: 7.1.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -13272,7 +13284,7 @@ packages:
     engines: {node: '>= 14'}
     dependencies:
       agent-base: 7.1.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -13422,7 +13434,7 @@ packages:
     dependencies:
       '@ioredis/commands': 1.2.0
       cluster-key-slot: 1.1.2
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       denque: 2.1.0
       lodash.defaults: 4.2.0
       lodash.isarguments: 3.1.0
@@ -13863,7 +13875,7 @@ packages:
     resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
     engines: {node: '>=10'}
     dependencies:
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       istanbul-lib-coverage: 3.2.0
       source-map: 0.6.1
     transitivePeerDependencies:
@@ -14541,7 +14553,7 @@ packages:
     resolution: {integrity: sha512-pJ4XLQP4Q9HTxl6RVDLJ8Cyh1uitSs0CzDBAz1uoJ4sRD/Bk7cFSXL1FUXDW3zJ7YnfliJx6eu8Jn283bpZ4Yg==}
     engines: {node: '>=10'}
     dependencies:
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       rfdc: 1.3.0
       uri-js: 4.4.1
     transitivePeerDependencies:
@@ -17109,7 +17121,7 @@ packages:
     engines: {node: '>=8.16.0'}
     dependencies:
       '@types/mime-types': 2.1.4
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       extract-zip: 1.7.0
       https-proxy-agent: 4.0.0
       mime: 2.6.0
@@ -18108,7 +18120,7 @@ packages:
     dependencies:
       '@hapi/hoek': 10.0.1
       '@hapi/wreck': 18.0.1
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       joi: 17.7.0
     transitivePeerDependencies:
       - supports-color
@@ -18308,7 +18320,7 @@ packages:
     engines: {node: '>= 14'}
     dependencies:
       agent-base: 7.1.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       socks: 2.7.1
     transitivePeerDependencies:
       - supports-color
@@ -18461,7 +18473,7 @@ packages:
       arg: 5.0.2
       bluebird: 3.7.2
       check-more-types: 2.24.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       execa: 5.1.1
       lazy-ass: 1.6.0
       ps-tree: 1.2.0
@@ -18726,7 +18738,6 @@ packages:
     engines: {node: '>=4'}
     dependencies:
       has-flag: 3.0.0
-    dev: true
 
   /supports-color@7.2.0:
     resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
@@ -19343,7 +19354,7 @@ packages:
       chalk: 4.1.2
       cli-highlight: 2.1.11
       date-fns: 2.30.0
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       dotenv: 16.0.3
       glob: 8.1.0
       ioredis: 5.3.2
@@ -19701,7 +19712,7 @@ packages:
     hasBin: true
     dependencies:
       cac: 6.7.14
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       mlly: 1.4.0
       pathe: 1.1.1
       picocolors: 1.0.0
@@ -19813,7 +19824,7 @@ packages:
       acorn-walk: 8.2.0
       cac: 6.7.14
       chai: 4.3.10
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       happy-dom: 10.0.3
       local-pkg: 0.4.3
       magic-string: 0.30.3
@@ -19895,7 +19906,7 @@ packages:
     peerDependencies:
       eslint: '>=6.0.0'
     dependencies:
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.4(supports-color@5.5.0)
       eslint: 8.56.0
       eslint-scope: 7.2.2
       eslint-visitor-keys: 3.4.3