diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0fd61442e4..99ab40f761 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,16 @@
 
 -->
 
+## 12.x.x (unreleased)
+
+### Changes
+- Room機能が削除されました
+  - 後日別リポジトリとして復活予定です
+
+### Improvements
+
+### Bugfixes
+
 ## 12.101.1 (2021/12/29)
 
 ### Bugfixes
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a16a76abcf..c7a4773bc7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -90,17 +90,6 @@ Misskey uses Vue(v3) as its front-end framework.
 **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
 Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
 
-## Adding MisskeyRoom items
-* Use English for material, object and texture names.
-* Use meter for unit of length.
-* Your PR should include all source files (e.g. `.png`, `.blend`) of your models (for later editing).
-* Your PR must include the glTF binary files (`.glb`) of your models.
-* Add a locale key `room.furnitures.YOUR_ITEM` at [`/locales/ja-JP.yml`](/locales/ja-JP.yml).
-* Add a furniture definition at [`src/client/scripts/room/furnitures.json5`](src/client/scripts/room/furnitures.json5).
-
-If you have no experience on 3D modeling, we suggest to use the free 3DCG software [Blender](https://www.blender.org/).
-You can find information on glTF 2.0 at [glTF 2.0 — Blender Manual]( https://docs.blender.org/manual/en/dev/addons/io_scene_gltf2.html).
-
 ## Notes
 ### How to resolve conflictions occurred at yarn.lock?
 
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 74964e366a..5ba09c4a81 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -537,7 +537,6 @@ yourAccountSuspendedDescription: "このアカウントは、サーバーの利
 menu: "メニュー"
 divider: "分割線"
 addItem: "項目を追加"
-rooms: "ルーム"
 relays: "リレー"
 addRelay: "リレーの追加"
 inboxUrl: "inboxのURL"
@@ -1362,69 +1361,6 @@ _timelines:
   social: "ソーシャル"
   global: "グローバル"
 
-_rooms:
-  roomOf: "{user}のルーム"
-  addFurniture: "家具を置く"
-  translate: "移動"
-  rotate: "回転"
-  exit: "戻る"
-  remove: "しまう"
-  clear: "片付け"
-  clearConfirm: "全ての家具をしまいますか?"
-  leaveConfirm: "未保存の変更があります、移動しますか?"
-  chooseImage: "画像を選択"
-  roomType: "部屋のタイプ"
-  carpetColor: "床の色"
-  _roomType:
-    default: "デフォルト"
-    washitsu: "和室"
-  _furnitures:
-    milk: "牛乳パック"
-    bed: "ベッド"
-    low-table: "ローテーブル"
-    desk: "デスク"
-    chair: "チェア"
-    chair2: "チェア2"
-    fan: "換気扇"
-    pc: "パソコン"
-    plant: "観葉植物"
-    plant2: "観葉植物2"
-    eraser: "消しゴム"
-    pencil: "鉛筆"
-    pudding: "プリン"
-    cardboard-box: "段ボール箱"
-    cardboard-box2: "段ボール箱2"
-    cardboard-box3: "段ボール箱3"
-    book: "本"
-    book2: "本2"
-    piano: "ピアノ"
-    facial-tissue: "ティッシュボックス"
-    server: "サーバー"
-    moon: "月"
-    corkboard: "コルクボード"
-    mousepad: "マウスパッド"
-    monitor: "モニター"
-    keyboard: "キーボード"
-    carpet-stripe: "カーペット(縞)"
-    mat: "マット"
-    color-box: "カラーボックス"
-    wall-clock: "壁掛け時計"
-    photoframe: "額縁"
-    cube: "キューブ"
-    tv: "テレビ"
-    pinguin: "ピンギン"
-    rubik-cube: "ルービックキューブ"
-    poster-h: "ポスター(横長)"
-    poster-v: "ポスター(縦長)"
-    sofa: "ソファ"
-    spiral: "螺旋階段"
-    bin: "ゴミ箱"
-    cup-noodle: "カップ麺"
-    holo-display: "ホログラフィックディスプレイ"
-    energy-drink: "エナジードリンク"
-    doll-ai: "藍ちゃん人形"
-    banknote: "札束"
-
 _pages:
   newPage: "ページの作成"
   editPage: "ページの編集"
diff --git a/packages/backend/src/models/entities/user-profile.ts b/packages/backend/src/models/entities/user-profile.ts
index eb8cdadd19..d8317de8d3 100644
--- a/packages/backend/src/models/entities/user-profile.ts
+++ b/packages/backend/src/models/entities/user-profile.ts
@@ -124,6 +124,7 @@ export class UserProfile {
 	})
 	public clientData: Record<string, any>;
 
+	// TODO: そのうち消す
 	@Column('jsonb', {
 		default: {},
 		comment: 'The room data of the User.',
diff --git a/packages/backend/src/server/api/endpoints/room/show.ts b/packages/backend/src/server/api/endpoints/room/show.ts
deleted file mode 100644
index a7193372ff..0000000000
--- a/packages/backend/src/server/api/endpoints/room/show.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-import $ from 'cafy';
-import define from '../../define';
-import { ApiError } from '../../error';
-import { Users, UserProfiles } from '@/models/index';
-import { ID } from '@/misc/cafy-id';
-import { toPunyNullable } from '@/misc/convert-host';
-
-export const meta = {
-	tags: ['room'],
-
-	requireCredential: false as const,
-
-	params: {
-		userId: {
-			validator: $.optional.type(ID),
-		},
-
-		username: {
-			validator: $.optional.str,
-		},
-
-		host: {
-			validator: $.optional.nullable.str,
-		},
-	},
-
-	errors: {
-		noSuchUser: {
-			message: 'No such user.',
-			code: 'NO_SUCH_USER',
-			id: '7ad3fa3e-5e12-42f0-b23a-f3d13f10ee4b',
-		},
-	},
-
-	res: {
-		type: 'object' as const,
-		optional: false as const, nullable: false as const,
-		properties: {
-			roomType: {
-				type: 'string' as const,
-				optional: false as const, nullable: false as const,
-				enum: ['default', 'washitsu'],
-			},
-			furnitures: {
-				type: 'array' as const,
-				optional: false as const, nullable: false as const,
-				items: {
-					type: 'object' as const,
-					optional: false as const, nullable: false as const,
-					properties: {
-						id: {
-							type: 'string' as const,
-							optional: false as const, nullable: false as const,
-						},
-						type: {
-							type: 'string' as const,
-							optional: false as const, nullable: false as const,
-						},
-						props: {
-							type: 'object' as const,
-							optional: true as const, nullable: false as const,
-						},
-						position: {
-							type: 'object' as const,
-							optional: false as const, nullable: false as const,
-							properties: {
-								x: {
-									type: 'number' as const,
-									optional: false as const, nullable: false as const,
-								},
-								y: {
-									type: 'number' as const,
-									optional: false as const, nullable: false as const,
-								},
-								z: {
-									type: 'number' as const,
-									optional: false as const, nullable: false as const,
-								},
-							},
-						},
-						rotation: {
-							type: 'object' as const,
-							optional: false as const, nullable: false as const,
-							properties: {
-								x: {
-									type: 'number' as const,
-									optional: false as const, nullable: false as const,
-								},
-								y: {
-									type: 'number' as const,
-									optional: false as const, nullable: false as const,
-								},
-								z: {
-									type: 'number' as const,
-									optional: false as const, nullable: false as const,
-								},
-							},
-						},
-					},
-				},
-			},
-			carpetColor: {
-				type: 'string' as const,
-				optional: false as const, nullable: false as const,
-				format: 'hex',
-				example: '#85CAF0',
-			},
-		},
-	},
-};
-
-// eslint-disable-next-line import/no-default-export
-export default define(meta, async (ps, me) => {
-	const user = await Users.findOne(ps.userId != null
-		? { id: ps.userId }
-		: { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) });
-
-	if (user == null) {
-		throw new ApiError(meta.errors.noSuchUser);
-	}
-
-	const profile = await UserProfiles.findOneOrFail(user.id);
-
-	if (profile.room.furnitures == null) {
-		await UserProfiles.update(user.id, {
-			room: {
-				furnitures: [],
-				...profile.room,
-			},
-		});
-
-		profile.room.furnitures = [];
-	}
-
-	if (profile.room.roomType == null) {
-		const initialType = 'default';
-		await UserProfiles.update(user.id, {
-			room: {
-				roomType: initialType as any,
-				...profile.room,
-			},
-		});
-
-		profile.room.roomType = initialType;
-	}
-
-	if (profile.room.carpetColor == null) {
-		const initialColor = '#85CAF0';
-		await UserProfiles.update(user.id, {
-			room: {
-				carpetColor: initialColor as any,
-				...profile.room,
-			},
-		});
-
-		profile.room.carpetColor = initialColor;
-	}
-
-	return profile.room;
-});
diff --git a/packages/backend/src/server/api/endpoints/room/update.ts b/packages/backend/src/server/api/endpoints/room/update.ts
deleted file mode 100644
index e2b18a8ab9..0000000000
--- a/packages/backend/src/server/api/endpoints/room/update.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import $ from 'cafy';
-import { publishMainStream } from '@/services/stream';
-import define from '../../define';
-import { Users, UserProfiles } from '@/models/index';
-
-export const meta = {
-	tags: ['room'],
-
-	requireCredential: true as const,
-
-	params: {
-		room: {
-			validator: $.obj({
-				furnitures: $.arr($.obj({
-					id: $.str,
-					type: $.str,
-					position: $.obj({
-						x: $.num,
-						y: $.num,
-						z: $.num,
-					}),
-					rotation: $.obj({
-						x: $.num,
-						y: $.num,
-						z: $.num,
-					}),
-					props: $.optional.nullable.obj(),
-				})),
-				roomType: $.str,
-				carpetColor: $.str,
-			}),
-		},
-	},
-};
-
-// eslint-disable-next-line import/no-default-export
-export default define(meta, async (ps, user) => {
-	await UserProfiles.update(user.id, {
-		room: ps.room as any,
-	});
-
-	const iObj = await Users.pack(user.id, user, {
-		detail: true,
-		includeSecrets: true,
-	});
-
-	// Publish meUpdated event
-	publishMainStream(user.id, 'meUpdated', iObj);
-
-	// TODO: レスポンスがおかしいと思う by YuzuRyo61
-	return iObj;
-});
diff --git a/packages/client/assets/room/furnitures/banknote/banknote.blend b/packages/client/assets/room/furnitures/banknote/banknote.blend
deleted file mode 100644
index 60b1968a29..0000000000
Binary files a/packages/client/assets/room/furnitures/banknote/banknote.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/banknote/banknote.glb b/packages/client/assets/room/furnitures/banknote/banknote.glb
deleted file mode 100644
index f4ef0b91e7..0000000000
Binary files a/packages/client/assets/room/furnitures/banknote/banknote.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/banknote/tex.png b/packages/client/assets/room/furnitures/banknote/tex.png
deleted file mode 100644
index 9106dc1457..0000000000
Binary files a/packages/client/assets/room/furnitures/banknote/tex.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/bed/bed.blend b/packages/client/assets/room/furnitures/bed/bed.blend
deleted file mode 100644
index 731df76d0c..0000000000
Binary files a/packages/client/assets/room/furnitures/bed/bed.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/bed/bed.glb b/packages/client/assets/room/furnitures/bed/bed.glb
deleted file mode 100644
index f35ecb9ef4..0000000000
Binary files a/packages/client/assets/room/furnitures/bed/bed.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/bin/bin.blend b/packages/client/assets/room/furnitures/bin/bin.blend
deleted file mode 100644
index 8d459a0869..0000000000
Binary files a/packages/client/assets/room/furnitures/bin/bin.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/bin/bin.glb b/packages/client/assets/room/furnitures/bin/bin.glb
deleted file mode 100644
index b45f203802..0000000000
Binary files a/packages/client/assets/room/furnitures/bin/bin.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book/book.blend b/packages/client/assets/room/furnitures/book/book.blend
deleted file mode 100644
index 0d4899d4ae..0000000000
Binary files a/packages/client/assets/room/furnitures/book/book.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book/book.glb b/packages/client/assets/room/furnitures/book/book.glb
deleted file mode 100644
index 546893da06..0000000000
Binary files a/packages/client/assets/room/furnitures/book/book.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book2/barcode.png b/packages/client/assets/room/furnitures/book2/barcode.png
deleted file mode 100644
index 37cfe5add3..0000000000
Binary files a/packages/client/assets/room/furnitures/book2/barcode.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book2/book2.blend b/packages/client/assets/room/furnitures/book2/book2.blend
deleted file mode 100644
index e0fdb48101..0000000000
Binary files a/packages/client/assets/room/furnitures/book2/book2.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book2/book2.glb b/packages/client/assets/room/furnitures/book2/book2.glb
deleted file mode 100644
index 2b26402f8c..0000000000
Binary files a/packages/client/assets/room/furnitures/book2/book2.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book2/texture.afdesign b/packages/client/assets/room/furnitures/book2/texture.afdesign
deleted file mode 100644
index b63771607a..0000000000
Binary files a/packages/client/assets/room/furnitures/book2/texture.afdesign and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book2/texture.png b/packages/client/assets/room/furnitures/book2/texture.png
deleted file mode 100644
index 5aa84f0340..0000000000
Binary files a/packages/client/assets/room/furnitures/book2/texture.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/book2/uv.png b/packages/client/assets/room/furnitures/book2/uv.png
deleted file mode 100644
index 61c4fb0400..0000000000
Binary files a/packages/client/assets/room/furnitures/book2/uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.blend b/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.blend
deleted file mode 100644
index 3a528de32a..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.glb b/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.glb
deleted file mode 100644
index bed372e94f..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend b/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend
deleted file mode 100644
index 5f146267ac..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb b/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb
deleted file mode 100644
index 85fcb5c0b6..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box2/texture.png b/packages/client/assets/room/furnitures/cardboard-box2/texture.png
deleted file mode 100644
index e498d8f65b..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box2/texture.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box2/uv.png b/packages/client/assets/room/furnitures/cardboard-box2/uv.png
deleted file mode 100644
index d547843ee0..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box2/uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend b/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend
deleted file mode 100644
index 00681a3cfd..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb b/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb
deleted file mode 100644
index 1ef0427689..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box3/texture.png b/packages/client/assets/room/furnitures/cardboard-box3/texture.png
deleted file mode 100644
index 56c914cb9d..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box3/texture.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box3/texture.xcf b/packages/client/assets/room/furnitures/cardboard-box3/texture.xcf
deleted file mode 100644
index 7ffb3e3439..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box3/texture.xcf and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cardboard-box3/uv.png b/packages/client/assets/room/furnitures/cardboard-box3/uv.png
deleted file mode 100644
index 797ac509db..0000000000
Binary files a/packages/client/assets/room/furnitures/cardboard-box3/uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend b/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend
deleted file mode 100644
index 750343d4f0..0000000000
Binary files a/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb b/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb
deleted file mode 100644
index 3066a69e35..0000000000
Binary files a/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/chair/chair.blend b/packages/client/assets/room/furnitures/chair/chair.blend
deleted file mode 100644
index 79c29a8401..0000000000
Binary files a/packages/client/assets/room/furnitures/chair/chair.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/chair/chair.glb b/packages/client/assets/room/furnitures/chair/chair.glb
deleted file mode 100644
index 08ee1a0bb0..0000000000
Binary files a/packages/client/assets/room/furnitures/chair/chair.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/chair2/chair2.blend b/packages/client/assets/room/furnitures/chair2/chair2.blend
deleted file mode 100644
index c6a1acd96f..0000000000
Binary files a/packages/client/assets/room/furnitures/chair2/chair2.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/chair2/chair2.glb b/packages/client/assets/room/furnitures/chair2/chair2.glb
deleted file mode 100644
index 5ea2f3518b..0000000000
Binary files a/packages/client/assets/room/furnitures/chair2/chair2.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/color-box/color-box.blend b/packages/client/assets/room/furnitures/color-box/color-box.blend
deleted file mode 100644
index f96a4ff766..0000000000
Binary files a/packages/client/assets/room/furnitures/color-box/color-box.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/color-box/color-box.glb b/packages/client/assets/room/furnitures/color-box/color-box.glb
deleted file mode 100644
index 43f2abcae8..0000000000
Binary files a/packages/client/assets/room/furnitures/color-box/color-box.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/corkboard/corkboard.blend b/packages/client/assets/room/furnitures/corkboard/corkboard.blend
deleted file mode 100644
index 9a7e1878cd..0000000000
Binary files a/packages/client/assets/room/furnitures/corkboard/corkboard.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/corkboard/corkboard.glb b/packages/client/assets/room/furnitures/corkboard/corkboard.glb
deleted file mode 100644
index fee108fb91..0000000000
Binary files a/packages/client/assets/room/furnitures/corkboard/corkboard.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cube/cube.blend b/packages/client/assets/room/furnitures/cube/cube.blend
deleted file mode 100644
index 1af5bf40a9..0000000000
Binary files a/packages/client/assets/room/furnitures/cube/cube.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cube/cube.glb b/packages/client/assets/room/furnitures/cube/cube.glb
deleted file mode 100644
index 4ac8b6036d..0000000000
Binary files a/packages/client/assets/room/furnitures/cube/cube.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.blend b/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.blend
deleted file mode 100644
index 37ca8868c7..0000000000
Binary files a/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.glb b/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.glb
deleted file mode 100644
index 58efb1b3b4..0000000000
Binary files a/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/cup-noodle/noodle.png b/packages/client/assets/room/furnitures/cup-noodle/noodle.png
deleted file mode 100644
index 1d74e0bbe7..0000000000
Binary files a/packages/client/assets/room/furnitures/cup-noodle/noodle.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/desk/desk.blend b/packages/client/assets/room/furnitures/desk/desk.blend
deleted file mode 100644
index c88d01f0b2..0000000000
Binary files a/packages/client/assets/room/furnitures/desk/desk.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/desk/desk.glb b/packages/client/assets/room/furnitures/desk/desk.glb
deleted file mode 100644
index 4a58513095..0000000000
Binary files a/packages/client/assets/room/furnitures/desk/desk.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/doll-ai/doll-ai.blend b/packages/client/assets/room/furnitures/doll-ai/doll-ai.blend
deleted file mode 100644
index a912231ecb..0000000000
Binary files a/packages/client/assets/room/furnitures/doll-ai/doll-ai.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/doll-ai/doll-ai.glb b/packages/client/assets/room/furnitures/doll-ai/doll-ai.glb
deleted file mode 100644
index ec55a7bd7b..0000000000
Binary files a/packages/client/assets/room/furnitures/doll-ai/doll-ai.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/doll-ai/doll_ai_tex.png b/packages/client/assets/room/furnitures/doll-ai/doll_ai_tex.png
deleted file mode 100644
index 370ca5f75b..0000000000
Binary files a/packages/client/assets/room/furnitures/doll-ai/doll_ai_tex.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/energy-drink/energy-drink.blend b/packages/client/assets/room/furnitures/energy-drink/energy-drink.blend
deleted file mode 100644
index 65fc41273e..0000000000
Binary files a/packages/client/assets/room/furnitures/energy-drink/energy-drink.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/energy-drink/energy-drink.glb b/packages/client/assets/room/furnitures/energy-drink/energy-drink.glb
deleted file mode 100644
index 7fb1c27836..0000000000
Binary files a/packages/client/assets/room/furnitures/energy-drink/energy-drink.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/energy-drink/texture.afdesign b/packages/client/assets/room/furnitures/energy-drink/texture.afdesign
deleted file mode 100644
index 8c117a49b1..0000000000
Binary files a/packages/client/assets/room/furnitures/energy-drink/texture.afdesign and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/energy-drink/texture.png b/packages/client/assets/room/furnitures/energy-drink/texture.png
deleted file mode 100644
index 484ca0f96f..0000000000
Binary files a/packages/client/assets/room/furnitures/energy-drink/texture.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/energy-drink/uv.png b/packages/client/assets/room/furnitures/energy-drink/uv.png
deleted file mode 100644
index 2a3f20c999..0000000000
Binary files a/packages/client/assets/room/furnitures/energy-drink/uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/eraser/cover.png b/packages/client/assets/room/furnitures/eraser/cover.png
deleted file mode 100644
index 932a3fc62e..0000000000
Binary files a/packages/client/assets/room/furnitures/eraser/cover.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/eraser/cover.psd b/packages/client/assets/room/furnitures/eraser/cover.psd
deleted file mode 100644
index c393337833..0000000000
Binary files a/packages/client/assets/room/furnitures/eraser/cover.psd and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/eraser/eraser-uv.png b/packages/client/assets/room/furnitures/eraser/eraser-uv.png
deleted file mode 100644
index 89e4ea4c45..0000000000
Binary files a/packages/client/assets/room/furnitures/eraser/eraser-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/eraser/eraser.blend b/packages/client/assets/room/furnitures/eraser/eraser.blend
deleted file mode 100644
index 103c54fbae..0000000000
Binary files a/packages/client/assets/room/furnitures/eraser/eraser.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/eraser/eraser.glb b/packages/client/assets/room/furnitures/eraser/eraser.glb
deleted file mode 100644
index 016b60df20..0000000000
Binary files a/packages/client/assets/room/furnitures/eraser/eraser.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png
deleted file mode 100644
index e3865ad15e..0000000000
Binary files a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.blend b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.blend
deleted file mode 100644
index d59f87c1ee..0000000000
Binary files a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.glb b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.glb
deleted file mode 100644
index 48b36ef347..0000000000
Binary files a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.png b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.png
deleted file mode 100644
index 7cee4b1859..0000000000
Binary files a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.psd b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.psd
deleted file mode 100644
index cd59fc007b..0000000000
Binary files a/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.psd and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/fan/fan.blend b/packages/client/assets/room/furnitures/fan/fan.blend
deleted file mode 100644
index 8c8106e5fe..0000000000
Binary files a/packages/client/assets/room/furnitures/fan/fan.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/fan/fan.glb b/packages/client/assets/room/furnitures/fan/fan.glb
deleted file mode 100644
index d9367f3534..0000000000
Binary files a/packages/client/assets/room/furnitures/fan/fan.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/holo-display/holo-display.blend b/packages/client/assets/room/furnitures/holo-display/holo-display.blend
deleted file mode 100644
index 56d2e1f819..0000000000
Binary files a/packages/client/assets/room/furnitures/holo-display/holo-display.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/holo-display/holo-display.glb b/packages/client/assets/room/furnitures/holo-display/holo-display.glb
deleted file mode 100644
index 4d042a59b3..0000000000
Binary files a/packages/client/assets/room/furnitures/holo-display/holo-display.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/holo-display/ray-uv.png b/packages/client/assets/room/furnitures/holo-display/ray-uv.png
deleted file mode 100644
index aa7e817e0f..0000000000
Binary files a/packages/client/assets/room/furnitures/holo-display/ray-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/holo-display/ray.png b/packages/client/assets/room/furnitures/holo-display/ray.png
deleted file mode 100644
index 6a5d24e143..0000000000
Binary files a/packages/client/assets/room/furnitures/holo-display/ray.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/keyboard/keyboard.blend b/packages/client/assets/room/furnitures/keyboard/keyboard.blend
deleted file mode 100644
index ab33d134b3..0000000000
Binary files a/packages/client/assets/room/furnitures/keyboard/keyboard.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/keyboard/keyboard.glb b/packages/client/assets/room/furnitures/keyboard/keyboard.glb
deleted file mode 100644
index 15dc69f47a..0000000000
Binary files a/packages/client/assets/room/furnitures/keyboard/keyboard.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/low-table/low-table.blend b/packages/client/assets/room/furnitures/low-table/low-table.blend
deleted file mode 100644
index e1592174d9..0000000000
Binary files a/packages/client/assets/room/furnitures/low-table/low-table.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/low-table/low-table.glb b/packages/client/assets/room/furnitures/low-table/low-table.glb
deleted file mode 100644
index c69bf35d7b..0000000000
Binary files a/packages/client/assets/room/furnitures/low-table/low-table.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/mat/mat.blend b/packages/client/assets/room/furnitures/mat/mat.blend
deleted file mode 100644
index a1e1a68c55..0000000000
Binary files a/packages/client/assets/room/furnitures/mat/mat.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/mat/mat.glb b/packages/client/assets/room/furnitures/mat/mat.glb
deleted file mode 100644
index 87ccd44e1a..0000000000
Binary files a/packages/client/assets/room/furnitures/mat/mat.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/milk/milk-uv.png b/packages/client/assets/room/furnitures/milk/milk-uv.png
deleted file mode 100644
index 258fd54638..0000000000
Binary files a/packages/client/assets/room/furnitures/milk/milk-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/milk/milk.blend b/packages/client/assets/room/furnitures/milk/milk.blend
deleted file mode 100644
index 2df508d5b9..0000000000
Binary files a/packages/client/assets/room/furnitures/milk/milk.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/milk/milk.glb b/packages/client/assets/room/furnitures/milk/milk.glb
deleted file mode 100644
index b335fe3d02..0000000000
Binary files a/packages/client/assets/room/furnitures/milk/milk.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/milk/milk.png b/packages/client/assets/room/furnitures/milk/milk.png
deleted file mode 100644
index 35181c8c8c..0000000000
Binary files a/packages/client/assets/room/furnitures/milk/milk.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/milk/milk.psd b/packages/client/assets/room/furnitures/milk/milk.psd
deleted file mode 100644
index f31e439277..0000000000
Binary files a/packages/client/assets/room/furnitures/milk/milk.psd and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/monitor/monitor.blend b/packages/client/assets/room/furnitures/monitor/monitor.blend
deleted file mode 100644
index 6c042ccdd8..0000000000
Binary files a/packages/client/assets/room/furnitures/monitor/monitor.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/monitor/monitor.glb b/packages/client/assets/room/furnitures/monitor/monitor.glb
deleted file mode 100644
index fc33286a15..0000000000
Binary files a/packages/client/assets/room/furnitures/monitor/monitor.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/monitor/monitor.psd b/packages/client/assets/room/furnitures/monitor/monitor.psd
deleted file mode 100644
index 57afff9cd9..0000000000
Binary files a/packages/client/assets/room/furnitures/monitor/monitor.psd and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/monitor/screen-uv.png b/packages/client/assets/room/furnitures/monitor/screen-uv.png
deleted file mode 100644
index 35f74de8aa..0000000000
Binary files a/packages/client/assets/room/furnitures/monitor/screen-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/monitor/screen.jpg b/packages/client/assets/room/furnitures/monitor/screen.jpg
deleted file mode 100644
index 4004a1ede9..0000000000
Binary files a/packages/client/assets/room/furnitures/monitor/screen.jpg and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/moon/moon.blend b/packages/client/assets/room/furnitures/moon/moon.blend
deleted file mode 100644
index 4ff3deab8e..0000000000
Binary files a/packages/client/assets/room/furnitures/moon/moon.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/moon/moon.glb b/packages/client/assets/room/furnitures/moon/moon.glb
deleted file mode 100644
index 07fa7e4c02..0000000000
Binary files a/packages/client/assets/room/furnitures/moon/moon.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/moon/moon.jpg b/packages/client/assets/room/furnitures/moon/moon.jpg
deleted file mode 100644
index 8988ac64b9..0000000000
Binary files a/packages/client/assets/room/furnitures/moon/moon.jpg and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/mousepad/mousepad.blend b/packages/client/assets/room/furnitures/mousepad/mousepad.blend
deleted file mode 100644
index 14bd139c94..0000000000
Binary files a/packages/client/assets/room/furnitures/mousepad/mousepad.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/mousepad/mousepad.glb b/packages/client/assets/room/furnitures/mousepad/mousepad.glb
deleted file mode 100644
index 681ada49cd..0000000000
Binary files a/packages/client/assets/room/furnitures/mousepad/mousepad.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pc/motherboard-uv.png b/packages/client/assets/room/furnitures/pc/motherboard-uv.png
deleted file mode 100644
index 355009fe7c..0000000000
Binary files a/packages/client/assets/room/furnitures/pc/motherboard-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pc/motherboard-uv.psd b/packages/client/assets/room/furnitures/pc/motherboard-uv.psd
deleted file mode 100644
index 971f33f79e..0000000000
Binary files a/packages/client/assets/room/furnitures/pc/motherboard-uv.psd and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pc/motherboard.jpg b/packages/client/assets/room/furnitures/pc/motherboard.jpg
deleted file mode 100644
index d894e4efcf..0000000000
Binary files a/packages/client/assets/room/furnitures/pc/motherboard.jpg and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pc/pc.blend b/packages/client/assets/room/furnitures/pc/pc.blend
deleted file mode 100644
index 13dfec6ccc..0000000000
Binary files a/packages/client/assets/room/furnitures/pc/pc.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pc/pc.glb b/packages/client/assets/room/furnitures/pc/pc.glb
deleted file mode 100644
index 44a48b18ae..0000000000
Binary files a/packages/client/assets/room/furnitures/pc/pc.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pencil/pencil.blend b/packages/client/assets/room/furnitures/pencil/pencil.blend
deleted file mode 100644
index 0fc6bdd776..0000000000
Binary files a/packages/client/assets/room/furnitures/pencil/pencil.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pencil/pencil.glb b/packages/client/assets/room/furnitures/pencil/pencil.glb
deleted file mode 100644
index a938b5cdcc..0000000000
Binary files a/packages/client/assets/room/furnitures/pencil/pencil.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/photoframe/photo-uv.png b/packages/client/assets/room/furnitures/photoframe/photo-uv.png
deleted file mode 100644
index 9b94906413..0000000000
Binary files a/packages/client/assets/room/furnitures/photoframe/photo-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/photoframe/photo.jpg b/packages/client/assets/room/furnitures/photoframe/photo.jpg
deleted file mode 100644
index af14f0f36a..0000000000
Binary files a/packages/client/assets/room/furnitures/photoframe/photo.jpg and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/photoframe/photoframe.blend b/packages/client/assets/room/furnitures/photoframe/photoframe.blend
deleted file mode 100644
index 4224cde45b..0000000000
Binary files a/packages/client/assets/room/furnitures/photoframe/photoframe.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/photoframe/photoframe.glb b/packages/client/assets/room/furnitures/photoframe/photoframe.glb
deleted file mode 100644
index 4255a77de6..0000000000
Binary files a/packages/client/assets/room/furnitures/photoframe/photoframe.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/piano/piano.blend b/packages/client/assets/room/furnitures/piano/piano.blend
deleted file mode 100644
index 7653cdf672..0000000000
Binary files a/packages/client/assets/room/furnitures/piano/piano.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/piano/piano.glb b/packages/client/assets/room/furnitures/piano/piano.glb
deleted file mode 100644
index 7242e78ceb..0000000000
Binary files a/packages/client/assets/room/furnitures/piano/piano.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pinguin/pinguin.blend b/packages/client/assets/room/furnitures/pinguin/pinguin.blend
deleted file mode 100644
index 514c713e4c..0000000000
Binary files a/packages/client/assets/room/furnitures/pinguin/pinguin.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pinguin/pinguin.glb b/packages/client/assets/room/furnitures/pinguin/pinguin.glb
deleted file mode 100644
index 6df34c06e9..0000000000
Binary files a/packages/client/assets/room/furnitures/pinguin/pinguin.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant/plant-soil-uv.png b/packages/client/assets/room/furnitures/plant/plant-soil-uv.png
deleted file mode 100644
index d4971a896c..0000000000
Binary files a/packages/client/assets/room/furnitures/plant/plant-soil-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant/plant-soil.png b/packages/client/assets/room/furnitures/plant/plant-soil.png
deleted file mode 100644
index e79ccd240e..0000000000
Binary files a/packages/client/assets/room/furnitures/plant/plant-soil.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant/plant-soil.psd b/packages/client/assets/room/furnitures/plant/plant-soil.psd
deleted file mode 100644
index 1457b7ea5b..0000000000
Binary files a/packages/client/assets/room/furnitures/plant/plant-soil.psd and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant/plant.blend b/packages/client/assets/room/furnitures/plant/plant.blend
deleted file mode 100644
index aa38c7b54e..0000000000
Binary files a/packages/client/assets/room/furnitures/plant/plant.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant/plant.glb b/packages/client/assets/room/furnitures/plant/plant.glb
deleted file mode 100644
index 38422b4a9b..0000000000
Binary files a/packages/client/assets/room/furnitures/plant/plant.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant2/plant2.blend b/packages/client/assets/room/furnitures/plant2/plant2.blend
deleted file mode 100644
index 6592c5d98d..0000000000
Binary files a/packages/client/assets/room/furnitures/plant2/plant2.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant2/plant2.glb b/packages/client/assets/room/furnitures/plant2/plant2.glb
deleted file mode 100644
index 223e6f5834..0000000000
Binary files a/packages/client/assets/room/furnitures/plant2/plant2.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/plant2/soil.png b/packages/client/assets/room/furnitures/plant2/soil.png
deleted file mode 100644
index e79ccd240e..0000000000
Binary files a/packages/client/assets/room/furnitures/plant2/soil.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/poster-h/poster-h.blend b/packages/client/assets/room/furnitures/poster-h/poster-h.blend
deleted file mode 100644
index 40f944f3c1..0000000000
Binary files a/packages/client/assets/room/furnitures/poster-h/poster-h.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/poster-h/poster-h.glb b/packages/client/assets/room/furnitures/poster-h/poster-h.glb
deleted file mode 100644
index c6032c1009..0000000000
Binary files a/packages/client/assets/room/furnitures/poster-h/poster-h.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/poster-h/uv.png b/packages/client/assets/room/furnitures/poster-h/uv.png
deleted file mode 100644
index f854231e0b..0000000000
Binary files a/packages/client/assets/room/furnitures/poster-h/uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/poster-v/poster-v.blend b/packages/client/assets/room/furnitures/poster-v/poster-v.blend
deleted file mode 100644
index 07fe971634..0000000000
Binary files a/packages/client/assets/room/furnitures/poster-v/poster-v.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/poster-v/poster-v.glb b/packages/client/assets/room/furnitures/poster-v/poster-v.glb
deleted file mode 100644
index 6e3782f193..0000000000
Binary files a/packages/client/assets/room/furnitures/poster-v/poster-v.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/poster-v/uv.png b/packages/client/assets/room/furnitures/poster-v/uv.png
deleted file mode 100644
index 7bb2bf809e..0000000000
Binary files a/packages/client/assets/room/furnitures/poster-v/uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pudding/pudding.blend b/packages/client/assets/room/furnitures/pudding/pudding.blend
deleted file mode 100644
index bba40ce161..0000000000
Binary files a/packages/client/assets/room/furnitures/pudding/pudding.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/pudding/pudding.glb b/packages/client/assets/room/furnitures/pudding/pudding.glb
deleted file mode 100644
index 06c9ed80cc..0000000000
Binary files a/packages/client/assets/room/furnitures/pudding/pudding.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.blend b/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.blend
deleted file mode 100644
index 6c09067e78..0000000000
Binary files a/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.glb b/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.glb
deleted file mode 100644
index d640df9b06..0000000000
Binary files a/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/server/rack-uv.png b/packages/client/assets/room/furnitures/server/rack-uv.png
deleted file mode 100644
index 65bdb0ffd9..0000000000
Binary files a/packages/client/assets/room/furnitures/server/rack-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/server/rack.png b/packages/client/assets/room/furnitures/server/rack.png
deleted file mode 100644
index b851295cfa..0000000000
Binary files a/packages/client/assets/room/furnitures/server/rack.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/server/server.blend b/packages/client/assets/room/furnitures/server/server.blend
deleted file mode 100644
index 6675dfbdc2..0000000000
Binary files a/packages/client/assets/room/furnitures/server/server.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/server/server.glb b/packages/client/assets/room/furnitures/server/server.glb
deleted file mode 100644
index a8b530a2d2..0000000000
Binary files a/packages/client/assets/room/furnitures/server/server.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/server/server.png b/packages/client/assets/room/furnitures/server/server.png
deleted file mode 100644
index 8e9a0d716c..0000000000
Binary files a/packages/client/assets/room/furnitures/server/server.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/server/uv.png b/packages/client/assets/room/furnitures/server/uv.png
deleted file mode 100644
index ca2e747d16..0000000000
Binary files a/packages/client/assets/room/furnitures/server/uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/sofa/sofa.blend b/packages/client/assets/room/furnitures/sofa/sofa.blend
deleted file mode 100644
index fb5aa51a2c..0000000000
Binary files a/packages/client/assets/room/furnitures/sofa/sofa.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/sofa/sofa.glb b/packages/client/assets/room/furnitures/sofa/sofa.glb
deleted file mode 100644
index 6ce77d94ac..0000000000
Binary files a/packages/client/assets/room/furnitures/sofa/sofa.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/spiral/spiral.blend b/packages/client/assets/room/furnitures/spiral/spiral.blend
deleted file mode 100644
index 9d3be77bce..0000000000
Binary files a/packages/client/assets/room/furnitures/spiral/spiral.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/spiral/spiral.glb b/packages/client/assets/room/furnitures/spiral/spiral.glb
deleted file mode 100644
index ee8e3c23b1..0000000000
Binary files a/packages/client/assets/room/furnitures/spiral/spiral.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/tv/screen-uv.png b/packages/client/assets/room/furnitures/tv/screen-uv.png
deleted file mode 100644
index 4bb74f031f..0000000000
Binary files a/packages/client/assets/room/furnitures/tv/screen-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/tv/tv.blend b/packages/client/assets/room/furnitures/tv/tv.blend
deleted file mode 100644
index 490e298e7b..0000000000
Binary files a/packages/client/assets/room/furnitures/tv/tv.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/tv/tv.glb b/packages/client/assets/room/furnitures/tv/tv.glb
deleted file mode 100644
index b9bd23896b..0000000000
Binary files a/packages/client/assets/room/furnitures/tv/tv.glb and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/wall-clock/wall-clock.blend b/packages/client/assets/room/furnitures/wall-clock/wall-clock.blend
deleted file mode 100644
index 0a61c8f01e..0000000000
Binary files a/packages/client/assets/room/furnitures/wall-clock/wall-clock.blend and /dev/null differ
diff --git a/packages/client/assets/room/furnitures/wall-clock/wall-clock.glb b/packages/client/assets/room/furnitures/wall-clock/wall-clock.glb
deleted file mode 100644
index b9f0093a8d..0000000000
Binary files a/packages/client/assets/room/furnitures/wall-clock/wall-clock.glb and /dev/null differ
diff --git a/packages/client/assets/room/rooms/default/default.blend b/packages/client/assets/room/rooms/default/default.blend
deleted file mode 100644
index 661154724a..0000000000
Binary files a/packages/client/assets/room/rooms/default/default.blend and /dev/null differ
diff --git a/packages/client/assets/room/rooms/default/default.glb b/packages/client/assets/room/rooms/default/default.glb
deleted file mode 100644
index 3d378deee2..0000000000
Binary files a/packages/client/assets/room/rooms/default/default.glb and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/husuma-uv.png b/packages/client/assets/room/rooms/washitsu/husuma-uv.png
deleted file mode 100644
index ae2fca3911..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/husuma-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/husuma.png b/packages/client/assets/room/rooms/washitsu/husuma.png
deleted file mode 100644
index 084cbed67c..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/husuma.png and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/tatami-single1600.png b/packages/client/assets/room/rooms/washitsu/tatami-single1600.png
deleted file mode 100644
index c0e684d743..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/tatami-single1600.png and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/tatami-uv.png b/packages/client/assets/room/rooms/washitsu/tatami-uv.png
deleted file mode 100644
index 5b16c66091..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/tatami-uv.png and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/tatami.afdesign b/packages/client/assets/room/rooms/washitsu/tatami.afdesign
deleted file mode 100644
index 9300a26950..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/tatami.afdesign and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/tatami.png b/packages/client/assets/room/rooms/washitsu/tatami.png
deleted file mode 100644
index 8894d040ae..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/tatami.png and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/washitsu.blend b/packages/client/assets/room/rooms/washitsu/washitsu.blend
deleted file mode 100644
index 84dc11374d..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/washitsu.blend and /dev/null differ
diff --git a/packages/client/assets/room/rooms/washitsu/washitsu.glb b/packages/client/assets/room/rooms/washitsu/washitsu.glb
deleted file mode 100644
index 5b4767bc73..0000000000
Binary files a/packages/client/assets/room/rooms/washitsu/washitsu.glb and /dev/null differ
diff --git a/packages/client/src/components/avatars.vue b/packages/client/src/components/avatars.vue
index e843d26daa..958e5db0a1 100644
--- a/packages/client/src/components/avatars.vue
+++ b/packages/client/src/components/avatars.vue
@@ -1,30 +1,24 @@
 <template>
 <div>
-	<div v-for="user in us" :key="user.id" style="display:inline-block;width:32px;height:32px;margin-right:8px;">
+	<div v-for="user in users" :key="user.id" style="display:inline-block;width:32px;height:32px;margin-right:8px;">
 		<MkAvatar :user="user" style="width:32px;height:32px;" :show-indicator="true"/>
 	</div>
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { onMounted, ref } from 'vue';
 import * as os from '@/os';
 
-export default defineComponent({
-	props: {
-		userIds: {
-			required: true
-		},
-	},
-	data() {
-		return {
-			us: []
-		};
-	},
-	async created() {
-		this.us = await os.api('users/show', {
-			userIds: this.userIds
-		});
-	}
+const props = defineProps<{
+	userIds: string[];
+}>();
+
+const users = ref([]);
+
+onMounted(async () => {
+	users.value = await os.api('users/show', {
+		userIds: props.userIds
+	});
 });
 </script>
diff --git a/packages/client/src/components/cw-button.vue b/packages/client/src/components/cw-button.vue
index 4bec7b511e..b0a9860de2 100644
--- a/packages/client/src/components/cw-button.vue
+++ b/packages/client/src/components/cw-button.vue
@@ -5,41 +5,33 @@
 </button>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { computed } from 'vue';
 import { length } from 'stringz';
+import * as misskey from 'misskey-js';
 import { concat } from '@/scripts/array';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	props: {
-		modelValue: {
-			type: Boolean,
-			required: true
-		},
-		note: {
-			type: Object,
-			required: true
-		}
-	},
+const props = defineProps<{
+	modelValue: boolean;
+	note: misskey.entities.Note;
+}>();
 
-	computed: {
-		label(): string {
-			return concat([
-				this.note.text ? [this.$t('_cw.chars', { count: length(this.note.text) })] : [],
-				this.note.files && this.note.files.length !== 0 ? [this.$t('_cw.files', { count: this.note.files.length }) ] : [],
-				this.note.poll != null ? [this.$ts.poll] : []
-			] as string[][]).join(' / ');
-		}
-	},
+const emit = defineEmits<{
+	(e: 'update:modelValue', v: boolean): void;
+}>();
 
-	methods: {
-		length,
-
-		toggle() {
-			this.$emit('update:modelValue', !this.modelValue);
-		}
-	}
+const label = computed(() => {
+	return concat([
+		props.note.text ? [i18n.t('_cw.chars', { count: length(props.note.text) })] : [],
+		props.note.files && props.note.files.length !== 0 ? [i18n.t('_cw.files', { count: props.note.files.length }) ] : [],
+		props.note.poll != null ? [i18n.locale.poll] : []
+	] as string[][]).join(' / ');
 });
+
+const toggle = () => {
+	emit('update:modelValue', !props.modelValue);
+};
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/file-type-icon.vue b/packages/client/src/components/file-type-icon.vue
index be1af5e501..11d28188cc 100644
--- a/packages/client/src/components/file-type-icon.vue
+++ b/packages/client/src/components/file-type-icon.vue
@@ -4,25 +4,12 @@
 </span>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
+<script lang="ts" setup>
+import { computed } from 'vue';
 
-export default defineComponent({
-	props: {
-		type: {
-			type: String,
-			required: true,
-		}
-	},
-	data() {
-		return {
-		};
-	},
-	computed: {
-		kind(): string {
-			return this.type.split('/')[0];
-		}
-	}
-});
+const props = defineProps<{
+	type: string;
+}>();
+
+const kind = computed(() => props.type.split('/')[0]);
 </script>
diff --git a/packages/client/src/components/global/acct.vue b/packages/client/src/components/global/acct.vue
index 018826153c..c3e806b5fb 100644
--- a/packages/client/src/components/global/acct.vue
+++ b/packages/client/src/components/global/acct.vue
@@ -5,28 +5,17 @@
 </span>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import * as misskey from 'misskey-js';
 import { toUnicode } from 'punycode/';
-import { host } from '@/config';
+import { host as hostRaw } from '@/config';
 
-export default defineComponent({
-	props: {
-		user: {
-			type: Object,
-			required: true
-		},
-		detail: {
-			type: Boolean,
-			default: false
-		},
-	},
-	data() {
-		return {
-			host: toUnicode(host),
-		};
-	}
-});
+defineProps<{
+	user: misskey.entities.UserDetailed;
+	detail?: boolean;
+}>();
+
+const host = toUnicode(hostRaw);
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/global/error.vue b/packages/client/src/components/global/error.vue
index d759186167..98b96fb414 100644
--- a/packages/client/src/components/global/error.vue
+++ b/packages/client/src/components/global/error.vue
@@ -8,19 +8,8 @@
 </transition>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
 import MkButton from '@/components/ui/button.vue';
-
-export default defineComponent({
-	components: {
-		MkButton,
-	},
-	data() {
-		return {
-		};
-	},
-});
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/google.vue b/packages/client/src/components/google.vue
index a39168b80f..210ca72bfe 100644
--- a/packages/client/src/components/google.vue
+++ b/packages/client/src/components/google.vue
@@ -5,31 +5,18 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
+<script lang="ts" setup>
+import { ref } from 'vue';
 
-export default defineComponent({
-	props: {
-		q: {
-			type: String,
-			required: true,
-		}
-	},
-	data() {
-		return {
-			query: null,
-		};
-	},
-	mounted() {
-		this.query = this.q;
-	},
-	methods: {
-		search() {
-			window.open(`https://www.google.com/search?q=${this.query}`, '_blank');
-		}
-	}
-});
+const props = defineProps<{
+	q: string;
+}>();
+
+const query = ref(props.q);
+
+const search = () => {
+	window.open(`https://www.google.com/search?q=${query.value}`, '_blank');
+};
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/media-video.vue b/packages/client/src/components/media-video.vue
index a0dc57b657..680eb27e64 100644
--- a/packages/client/src/components/media-video.vue
+++ b/packages/client/src/components/media-video.vue
@@ -22,26 +22,16 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
+<script lang="ts" setup>
+import { ref } from 'vue';
+import * as misskey from 'misskey-js';
+import { defaultStore } from '@/store';
 
-export default defineComponent({
-	props: {
-		video: {
-			type: Object,
-			required: true
-		}
-	},
-	data() {
-		return {
-			hide: true,
-		};
-	},
-	created() {
-		this.hide = (this.$store.state.nsfw === 'force') ? true : this.video.isSensitive && (this.$store.state.nsfw !== 'ignore');
-	},
-});
+const props = defineProps<{
+	video: misskey.entities.DriveFile;
+}>();
+
+const hide = ref((defaultStore.state.nsfw === 'force') ? true : props.video.isSensitive && (defaultStore.state.nsfw !== 'ignore'));
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/remote-caution.vue b/packages/client/src/components/remote-caution.vue
index c496ea8f48..aa623f0fb0 100644
--- a/packages/client/src/components/remote-caution.vue
+++ b/packages/client/src/components/remote-caution.vue
@@ -2,22 +2,10 @@
 <div class="jmgmzlwq _block"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i>{{ $ts.remoteUserCaution }}<a :href="href" rel="nofollow noopener" target="_blank">{{ $ts.showOnRemote }}</a></div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
-
-export default defineComponent({
-	props: {
-		href: {
-			type: String,
-			required: true
-		},
-	},
-	data() {
-		return {
-		};
-	}
-});
+<script lang="ts" setup>
+defineProps<{
+	href: string;
+}>();
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/components/taskmanager.api-window.vue b/packages/client/src/components/taskmanager.api-window.vue
deleted file mode 100644
index 6ec4da3a59..0000000000
--- a/packages/client/src/components/taskmanager.api-window.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-<template>
-<XWindow ref="window"
-	:initial-width="370"
-	:initial-height="450"
-	:can-resize="true"
-	@close="$refs.window.close()"
-	@closed="$emit('closed')"
->
-	<template #header>Req Viewer</template>
-
-	<div class="rlkneywz">
-		<MkTab v-model="tab" style="border-bottom: solid 0.5px var(--divider);">
-			<option value="req">Request</option>
-			<option value="res">Response</option>
-		</MkTab>
-
-		<code v-if="tab === 'req'" class="_monospace">{{ reqStr }}</code>
-		<code v-if="tab === 'res'" class="_monospace">{{ resStr }}</code>
-	</div>
-</XWindow>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as JSON5 from 'json5';
-import XWindow from '@/components/ui/window.vue';
-import MkTab from '@/components/tab.vue';
-
-export default defineComponent({
-	components: {
-		XWindow,
-		MkTab,
-	},
-
-	props: {
-		req: {
-			required: true,
-		}
-	},
-
-	emits: ['closed'],
-
-	data() {
-		return {
-			tab: 'req',
-			reqStr: JSON5.stringify(this.req.req, null, '\t'),
-			resStr: JSON5.stringify(this.req.res, null, '\t'),
-		}
-	},
-
-	methods: {
-	}
-});
-</script>
-
-<style lang="scss" scoped>
-.rlkneywz {
-	display: flex;
-	flex-direction: column;
-	height: 100%;
-
-	> code {
-		display: block;
-		flex: 1;
-		padding: 8px;
-		overflow: auto;
-		font-size: 0.9em;
-		tab-size: 2;
-		white-space: pre;
-	}
-}
-</style>
diff --git a/packages/client/src/components/taskmanager.vue b/packages/client/src/components/taskmanager.vue
deleted file mode 100644
index c5d2c6d8f8..0000000000
--- a/packages/client/src/components/taskmanager.vue
+++ /dev/null
@@ -1,234 +0,0 @@
-<template>
-<XWindow ref="window" :initial-width="650" :initial-height="420" :can-resize="true" @closed="$emit('closed')">
-	<template #header>
-		<i class="fas fa-terminal" style="margin-right: 0.5em;"></i>Task Manager
-	</template>
-	<div class="qljqmnzj _monospace">
-		<MkTab v-model="tab" style="border-bottom: solid 0.5px var(--divider);">
-			<option value="windows">Windows</option>
-			<option value="stream">Stream</option>
-			<option value="streamPool">Stream (Pool)</option>
-			<option value="api">API</option>
-		</MkTab>
-
-		<div class="content">
-			<div v-if="tab === 'windows'" v-follow class="windows">
-				<div class="header">
-					<div>#ID</div>
-					<div>Component</div>
-					<div>Action</div>
-				</div>
-				<div v-for="p in popups">
-					<div>#{{ p.id }}</div>
-					<div>{{ p.component.name ? p.component.name : '<anonymous>' }}</div>
-					<div><button class="_textButton" @click="killPopup(p)">Kill</button></div>
-				</div>
-			</div>
-			<div v-if="tab === 'stream'" v-follow class="stream">
-				<div class="header">
-					<div>#ID</div>
-					<div>Ch</div>
-					<div>Handle</div>
-					<div>In</div>
-					<div>Out</div>
-				</div>
-				<div v-for="c in connections">
-					<div>#{{ c.id }}</div>
-					<div>{{ c.channel }}</div>
-					<div v-if="c.users !== null">(shared)<span v-if="c.name">{{ ' ' + c.name }}</span></div>
-					<div v-else>{{ c.name ? c.name : '<anonymous>' }}</div>
-					<div>{{ c.in }}</div>
-					<div>{{ c.out }}</div>
-				</div>
-			</div>
-			<div v-if="tab === 'streamPool'" v-follow class="streamPool">
-				<div class="header">
-					<div>#ID</div>
-					<div>Ch</div>
-					<div>Users</div>
-				</div>
-				<div v-for="p in pools">
-					<div>#{{ p.id }}</div>
-					<div>{{ p.channel }}</div>
-					<div>{{ p.users }}</div>
-				</div>
-			</div>
-			<div v-if="tab === 'api'" v-follow class="api">
-				<div class="header">
-					<div>#ID</div>
-					<div>Endpoint</div>
-					<div>State</div>
-				</div>
-				<div v-for="req in apiRequests" @click="showReq(req)">
-					<div>#{{ req.id }}</div>
-					<div>{{ req.endpoint }}</div>
-					<div class="state" :class="req.state">{{ req.state }}</div>
-				</div>
-			</div>
-		</div>
-
-		<footer>
-			<div><span class="label">Windows</span>{{ popups.length }}</div>
-			<div><span class="label">Stream</span>{{ connections.length }}</div>
-			<div><span class="label">Stream (Pool)</span>{{ pools.length }}</div>
-		</footer>
-	</div>
-</XWindow>
-</template>
-
-<script lang="ts">
-import { defineComponent, markRaw, onBeforeUnmount, ref, shallowRef } from 'vue';
-import XWindow from '@/components/ui/window.vue';
-import MkTab from '@/components/tab.vue';
-import MkButton from '@/components/ui/button.vue';
-import follow from '@/directives/follow-append';
-import * as os from '@/os';
-import { stream } from '@/stream';
-
-export default defineComponent({
-	components: {
-		XWindow,
-		MkTab,
-		MkButton,
-	},
-
-	directives: {
-		follow
-	},
-
-	props: {
-	},
-
-	emits: ['closed'],
-
-	setup() {
-		const connections = shallowRef([]);
-		const pools = shallowRef([]);
-		const refreshStreamInfo = () => {
-			console.log(stream.sharedConnectionPools, stream.sharedConnections, stream.nonSharedConnections);
-			const conn = stream.sharedConnections.map(c => ({
-				id: c.id, name: c.name, channel: c.channel, users: c.pool.users, in: c.inCount, out: c.outCount,
-			})).concat(stream.nonSharedConnections.map(c => ({
-				id: c.id, name: c.name, channel: c.channel, users: null, in: c.inCount, out: c.outCount,
-			})));
-			conn.sort((a, b) => (a.id > b.id) ? 1 : -1);
-			connections.value = conn;
-			pools.value = stream.sharedConnectionPools;
-		};
-		const interval = setInterval(refreshStreamInfo, 1000);
-		onBeforeUnmount(() => {
-			clearInterval(interval);
-		});
-
-		const killPopup = p => {
-			os.popups.value = os.popups.value.filter(x => x !== p);
-		};
-
-		const showReq = req => {
-			os.popup(import('./taskmanager.api-window.vue'), {
-				req: req
-			}, {
-			}, 'closed');
-		};
-
-		return {
-			tab: ref('stream'),
-			popups: os.popups,
-			apiRequests: os.apiRequests,
-			connections,
-			pools,
-			killPopup,
-			showReq,
-		};
-	},
-});
-</script>
-
-<style lang="scss" scoped>
-.qljqmnzj {
-	display: flex;
-	flex-direction: column;
-	height: 100%;
-
-	> .content {
-		flex: 1;
-		overflow: auto;
-
-		> div {
-			display: table;
-			width: 100%;
-			padding: 16px;
-			box-sizing: border-box;
-
-			> div {
-				display: table-row;
-
-				&:nth-child(even) {
-					//background: rgba(0, 0, 0, 0.1);
-				}
-
-				&.header {
-					opacity: 0.7;
-				}
-
-				> div {
-					display: table-cell;
-					white-space: nowrap;
-
-					&:not(:last-child) {
-						padding-right: 8px;
-					}
-				}
-			}
-
-			&.api {
-				> div {
-					&:not(.header) {
-						cursor: pointer;
-
-						&:hover {
-							color: var(--accent);
-						}
-					}
-
-					> .state {
-						&.pending {
-							color: var(--warn);
-						}
-
-						&.success {
-							color: var(--success);
-						}
-
-						&.failed {
-							color: var(--error);
-						}
-					}
-				}
-			}
-		}
-	}
-
-	> footer {
-		display: flex;
-		width: 100%;
-		padding: 8px 16px;
-		box-sizing: border-box;
-		border-top: solid 0.5px var(--divider);
-		font-size: 0.9em;
-
-		> div {
-			flex: 1;
-
-			> .label {
-				opacity: 0.7;
-				margin-right: 0.5em;
-
-				&:after {
-					content: ":";
-				}
-			}
-		}
-	}
-}
-</style>
diff --git a/packages/client/src/components/toast.vue b/packages/client/src/components/toast.vue
index 914704c527..869182d8e1 100644
--- a/packages/client/src/components/toast.vue
+++ b/packages/client/src/components/toast.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="mk-toast">
-	<transition name="toast" appear @after-leave="$emit('closed')">
+	<transition name="toast" appear @after-leave="emit('closed')">
 		<div v-if="showing" class="body _acrylic" :style="{ zIndex }">
 			<div class="message">
 				{{ message }}
@@ -10,29 +10,25 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { onMounted, ref } from 'vue';
 import * as os from '@/os';
 
-export default defineComponent({
-	props: {
-		message: {
-			type: String,
-			required: true,
-		},
-	},
-	emits: ['closed'],
-	data() {
-		return {
-			showing: true,
-			zIndex: os.claimZIndex('high'),
-		};
-	},
-	mounted() {
-		setTimeout(() => {
-			this.showing = false;
-		}, 4000);
-	}
+defineProps<{
+	message: string;
+}>();
+
+const emit = defineEmits<{
+	(e: 'closed'): void;
+}>();
+
+const showing = ref(true);
+const zIndex = os.claimZIndex('high');
+
+onMounted(() => {
+	setTimeout(() => {
+		showing.value = false;
+	}, 4000);
 });
 </script>
 
diff --git a/packages/client/src/components/url-preview.vue b/packages/client/src/components/url-preview.vue
index fe88985a62..dff74800ed 100644
--- a/packages/client/src/components/url-preview.vue
+++ b/packages/client/src/components/url-preview.vue
@@ -76,7 +76,7 @@ export default defineComponent({
 			tweetExpanded: this.detail,
 			embedId: `embed${Math.random().toString().replace(/\D/,'')}`,
 			tweetHeight: 150,
- 			tweetLeft: 0,
+			tweetLeft: 0,
 			playerEnabled: false,
 			self: self,
 			attr: self ? 'to' : 'href',
diff --git a/packages/client/src/components/user-info.vue b/packages/client/src/components/user-info.vue
index 779a71358d..6a25d412fc 100644
--- a/packages/client/src/components/user-info.vue
+++ b/packages/client/src/components/user-info.vue
@@ -27,32 +27,14 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import * as misskey from 'misskey-js';
 import MkFollowButton from './follow-button.vue';
 import { userPage } from '@/filters/user';
 
-export default defineComponent({
-	components: {
-		MkFollowButton
-	},
-
-	props: {
-		user: {
-			type: Object,
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	methods: {
-		userPage,
-	}
-});
+defineProps<{
+	user: misskey.entities.UserDetailed;
+}>();
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/menu.ts b/packages/client/src/menu.ts
index bd155ba16d..ea6f801fec 100644
--- a/packages/client/src/menu.ts
+++ b/packages/client/src/menu.ts
@@ -173,12 +173,6 @@ export const menuDef = reactive({
 		icon: 'fas fa-terminal',
 		to: '/scratchpad',
 	},
-	rooms: {
-		title: 'rooms',
-		icon: 'fas fa-door-closed',
-		show: computed(() => $i != null),
-		to: computed(() => `/@${$i.username}/room`),
-	},
 	ui: {
 		title: 'switchUi',
 		icon: 'fas fa-columns',
diff --git a/packages/client/src/os.ts b/packages/client/src/os.ts
index d9400103f5..e6dd4567f7 100644
--- a/packages/client/src/os.ts
+++ b/packages/client/src/os.ts
@@ -4,16 +4,13 @@ import { Component, defineAsyncComponent, markRaw, reactive, Ref, ref } from 'vu
 import { EventEmitter } from 'eventemitter3';
 import insertTextAtCursor from 'insert-text-at-cursor';
 import * as Misskey from 'misskey-js';
-import { apiUrl, debug, url } from '@/config';
+import { apiUrl, url } from '@/config';
 import MkPostFormDialog from '@/components/post-form-dialog.vue';
 import MkWaitingDialog from '@/components/waiting-dialog.vue';
 import { resolve } from '@/router';
 import { $i } from '@/account';
-import { defaultStore } from '@/store';
 
 export const pendingApiRequestsCount = ref(0);
-let apiRequestsCount = 0; // for debug
-export const apiRequests = ref([]); // for debug
 
 const apiClient = new Misskey.api.APIClient({
 	origin: url,
@@ -26,18 +23,6 @@ export const api = ((endpoint: string, data: Record<string, any> = {}, token?: s
 		pendingApiRequestsCount.value--;
 	};
 
-	const log = debug ? reactive({
-		id: ++apiRequestsCount,
-		endpoint,
-		req: markRaw(data),
-		res: null,
-		state: 'pending',
-	}) : null;
-	if (debug) {
-		apiRequests.value.push(log);
-		if (apiRequests.value.length > 128) apiRequests.value.shift();
-	}
-
 	const promise = new Promise((resolve, reject) => {
 		// Append a credential
 		if ($i) (data as any).i = $i.token;
@@ -54,21 +39,10 @@ export const api = ((endpoint: string, data: Record<string, any> = {}, token?: s
 
 			if (res.status === 200) {
 				resolve(body);
-				if (debug) {
-					log!.res = markRaw(JSON.parse(JSON.stringify(body)));
-					log!.state = 'success';
-				}
 			} else if (res.status === 204) {
 				resolve();
-				if (debug) {
-					log!.state = 'success';
-				}
 			} else {
 				reject(body.error);
-				if (debug) {
-					log!.res = markRaw(body.error);
-					log!.state = 'failed';
-				}
 			}
 		}).catch(reject);
 	});
diff --git a/packages/client/src/pages/_loading_.vue b/packages/client/src/pages/_loading_.vue
index 05c6af1cd7..1dd2e46e10 100644
--- a/packages/client/src/pages/_loading_.vue
+++ b/packages/client/src/pages/_loading_.vue
@@ -2,9 +2,5 @@
 <MkLoading/>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
-
-export default defineComponent({});
+<script lang="ts" setup>
 </script>
diff --git a/packages/client/src/pages/about.vue b/packages/client/src/pages/about.vue
index e9d17feec1..a5984c548d 100644
--- a/packages/client/src/pages/about.vue
+++ b/packages/client/src/pages/about.vue
@@ -67,8 +67,8 @@
 </MkSpacer>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { ref } from 'vue';
 import { version, instanceName } from '@/config';
 import FormLink from '@/components/form/link.vue';
 import FormSection from '@/components/form/section.vue';
@@ -79,37 +79,21 @@ import * as os from '@/os';
 import number from '@/filters/number';
 import * as symbols from '@/symbols';
 import { host } from '@/config';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	components: {
-		MkKeyValue,
-		FormSection,
-		FormLink,
-		FormSuspense,
-		FormSplit,
+const stats = ref(null);
+
+const initStats = () => os.api('stats', {
+}).then((res) => {
+	stats.value = res;
+});
+
+defineExpose({
+	[symbols.PAGE_INFO]: {
+		title: i18n.locale.instanceInfo,
+		icon: 'fas fa-info-circle',
+		bg: 'var(--bg)',
 	},
-
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.instanceInfo,
-				icon: 'fas fa-info-circle',
-				bg: 'var(--bg)',
-			},
-			host,
-			version,
-			instanceName,
-			stats: null,
-			initStats: () => os.api('stats', {
-			}).then((stats) => {
-				this.stats = stats;
-			})
-		}
-	},
-
-	methods: {
-		number
-	}
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/index.vue b/packages/client/src/pages/admin/index.vue
index a628ce87ae..b7160de11d 100644
--- a/packages/client/src/pages/admin/index.vue
+++ b/packages/client/src/pages/admin/index.vue
@@ -171,11 +171,6 @@ export default defineComponent({
 				text: i18n.locale.security,
 				to: '/admin/security',
 				active: page.value === 'security',
-			}, {
-				icon: 'fas fa-bolt',
-				text: 'ServiceWorker',
-				to: '/admin/service-worker',
-				active: page.value === 'service-worker',
 			}, {
 				icon: 'fas fa-globe',
 				text: i18n.locale.relays,
@@ -228,7 +223,6 @@ export default defineComponent({
 				case 'email-settings': return defineAsyncComponent(() => import('./email-settings.vue'));
 				case 'object-storage': return defineAsyncComponent(() => import('./object-storage.vue'));
 				case 'security': return defineAsyncComponent(() => import('./security.vue'));
-				case 'service-worker': return defineAsyncComponent(() => import('./service-worker.vue'));
 				case 'relays': return defineAsyncComponent(() => import('./relays.vue'));
 				case 'integrations': return defineAsyncComponent(() => import('./integrations.vue'));
 				case 'instance-block': return defineAsyncComponent(() => import('./instance-block.vue'));
diff --git a/packages/client/src/pages/admin/other-settings.vue b/packages/client/src/pages/admin/other-settings.vue
index eb47a3fa1f..d21d0c5992 100644
--- a/packages/client/src/pages/admin/other-settings.vue
+++ b/packages/client/src/pages/admin/other-settings.vue
@@ -1,21 +1,7 @@
 <template>
 <MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
 	<FormSuspense :p="init">
-		<FormSection>
-			<FormInput v-model="summalyProxy" class="_formBlock">
-				<template #prefix><i class="fas fa-link"></i></template>
-				<template #label>Summaly Proxy URL</template>
-			</FormInput>
-		</FormSection>
-		<FormSection>
-			<FormInput v-model="deeplAuthKey" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
-				<template #label>DeepL Auth Key</template>
-			</FormInput>
-			<FormSwitch v-model="deeplIsPro" class="_formBlock">
-				<template #label>Pro account</template>
-			</FormSwitch>
-		</FormSection>
+		none
 	</FormSuspense>
 </MkSpacer>
 </template>
@@ -53,9 +39,6 @@ export default defineComponent({
 					handler: this.save,
 				}],
 			},
-			summalyProxy: '',
-			deeplAuthKey: '',
-			deeplIsPro: false,
 		}
 	},
 
@@ -66,15 +49,9 @@ export default defineComponent({
 	methods: {
 		async init() {
 			const meta = await os.api('meta', { detail: true });
-			this.summalyProxy = meta.summalyProxy;
-			this.deeplAuthKey = meta.deeplAuthKey;
-			this.deeplIsPro = meta.deeplIsPro;
 		},
 		save() {
 			os.apiWithDialog('admin/update-meta', {
-				summalyProxy: this.summalyProxy,
-				deeplAuthKey: this.deeplAuthKey,
-				deeplIsPro: this.deeplIsPro,
 			}).then(() => {
 				fetchInstance();
 			});
diff --git a/packages/client/src/pages/admin/security.vue b/packages/client/src/pages/admin/security.vue
index d6ca9e0cba..276c514f16 100644
--- a/packages/client/src/pages/admin/security.vue
+++ b/packages/client/src/pages/admin/security.vue
@@ -11,6 +11,19 @@
 
 				<XBotProtection/>
 			</FormFolder>
+
+			<FormFolder class="_formBlock">
+				<template #label>Summaly Proxy</template>
+
+				<div class="_formRoot">
+					<FormInput v-model="summalyProxy" class="_formBlock">
+						<template #prefix><i class="fas fa-link"></i></template>
+						<template #label>Summaly Proxy URL</template>
+					</FormInput>
+
+					<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+				</div>
+			</FormFolder>
 		</div>
 	</FormSuspense>
 </MkSpacer>
@@ -23,6 +36,8 @@ import FormSwitch from '@/components/form/switch.vue';
 import FormInfo from '@/components/ui/info.vue';
 import FormSuspense from '@/components/form/suspense.vue';
 import FormSection from '@/components/form/section.vue';
+import FormInput from '@/components/form/input.vue';
+import FormButton from '@/components/ui/button.vue';
 import XBotProtection from './bot-protection.vue';
 import * as os from '@/os';
 import * as symbols from '@/symbols';
@@ -35,6 +50,8 @@ export default defineComponent({
 		FormInfo,
 		FormSection,
 		FormSuspense,
+		FormButton,
+		FormInput,
 		XBotProtection,
 	},
 
@@ -47,6 +64,7 @@ export default defineComponent({
 				icon: 'fas fa-lock',
 				bg: 'var(--bg)',
 			},
+			summalyProxy: '',
 			enableHcaptcha: false,
 			enableRecaptcha: false,
 		}
@@ -59,9 +77,18 @@ export default defineComponent({
 	methods: {
 		async init() {
 			const meta = await os.api('meta', { detail: true });
+			this.summalyProxy = meta.summalyProxy;
 			this.enableHcaptcha = meta.enableHcaptcha;
 			this.enableRecaptcha = meta.enableRecaptcha;
 		},
+
+		save() {
+			os.apiWithDialog('admin/update-meta', {
+				summalyProxy: this.summalyProxy,
+			}).then(() => {
+				fetchInstance();
+			});
+		}
 	}
 });
 </script>
diff --git a/packages/client/src/pages/admin/service-worker.vue b/packages/client/src/pages/admin/service-worker.vue
deleted file mode 100644
index eb4c2bb9a0..0000000000
--- a/packages/client/src/pages/admin/service-worker.vue
+++ /dev/null
@@ -1,81 +0,0 @@
-<template>
-<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
-	<FormSuspense :p="init">
-		<FormSwitch v-model="enableServiceWorker" class="_formBlock">
-			<template #label>{{ $ts.enableServiceworker }}</template>
-			<template #caption>{{ $ts.serviceworkerInfo }}</template>
-		</FormSwitch>
-
-		<template v-if="enableServiceWorker">
-			<FormInput v-model="swPublicKey" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
-				<template #label>Public key</template>
-			</FormInput>
-
-			<FormInput v-model="swPrivateKey" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
-				<template #label>Private key</template>
-			</FormInput>
-		</template>
-
-		<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
-	</FormSuspense>
-</MkSpacer>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-import FormSwitch from '@/components/form/switch.vue';
-import FormInput from '@/components/form/input.vue';
-import FormButton from '@/components/ui/button.vue';
-import FormSuspense from '@/components/form/suspense.vue';
-import * as os from '@/os';
-import * as symbols from '@/symbols';
-import { fetchInstance } from '@/instance';
-
-export default defineComponent({
-	components: {
-		FormSwitch,
-		FormInput,
-		FormButton,
-		FormSuspense,
-	},
-
-	emits: ['info'],
-
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: 'ServiceWorker',
-				icon: 'fas fa-bolt',
-				bg: 'var(--bg)',
-			},
-			enableServiceWorker: false,
-			swPublicKey: null,
-			swPrivateKey: null,
-		}
-	},
-
-	async mounted() {
-		this.$emit('info', this[symbols.PAGE_INFO]);
-	},
-
-	methods: {
-		async init() {
-			const meta = await os.api('meta', { detail: true });
-			this.enableServiceWorker = meta.enableServiceWorker;
-			this.swPublicKey = meta.swPublickey;
-			this.swPrivateKey = meta.swPrivateKey;
-		},
-		save() {
-			os.apiWithDialog('admin/update-meta', {
-				enableServiceWorker: this.enableServiceWorker,
-				swPublicKey: this.swPublicKey,
-				swPrivateKey: this.swPrivateKey,
-			}).then(() => {
-				fetchInstance();
-			});
-		}
-	}
-});
-</script>
diff --git a/packages/client/src/pages/admin/settings.vue b/packages/client/src/pages/admin/settings.vue
index e20ce40c75..802d7463ec 100644
--- a/packages/client/src/pages/admin/settings.vue
+++ b/packages/client/src/pages/admin/settings.vue
@@ -94,6 +94,39 @@
 					</FormInput>
 				</FormSplit>
 			</FormSection>
+
+			<FormSection>
+				<template #label>ServiceWorker</template>
+
+				<FormSwitch v-model="enableServiceWorker" class="_formBlock">
+					<template #label>{{ $ts.enableServiceworker }}</template>
+					<template #caption>{{ $ts.serviceworkerInfo }}</template>
+				</FormSwitch>
+
+				<template v-if="enableServiceWorker">
+					<FormInput v-model="swPublicKey" class="_formBlock">
+						<template #prefix><i class="fas fa-key"></i></template>
+						<template #label>Public key</template>
+					</FormInput>
+
+					<FormInput v-model="swPrivateKey" class="_formBlock">
+						<template #prefix><i class="fas fa-key"></i></template>
+						<template #label>Private key</template>
+					</FormInput>
+				</template>
+			</FormSection>
+
+			<FormSection>
+				<template #label>DeepL Translation</template>
+
+				<FormInput v-model="deeplAuthKey" class="_formBlock">
+					<template #prefix><i class="fas fa-key"></i></template>
+					<template #label>DeepL Auth Key</template>
+				</FormInput>
+				<FormSwitch v-model="deeplIsPro" class="_formBlock">
+					<template #label>Pro account</template>
+				</FormSwitch>
+			</FormSection>
 		</div>
 	</FormSuspense>
 </MkSpacer>
@@ -156,6 +189,11 @@ export default defineComponent({
 			remoteDriveCapacityMb: 0,
 			enableRegistration: false,
 			emailRequiredForSignup: false,
+			enableServiceWorker: false,
+			swPublicKey: null,
+			swPrivateKey: null,
+			deeplAuthKey: '',
+			deeplIsPro: false,
 		}
 	},
 
@@ -184,6 +222,11 @@ export default defineComponent({
 			this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
 			this.enableRegistration = !meta.disableRegistration;
 			this.emailRequiredForSignup = meta.emailRequiredForSignup;
+			this.enableServiceWorker = meta.enableServiceWorker;
+			this.swPublicKey = meta.swPublickey;
+			this.swPrivateKey = meta.swPrivateKey;
+			this.deeplAuthKey = meta.deeplAuthKey;
+			this.deeplIsPro = meta.deeplIsPro;
 		},
 
 		save() {
@@ -206,6 +249,11 @@ export default defineComponent({
 				remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10),
 				disableRegistration: !this.enableRegistration,
 				emailRequiredForSignup: this.emailRequiredForSignup,
+				enableServiceWorker: this.enableServiceWorker,
+				swPublicKey: this.swPublicKey,
+				swPrivateKey: this.swPrivateKey,
+				deeplAuthKey: this.deeplAuthKey,
+				deeplIsPro: this.deeplIsPro,
 			}).then(() => {
 				fetchInstance();
 			});
diff --git a/packages/client/src/pages/advanced-theme-editor.vue b/packages/client/src/pages/advanced-theme-editor.vue
deleted file mode 100644
index 9c2423131c..0000000000
--- a/packages/client/src/pages/advanced-theme-editor.vue
+++ /dev/null
@@ -1,349 +0,0 @@
-<template>
-<div class="t9makv94">
-	<section class="_section">
-		<div class="_content">
-			<details>
-				<summary>{{ $ts.import }}</summary>
-				<MkTextarea v-model="themeToImport">
-					{{ $ts._theme.importInfo }}
-				</MkTextarea>
-				<MkButton :disabled="!themeToImport.trim()" @click="importTheme">{{ $ts.import }}</MkButton>
-			</details>
-		</div>
-	</section>
-	<section class="_section">
-		<div class="_content _card _gap">
-			<div class="_content">
-				<MkInput v-model="name" required><span>{{ $ts.name }}</span></MkInput>
-				<MkInput v-model="author" required><span>{{ $ts.author }}</span></MkInput>
-				<MkTextarea v-model="description"><span>{{ $ts.description }}</span></MkTextarea>
-				<div class="_inputs">
-					<div v-text="$ts._theme.base" />
-					<MkRadio v-model="baseTheme" value="light">{{ $ts.light }}</MkRadio>
-					<MkRadio v-model="baseTheme" value="dark">{{ $ts.dark }}</MkRadio>
-				</div>
-			</div>
-		</div>
-		<div class="_content _card _gap">
-			<div class="list-view _content">
-				<div v-for="([ k, v ], i) in theme" :key="k" class="item">
-					<div class="_inputs">
-						<div>
-							{{ k.startsWith('$') ? `${k} (${$ts._theme.constant})` : $t('_theme.keys.' + k) }}
-							<button v-if="k.startsWith('$')" class="_button _link" @click="del(i)" v-text="$ts.delete" />
-						</div>
-						<div>
-							<div class="type" @click="chooseType($event, i)">
-								{{ getTypeOf(v) }} <i class="fas fa-chevron-down"></i>
-							</div>
-							<!-- default -->
-							<div v-if="v === null" class="default-value" v-text="baseProps[k]" />
-							<!-- color -->
-							<div v-else-if="typeof v === 'string'" class="color">
-								<input type="color" :value="v" @input="colorChanged($event.target.value, i)"/>
-								<MkInput class="select" :value="v" @update:modelValue="colorChanged($event, i)"/>
-							</div>
-							<!-- ref const -->
-							<MkInput v-else-if="v.type === 'refConst'" v-model="v.key">
-								<template #prefix>$</template>
-								<span>{{ $ts.name }}</span>
-							</MkInput>
-							<!-- ref props -->
-							<MkSelect v-else-if="v.type === 'refProp'" v-model="v.key" class="select">
-								<option v-for="key in themeProps" :key="key" :value="key">{{ $t('_theme.keys.' + key) }}</option>
-							</MkSelect>
-							<!-- func -->
-							<template v-else-if="v.type === 'func'">
-								<MkSelect v-model="v.name" class="select">
-									<template #label>{{ $ts._theme.funcKind }}</template>
-									<option v-for="n in ['alpha', 'darken', 'lighten']" :key="n" :value="n">{{ $t('_theme.' + n) }}</option>
-								</MkSelect>
-								<MkInput v-model="v.arg" type="number"><span>{{ $ts._theme.argument }}</span></MkInput>
-								<MkSelect v-model="v.value" class="select">
-									<template #label>{{ $ts._theme.basedProp }}</template>
-									<option v-for="key in themeProps" :key="key" :value="key">{{ $t('_theme.keys.' + key) }}</option>
-								</MkSelect>
-							</template>
-							<!-- CSS -->
-							<MkInput v-else-if="v.type === 'css'" v-model="v.value">
-								<span>CSS</span>
-							</MkInput>
-						</div>
-					</div>
-				</div>
-				<MkButton primary @click="addConst">{{ $ts._theme.addConstant }}</MkButton>
-			</div>
-		</div>
-	</section>
-	<section class="_section">
-		<details class="_content">
-			<summary>{{ $ts.sample }}</summary>
-			<MkSample/>
-		</details>
-	</section>
-	<section class="_section">
-		<div class="_content">
-			<MkButton inline @click="preview">{{ $ts.preview }}</MkButton>
-			<MkButton inline primary :disabled="!name || !author" @click="save">{{ $ts.save }}</MkButton>
-		</div>
-	</section>
-</div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as JSON5 from 'json5';
-import { toUnicode } from 'punycode/';
-
-import MkRadio from '@/components/form/radio.vue';
-import MkButton from '@/components/ui/button.vue';
-import MkInput from '@/components/form/input.vue';
-import MkTextarea from '@/components/form/textarea.vue';
-import MkSelect from '@/components/form/select.vue';
-import MkSample from '@/components/sample.vue';
-
-import { convertToMisskeyTheme, ThemeValue, convertToViewModel, ThemeViewModel } from '@/scripts/theme-editor';
-import { Theme, applyTheme, lightTheme, darkTheme, themeProps, validateTheme } from '@/scripts/theme';
-import { host } from '@/config';
-import * as os from '@/os';
-import { ColdDeviceStorage } from '@/store';
-import { addTheme } from '@/theme-store';
-import * as symbols from '@/symbols';
-
-export default defineComponent({
-	components: {
-		MkRadio,
-		MkButton,
-		MkInput,
-		MkTextarea,
-		MkSelect,
-		MkSample,
-	},
-
-	async beforeRouteLeave(to, from, next) {
-		if (this.changed && !(await this.confirm())) {
-			next(false);
-		} else {
-			next();
-		}
-	},
-
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.themeEditor,
-				icon: 'fas fa-palette',
-			},
-			theme: [] as ThemeViewModel,
-			name: '',
-			description: '',
-			baseTheme: 'light' as 'dark' | 'light',
-			author: `@${this.$i.username}@${toUnicode(host)}`,
-			themeToImport: '',
-			changed: false,
-			lightTheme, darkTheme, themeProps,
-		}
-	},
-
-	computed: {
-		baseProps() {
-			return this.baseTheme === 'light' ? this.lightTheme.props : this.darkTheme.props;
-		},
-	},
-
-	beforeUnmount() {
-		window.removeEventListener('beforeunload', this.beforeunload);
-	},
-
-	mounted() {
-		this.init();
-		window.addEventListener('beforeunload', this.beforeunload);
-		const changed = () => this.changed = true;
-		this.$watch('name', changed);
-		this.$watch('description', changed);
-		this.$watch('baseTheme', changed);
-		this.$watch('author', changed);
-		this.$watch('theme', changed);
-	},
-
-	methods: {
-		beforeunload(e: BeforeUnloadEvent) {
-			if (this.changed) {
-				e.preventDefault();
-				e.returnValue = '';
-			}
-		},
-
-		async confirm(): Promise<boolean> {
-			const { canceled } = await os.confirm({
-				type: 'warning',
-				text: this.$ts.leaveConfirm,
-			});
-			return !canceled;
-		},
-
-		init() {
-			const t: ThemeViewModel = [];
-			for (const key of themeProps) {
-				t.push([ key, null ]);
-			}
-			this.theme = t;
-		},
-	
-		async del(i: number) {
-			const { canceled } = await os.confirm({ 
-				type: 'warning',
-				text: this.$t('_theme.deleteConstantConfirm', { const: this.theme[i][0] }),
-			});
-			if (canceled) return;
-			Vue.delete(this.theme, i);
-		},
-	
-		async addConst() {
-			const { canceled, result } = await os.inputText({
-				title: this.$ts._theme.inputConstantName,
-			});
-			if (canceled) return;
-			this.theme.push([ '$' + result, '#000000']);
-		},
-	
-		save() {
-			const theme = convertToMisskeyTheme(this.theme, this.name, this.description, this.author, this.baseTheme);
-			addTheme(theme);
-			os.alert({
-				type: 'success',
-				text: this.$t('_theme.installed', { name: theme.name })
-			});
-			this.changed = false;
-		},
-	
-		preview() {
-			const theme = convertToMisskeyTheme(this.theme, this.name, this.description, this.author, this.baseTheme);
-			try {
-				applyTheme(theme, false);
-			} catch (e) {
-				os.alert({
-					type: 'error',
-					text: e.message
-				});
-			}
-		},
-	
-		async importTheme() {
-			if (this.changed && (!await this.confirm())) return;
-
-			try {
-				const theme = JSON5.parse(this.themeToImport) as Theme;
-				if (!validateTheme(theme)) throw new Error(this.$ts._theme.invalid);
-
-				this.name = theme.name;
-				this.description = theme.desc || '';
-				this.author = theme.author;
-				this.baseTheme = theme.base || 'light';
-				this.theme = convertToViewModel(theme);
-				this.themeToImport = '';
-			} catch (e) {
-				os.alert({
-					type: 'error',
-					text: e.message
-				});
-			}
-		},
-	
-		colorChanged(color: string, i: number) {
-			this.theme[i] = [this.theme[i][0], color];
-		},
-
-		getTypeOf(v: ThemeValue) {
-			return v === null
-				? this.$ts._theme.defaultValue
-				: typeof v === 'string'
-					? this.$ts._theme.color
-					: this.$t('_theme.' + v.type);
-		},
-	
-		async chooseType(e: MouseEvent, i: number) {
-			const newValue = await this.showTypeMenu(e);
-			this.theme[i] = [ this.theme[i][0], newValue ];
-		},
-	
-		showTypeMenu(e: MouseEvent) {
-			return new Promise<ThemeValue>((resolve) => {
-				os.popupMenu([{
-					text: this.$ts._theme.defaultValue,
-					action: () => resolve(null),
-				}, {
-					text: this.$ts._theme.color,
-					action: () => resolve('#000000'),
-				}, {
-					text: this.$ts._theme.func,
-					action: () => resolve({
-						type: 'func', name: 'alpha', arg: 1, value: 'accent'
-					}),
-				}, {
-					text: this.$ts._theme.refProp,
-					action: () => resolve({
-						type: 'refProp', key: 'accent',
-					}),
-				}, {
-					text: this.$ts._theme.refConst,
-					action: () => resolve({
-						type: 'refConst', key: '',
-					}),
-				}, {
-					text: 'CSS',
-					action: () => resolve({
-						type: 'css', value: '',
-					}),
-				}], e.currentTarget || e.target);
-			});
-		}
-	}
-});
-</script>
-
-<style lang="scss" scoped>
-.t9makv94 {
-	> ._section {
-		> ._content {
-			> .list-view {
-				> .item {
-					min-height: 48px;
-					word-break: break-all;
-
-					&:not(:last-child) {
-						margin-bottom: 8px;
-					}
-
-					.select {
-						margin: 24px 0;
-					}
-
-					.type {
-						cursor: pointer;
-					}
-
-					.default-value {
-						opacity: 0.6;
-						pointer-events: none;
-						user-select: none;
-					}
-
-					.color {
-						> input {
-							display: inline-block;
-							width: 1.5em;
-							height: 1.5em;
-						}
-
-						> div {
-							margin-left: 8px;
-							display: inline-block;
-						}
-					}
-				}
-			}
-		}
-	}
-}
-</style>
diff --git a/packages/client/src/pages/favorites.vue b/packages/client/src/pages/favorites.vue
index faab864744..588b0fa66c 100644
--- a/packages/client/src/pages/favorites.vue
+++ b/packages/client/src/pages/favorites.vue
@@ -1,49 +1,26 @@
 <template>
-<div class="jmelgwjh">
-	<div class="body">
-		<XNotes class="notes" :pagination="pagination" :detail="true" :prop="'note'"/>
-	</div>
-</div>
+<MkSpacer :content-max="800">
+	<XNotes :pagination="pagination" :detail="true" :prop="'note'"/>
+</MkSpacer>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
 import XNotes from '@/components/notes.vue';
-import * as os from '@/os';
 import * as symbols from '@/symbols';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	components: {
-		XNotes
-	},
+const pagination = {
+	endpoint: 'i/favorites',
+	limit: 10,
+	params: () => ({
+	}),
+};
 
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.favorites,
-				icon: 'fas fa-star',
-				bg: 'var(--bg)',
-			},
-			pagination: {
-				endpoint: 'i/favorites',
-				limit: 10,
-				params: () => ({
-				})
-			},
-		};
+defineExpose({
+	[symbols.PAGE_INFO]: {
+		title: i18n.locale.favorites,
+		icon: 'fas fa-star',
+		bg: 'var(--bg)',
 	},
 });
 </script>
-
-<style lang="scss" scoped>
-.jmelgwjh {
-	background: var(--bg);
-
-	> .body {
-		box-sizing: border-box;
-		max-width: 800px;
-		margin: 0 auto;
-		padding: 16px;
-	}
-}
-</style>
diff --git a/packages/client/src/pages/featured.vue b/packages/client/src/pages/featured.vue
index 0844c0952f..efa74ca599 100644
--- a/packages/client/src/pages/featured.vue
+++ b/packages/client/src/pages/featured.vue
@@ -4,29 +4,22 @@
 </MkSpacer>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
 import XNotes from '@/components/notes.vue';
 import * as symbols from '@/symbols';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	components: {
-		XNotes
-	},
+const pagination = {
+	endpoint: 'notes/featured',
+	limit: 10,
+	offsetMode: true,
+};
 
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.featured,
-				icon: 'fas fa-fire-alt',
-				bg: 'var(--bg)',
-			},
-			pagination: {
-				endpoint: 'notes/featured',
-				limit: 10,
-				offsetMode: true,
-			},
-		};
+defineExpose({
+	[symbols.PAGE_INFO]: {
+		title: i18n.locale.featured,
+		icon: 'fas fa-fire-alt',
+		bg: 'var(--bg)',
 	},
 });
 </script>
diff --git a/packages/client/src/pages/gallery/edit.vue b/packages/client/src/pages/gallery/edit.vue
index d317da038f..e3fa1a0fcd 100644
--- a/packages/client/src/pages/gallery/edit.vue
+++ b/packages/client/src/pages/gallery/edit.vue
@@ -10,7 +10,7 @@
 		</FormTextarea>
 
 		<FormGroup>
-			<div v-for="file in files" :key="file.id" class="_debobigegoItem _debobigegoPanel wqugxsfx" :style="{ backgroundImage: file ? `url(${ file.thumbnailUrl })` : null }">
+			<div v-for="file in files" :key="file.id" class="_formGroup wqugxsfx" :style="{ backgroundImage: file ? `url(${ file.thumbnailUrl })` : null }">
 				<div class="name">{{ file.name }}</div>
 				<button v-tooltip="$ts.remove" class="remove _button" @click="remove(file)"><i class="fas fa-times"></i></button>
 			</div>
diff --git a/packages/client/src/pages/mentions.vue b/packages/client/src/pages/mentions.vue
index 691d3bd9aa..ea23c6a2f6 100644
--- a/packages/client/src/pages/mentions.vue
+++ b/packages/client/src/pages/mentions.vue
@@ -4,28 +4,21 @@
 </MkSpacer>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
 import XNotes from '@/components/notes.vue';
 import * as symbols from '@/symbols';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	components: {
-		XNotes
-	},
+const pagination = {
+	endpoint: 'notes/mentions',
+	limit: 10,
+};
 
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.mentions,
-				icon: 'fas fa-at',
-				bg: 'var(--bg)',
-			},
-			pagination: {
-				endpoint: 'notes/mentions',
-				limit: 10,
-			},
-		};
+defineExpose({
+	[symbols.PAGE_INFO]: {
+		title: i18n.locale.mentions,
+		icon: 'fas fa-at',
+		bg: 'var(--bg)',
 	},
 });
 </script>
diff --git a/packages/client/src/pages/messages.vue b/packages/client/src/pages/messages.vue
index 9085af9489..448aa0241f 100644
--- a/packages/client/src/pages/messages.vue
+++ b/packages/client/src/pages/messages.vue
@@ -4,31 +4,24 @@
 </MkSpacer>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
 import XNotes from '@/components/notes.vue';
 import * as symbols from '@/symbols';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	components: {
-		XNotes
-	},
+const pagination = {
+	endpoint: 'notes/mentions',
+	limit: 10,
+	params: () => ({
+		visibility: 'specified'
+	}),
+};
 
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.directNotes,
-				icon: 'fas fa-envelope',
-				bg: 'var(--bg)',
-			},
-			pagination: {
-				endpoint: 'notes/mentions',
-				limit: 10,
-				params: () => ({
-					visibility: 'specified'
-				})
-			},
-		};
+defineExpose({
+	[symbols.PAGE_INFO]: {
+		title: i18n.locale.directNotes,
+		icon: 'fas fa-envelope',
+		bg: 'var(--bg)',
 	},
 });
 </script>
diff --git a/packages/client/src/pages/not-found.vue b/packages/client/src/pages/not-found.vue
index 92d3f399f7..914fdb9297 100644
--- a/packages/client/src/pages/not-found.vue
+++ b/packages/client/src/pages/not-found.vue
@@ -7,19 +7,15 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
+<script lang="ts" setup>
 import * as symbols from '@/symbols';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.notFound,
-				icon: 'fas fa-exclamation-triangle'
-			},
-		}
+defineExpose({
+	[symbols.PAGE_INFO]: {
+		title: i18n.locale.notFound,
+		icon: 'fas fa-exclamation-triangle',
+		bg: 'var(--bg)',
 	},
 });
 </script>
diff --git a/packages/client/src/pages/room/preview.vue b/packages/client/src/pages/room/preview.vue
deleted file mode 100644
index b0e600d4fb..0000000000
--- a/packages/client/src/pages/room/preview.vue
+++ /dev/null
@@ -1,107 +0,0 @@
-<template>
-<canvas width="224" height="128"></canvas>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as THREE from 'three';
-import * as os from '@/os';
-
-export default defineComponent({
-	data() {
-		return {
-			selected: null,
-			objectHeight: 0,
-			orbitRadius: 5
-		};
-	},
-
-	mounted() {
-		const canvas = this.$el;
-
-		const width = canvas.width;
-		const height = canvas.height;
-
-		const scene = new THREE.Scene();
-
-		const renderer = new THREE.WebGLRenderer({
-			canvas: canvas,
-			antialias: true,
-			alpha: false
-		});
-		renderer.setPixelRatio(window.devicePixelRatio);
-		renderer.setSize(width, height);
-		renderer.setClearColor(0x000000);
-		renderer.autoClear = false;
-		renderer.shadowMap.enabled = true;
-		renderer.shadowMap.cullFace = THREE.CullFaceBack;
-
-		const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100);
-		camera.zoom = 10;
-		camera.position.x = 0;
-		camera.position.y = 2;
-		camera.position.z = 0;
-		camera.updateProjectionMatrix();
-		scene.add(camera);
-
-		const ambientLight = new THREE.AmbientLight(0xffffff, 1);
-		ambientLight.castShadow = false;
-		scene.add(ambientLight);
-
-		const light = new THREE.PointLight(0xffffff, 1, 100);
-		light.position.set(3, 3, 3);
-		scene.add(light);
-
-		const grid = new THREE.GridHelper(5, 16, 0x444444, 0x222222);
-		scene.add(grid);
-
-		const render = () => {
-			const timer = Date.now() * 0.0004;
-			requestAnimationFrame(render);
-			
-			camera.position.y = Math.sin(Math.PI / 6) * this.orbitRadius;	// Math.PI / 6 => 30deg
-			camera.position.z = Math.cos(timer) * this.orbitRadius;
-			camera.position.x = Math.sin(timer) * this.orbitRadius;
-			camera.lookAt(new THREE.Vector3(0, this.objectHeight / 2, 0));
-			renderer.render(scene, camera);
-		};
-
-		this.selected = selected => {
-			const obj = selected.clone();
-
-			// Remove current object
-			const current = scene.getObjectByName('obj');
-			if (current != null) {
-				scene.remove(current);
-			}
-
-			// Add new object
-			obj.name = 'obj';
-			obj.position.x = 0;
-			obj.position.y = 0;
-			obj.position.z = 0;
-			obj.rotation.x = 0;
-			obj.rotation.y = 0;
-			obj.rotation.z = 0;
-			obj.traverse(child => {
-				if (child instanceof THREE.Mesh) {
-					child.material = child.material.clone();
-					return child.material.emissive.setHex(0x000000);
-				}
-			});
-			const objectBoundingBox = new THREE.Box3().setFromObject(obj);
-			this.objectHeight = objectBoundingBox.max.y - objectBoundingBox.min.y;
-
-			const objectWidth = objectBoundingBox.max.x - objectBoundingBox.min.x;
-			const objectDepth = objectBoundingBox.max.z - objectBoundingBox.min.z;
-
-			const horizontal = Math.hypot(objectWidth, objectDepth) / camera.aspect;
-			this.orbitRadius = Math.max(horizontal, this.objectHeight) * camera.zoom * 0.625 / Math.tan(camera.fov * 0.5 * (Math.PI / 180));
-		
-			scene.add(obj);
-		};
-
-		render();
-	},
-});
-</script>
diff --git a/packages/client/src/pages/room/room.vue b/packages/client/src/pages/room/room.vue
deleted file mode 100644
index eb85d39dc4..0000000000
--- a/packages/client/src/pages/room/room.vue
+++ /dev/null
@@ -1,279 +0,0 @@
-<template>
-<div class="hveuntkp">
-	<div v-if="objectSelected" class="controller _section">
-		<div class="_content">
-			<p class="name">{{ selectedFurnitureName }}</p>
-			<XPreview ref="preview"/>
-			<template v-if="selectedFurnitureInfo.props">
-				<div v-for="k in Object.keys(selectedFurnitureInfo.props)" :key="k">
-					<p>{{ k }}</p>
-					<template v-if="selectedFurnitureInfo.props[k] === 'image'">
-						<MkButton @click="chooseImage(k, $event)">{{ $ts._rooms.chooseImage }}</MkButton>
-					</template>
-					<template v-else-if="selectedFurnitureInfo.props[k] === 'color'">
-						<input type="color" :value="selectedFurnitureProps ? selectedFurnitureProps[k] : null" @change="updateColor(k, $event)"/>
-					</template>
-				</div>
-			</template>
-		</div>
-		<div class="_content">
-			<MkButton inline :primary="isTranslateMode" @click="translate()"><i class="fas fa-arrows-alt"></i> {{ $ts._rooms.translate }}</MkButton>
-			<MkButton inline :primary="isRotateMode" @click="rotate()"><i class="fas fa-undo"></i> {{ $ts._rooms.rotate }}</MkButton>
-			<MkButton v-if="isTranslateMode || isRotateMode" inline @click="exit()"><i class="fas fa-ban"></i> {{ $ts._rooms.exit }}</MkButton>
-		</div>
-		<div class="_content">
-			<MkButton @click="remove()"><i class="fas fa-trash-alt"></i> {{ $ts._rooms.remove }}</MkButton>
-		</div>
-	</div>
-
-	<div v-if="isMyRoom" class="menu _section">
-		<div class="_content">
-			<MkButton @click="add()"><i class="fas fa-box-open"></i> {{ $ts._rooms.addFurniture }}</MkButton>
-		</div>
-		<div class="_content">
-			<MkSelect :model-value="roomType" @update:modelValue="updateRoomType($event)">
-				<template #label>{{ $ts._rooms.roomType }}</template>
-				<option value="default">{{ $ts._rooms._roomType.default }}</option>
-				<option value="washitsu">{{ $ts._rooms._roomType.washitsu }}</option>
-			</MkSelect>
-			<label v-if="roomType === 'default'">
-				<span>{{ $ts._rooms.carpetColor }}</span>
-				<input type="color" :value="carpetColor" @change="updateCarpetColor($event)"/>
-			</label>
-		</div>
-		<div class="_content">
-			<MkButton inline :disabled="!changed" primary @click="save()"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
-			<MkButton inline @click="clear()"><i class="fas fa-broom"></i> {{ $ts._rooms.clear }}</MkButton>
-		</div>
-	</div>
-</div>
-</template>
-
-<script lang="ts">
-import { computed, defineComponent } from 'vue';
-import { Room } from '@/scripts/room/room';
-import * as Acct from 'misskey-js/built/acct';
-import XPreview from './preview.vue';
-const storeItems = require('@/scripts/room/furnitures.json5');
-import { query as urlQuery } from '@/scripts/url';
-import MkButton from '@/components/ui/button.vue';
-import MkSelect from '@/components/form/select.vue';
-import { selectFile } from '@/scripts/select-file';
-import * as os from '@/os';
-import { ColdDeviceStorage } from '@/store';
-import * as symbols from '@/symbols';
-
-let room: Room;
-
-export default defineComponent({
-	components: {
-		XPreview,
-		MkButton,
-		MkSelect,
-	},
-
-	beforeRouteLeave(to, from, next) {
-		if (this.changed) {
-			os.confirm({
-				type: 'warning',
-				text: this.$ts.leaveConfirm,
-			}).then(({ canceled }) => {
-				if (canceled) {
-					next(false);
-				} else {
-					next();
-				}
-			});
-		} else {
-			next();
-		}
-	},
-
-	props: {
-		acct: {
-			type: String,
-			required: true
-		},
-	},
-
-	data() {
-		return {
-			[symbols.PAGE_INFO]: computed(() => this.user ? {
-				title: this.$ts.room,
-				avatar: this.user,
-			} : null),
-			user: null,
-			objectSelected: false,
-			selectedFurnitureName: null,
-			selectedFurnitureInfo: null,
-			selectedFurnitureProps: null,
-			roomType: null,
-			carpetColor: null,
-			isTranslateMode: false,
-			isRotateMode: false,
-			isMyRoom: false,
-			changed: false,
-		};
-	},
-
-	async mounted() {
-		window.addEventListener('beforeunload', this.beforeunload);
-
-		this.user = await os.api('users/show', {
-			...Acct.parse(this.acct)
-		});
-
-		this.isMyRoom = this.$i && (this.$i.id === this.user.id);
-
-		const roomInfo = await os.api('room/show', {
-			userId: this.user.id
-		});
-
-		this.roomType = roomInfo.roomType;
-		this.carpetColor = roomInfo.carpetColor;
-
-		room = new Room(this.user, this.isMyRoom, roomInfo, this.$el, {
-			graphicsQuality: ColdDeviceStorage.get('roomGraphicsQuality'),
-			onChangeSelect: obj => {
-				this.objectSelected = obj != null;
-				if (obj) {
-					const f = room.findFurnitureById(obj.name);
-					this.selectedFurnitureName = this.$t('_rooms._furnitures.' + f.type);
-					this.selectedFurnitureInfo = storeItems.find(x => x.id === f.type);
-					this.selectedFurnitureProps = f.props
-						? JSON.parse(JSON.stringify(f.props)) // Disable reactivity
-						: null;
-					this.$nextTick(() => {
-						this.$refs.preview.selected(obj);
-					});
-				}
-			},
-			useOrthographicCamera: ColdDeviceStorage.get('roomUseOrthographicCamera'),
-		});
-	},
-
-	beforeUnmount() {
-		room.destroy();
-		window.removeEventListener('beforeunload', this.beforeunload);
-	},
-
-	methods: {
-		beforeunload(e: BeforeUnloadEvent) {
-			if (this.changed) {
-				e.preventDefault();
-				e.returnValue = '';
-			}
-		},
-
-		async add() {
-			const { canceled, result: id } = await os.select({
-				title: this.$ts._rooms.addFurniture,
-				items: storeItems.map(item => ({
-					value: item.id, text: this.$t('_rooms._furnitures.' + item.id)
-				}))
-			});
-			if (canceled) return;
-			room.addFurniture(id);
-			this.changed = true;
-		},
-
-		remove() {
-			this.isTranslateMode = false;
-			this.isRotateMode = false;
-			room.removeFurniture();
-			this.changed = true;
-		},
-
-		save() {
-			os.api('room/update', {
-				room: room.getRoomInfo()
-			}).then(() => {
-				this.changed = false;
-				os.success();
-			}).catch((e: any) => {
-				os.alert({
-					type: 'error',
-					text: e.message
-				});
-			});
-		},
-
-		clear() {
-			os.confirm({
-				type: 'warning',
-				text: this.$ts._rooms.clearConfirm,
-			}).then(({ canceled }) => {
-				if (canceled) return;
-				room.removeAllFurnitures();
-				this.changed = true;
-			});
-		},
-
-		chooseImage(key, e) {
-			selectFile(e.currentTarget || e.target, null).then(file => {
-				room.updateProp(key, `/proxy/?${urlQuery({ url: file.thumbnailUrl })}`);
-				this.$refs.preview.selected(room.getSelectedObject());
-				this.changed = true;
-			});
-		},
-
-		updateColor(key, ev) {
-			room.updateProp(key, ev.target.value);
-			this.$refs.preview.selected(room.getSelectedObject());
-			this.changed = true;
-		},
-
-		updateCarpetColor(ev) {
-			room.updateCarpetColor(ev.target.value);
-			this.carpetColor = ev.target.value;
-			this.changed = true;
-		},
-
-		updateRoomType(type) {
-			room.changeRoomType(type);
-			this.roomType = type;
-			this.changed = true;
-		},
-
-		translate() {
-			if (this.isTranslateMode) {
-				this.exit();
-			} else {
-				this.isRotateMode = false;
-				this.isTranslateMode = true;
-				room.enterTransformMode('translate');
-			}
-			this.changed = true;
-		},
-
-		rotate() {
-			if (this.isRotateMode) {
-				this.exit();
-			} else {
-				this.isTranslateMode = false;
-				this.isRotateMode = true;
-				room.enterTransformMode('rotate');
-			}
-			this.changed = true;
-		},
-
-		exit() {
-			this.isTranslateMode = false;
-			this.isRotateMode = false;
-			room.exitTransformMode();
-			this.changed = true;
-		}
-	}
-});
-</script>
-
-<style lang="scss" scoped>
-.hveuntkp {
-	position: relative;
-	min-height: 500px;
-
-	> ::v-deep(canvas) {
-		display: block;
-	}
-}
-</style>
diff --git a/packages/client/src/pages/settings/other.vue b/packages/client/src/pages/settings/other.vue
index acc1fb4d3e..7547013832 100644
--- a/packages/client/src/pages/settings/other.vue
+++ b/packages/client/src/pages/settings/other.vue
@@ -63,11 +63,6 @@ export default defineComponent({
 				injectFeaturedNote: v
 			});
 		},
-
-		taskmanager() {
-			os.popup(import('@/components/taskmanager.vue'), {
-			}, {}, 'closed');
-		},
 	}
 });
 </script>
diff --git a/packages/client/src/pages/test.vue b/packages/client/src/pages/test.vue
deleted file mode 100644
index d05e00d374..0000000000
--- a/packages/client/src/pages/test.vue
+++ /dev/null
@@ -1,260 +0,0 @@
-<template>
-<div class="_section">
-	<div class="_content">
-		<div class="_card _gap">
-			<div class="_title">Dialog</div>
-			<div class="_content">
-				<MkInput v-model="dialogTitle">
-					<template #label>Title</template>
-				</MkInput>
-				<MkInput v-model="dialogBody">
-					<template #label>Body</template>
-				</MkInput>
-				<MkRadio v-model="dialogType" value="info">Info</MkRadio>
-				<MkRadio v-model="dialogType" value="success">Success</MkRadio>
-				<MkRadio v-model="dialogType" value="warning">Warn</MkRadio>
-				<MkRadio v-model="dialogType" value="error">Error</MkRadio>
-				<MkSwitch v-model="dialogCancel">
-					<span>With cancel button</span>
-				</MkSwitch>
-				<MkSwitch v-model="dialogCancelByBgClick">
-					<span>Can cancel by modal bg click</span>
-				</MkSwitch>
-				<MkSwitch v-model="dialogInput">
-					<span>With input field</span>
-				</MkSwitch>
-				<MkButton @click="showDialog()">Show</MkButton>
-			</div>
-			<div class="_content">
-				<code>Result: {{ dialogResult }}</code>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">Form</div>
-			<div class="_content">
-				<MkInput v-model="formTitle">
-					<template #label>Title</template>
-				</MkInput>
-				<MkTextarea v-model="formForm">
-					<template #label>Form</template>
-				</MkTextarea>
-				<MkButton @click="form()">Show</MkButton>
-			</div>
-			<div class="_content">
-				<code>Result: {{ formResult }}</code>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">MFM</div>
-			<div class="_content">
-				<MkTextarea v-model="mfm">
-					<template #label>MFM</template>
-				</MkTextarea>
-			</div>
-			<div class="_content">
-				<Mfm :text="mfm"/>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">selectDriveFile</div>
-			<div class="_content">
-				<MkSwitch v-model="selectDriveFileMultiple">
-					<span>Multiple</span>
-				</MkSwitch>
-				<MkButton @click="selectDriveFile()">selectDriveFile</MkButton>
-			</div>
-			<div class="_content">
-				<code>Result: {{ JSON.stringify(selectDriveFileResult) }}</code>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">selectDriveFolder</div>
-			<div class="_content">
-				<MkSwitch v-model="selectDriveFolderMultiple">
-					<span>Multiple</span>
-				</MkSwitch>
-				<MkButton @click="selectDriveFolder()">selectDriveFolder</MkButton>
-			</div>
-			<div class="_content">
-				<code>Result: {{ JSON.stringify(selectDriveFolderResult) }}</code>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">selectUser</div>
-			<div class="_content">
-				<MkButton @click="selectUser()">selectUser</MkButton>
-			</div>
-			<div class="_content">
-				<code>Result: {{ user }}</code>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">Notification</div>
-			<div class="_content">
-				<MkInput v-model="notificationIconUrl">
-					<template #label>Icon URL</template>
-				</MkInput>
-				<MkInput v-model="notificationHeader">
-					<template #label>Header</template>
-				</MkInput>
-				<MkTextarea v-model="notificationBody">
-					<template #label>Body</template>
-				</MkTextarea>
-				<MkButton @click="createNotification()">createNotification</MkButton>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">Waiting dialog</div>
-			<div class="_content">
-				<MkButton inline @click="openWaitingDialog()">icon only</MkButton>
-				<MkButton inline @click="openWaitingDialog('Doing')">with text</MkButton>
-			</div>
-		</div>
-
-		<div class="_card _gap">
-			<div class="_title">Messaging window</div>
-			<div class="_content">
-				<MkButton @click="messagingWindowOpen()">open</MkButton>
-			</div>
-		</div>
-
-		<MkButton @click="resetTutorial()">Reset tutorial</MkButton>
-	</div>
-</div>
-</template>
-
-<script lang="ts">
-import { defineComponent, defineAsyncComponent } from 'vue';
-import MkButton from '@/components/ui/button.vue';
-import MkInput from '@/components/form/input.vue';
-import MkSwitch from '@/components/form/switch.vue';
-import MkTextarea from '@/components/form/textarea.vue';
-import MkRadio from '@/components/form/radio.vue';
-import * as os from '@/os';
-import * as symbols from '@/symbols';
-
-export default defineComponent({
-	components: {
-		MkButton,
-		MkInput,
-		MkSwitch,
-		MkTextarea,
-		MkRadio,
-	},
-
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: 'TEST',
-				icon: 'fas fa-exclamation-triangle'
-			},
-			dialogTitle: 'Hello',
-			dialogBody: 'World!',
-			dialogType: 'info',
-			dialogCancel: false,
-			dialogCancelByBgClick: true,
-			dialogInput: false,
-			dialogResult: null,
-			formTitle: 'Test form',
-			formForm: JSON.stringify({
-				foo: {
-					type: 'boolean',
-					default: true,
-					label: 'This is a boolean property'
-				},
-				bar: {
-					type: 'number',
-					default: 300,
-					label: 'This is a number property'
-				},
-				baz: {
-					type: 'string',
-					default: 'Misskey makes you happy.',
-					label: 'This is a string property'
-				},
-				qux: {
-					type: 'string',
-					multiline: true,
-					default: 'Misskey makes\nyou happy.',
-					label: 'Multiline string'
-				},
-			}, null, '\t'),
-			formResult: null,
-			mfm: '',
-			selectDriveFileMultiple: false,
-			selectDriveFolderMultiple: false,
-			selectDriveFileResult: null,
-			selectDriveFolderResult: null,
-			user: null,
-			notificationIconUrl: null,
-			notificationHeader: '',
-			notificationBody: '',
-		}
-	},
-
-	methods: {
-		async showDialog() {
-			this.dialogResult = null;
-			/*
-			this.dialogResult = await os.dialog({
-				type: this.dialogType,
-				title: this.dialogTitle,
-				text: this.dialogBody,
-				showCancelButton: this.dialogCancel,
-				cancelableByBgClick: this.dialogCancelByBgClick,
-				input: this.dialogInput ? {} : null
-			});*/
-		},
-
-		async form() {
-			this.formResult = null;
-			this.formResult = await os.form(this.formTitle, JSON.parse(this.formForm));
-		},
-
-		async selectDriveFile() {
-			this.selectDriveFileResult = null;
-			this.selectDriveFileResult = await os.selectDriveFile(this.selectDriveFileMultiple);
-		},
-
-		async selectDriveFolder() {
-			this.selectDriveFolderResult = null;
-			this.selectDriveFolderResult = await os.selectDriveFolder(this.selectDriveFolderMultiple);
-		},
-
-		async selectUser() {
-			this.user = null;
-			this.user = await os.selectUser();
-		},
-
-		async createNotification() {
-			os.api('notifications/create', {
-				header: this.notificationHeader,
-				body: this.notificationBody,
-				icon: this.notificationIconUrl,
-			});
-		},
-
-		messagingWindowOpen() {
-			os.pageWindow('/my/messaging');
-		},
-
-		openWaitingDialog(text?) {
-			const promise = new Promise((resolve, reject) => {
-				setTimeout(resolve, 2000);
-			});
-			os.promiseDialog(promise, null, null, text);
-		},
-
-		resetTutorial() {
-			this.$store.set('tutorial', 0);
-		},
-	}
-});
-</script>
diff --git a/packages/client/src/pages/v.vue b/packages/client/src/pages/v.vue
deleted file mode 100644
index 3b1bb20861..0000000000
--- a/packages/client/src/pages/v.vue
+++ /dev/null
@@ -1,29 +0,0 @@
-<template>
-<div>
-	<section class="_section">
-		<div class="_content" style="text-align: center;">
-			<img src="/static-assets/icons/512.png" alt="" style="display: block; width: 100px; margin: 0 auto; border-radius: 16px;"/>
-			<div style="margin-top: 0.75em;">Misskey</div>
-			<div style="opacity: 0.5;">v{{ version }}</div>
-		</div>
-	</section>
-</div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-import { version } from '@/config';
-import * as symbols from '@/symbols';
-
-export default defineComponent({
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: 'Misskey',
-				icon: null
-			},
-			version,
-		}
-	},
-});
-</script>
diff --git a/packages/client/src/router.ts b/packages/client/src/router.ts
index 2a07ff37cd..a5ae1177e8 100644
--- a/packages/client/src/router.ts
+++ b/packages/client/src/router.ts
@@ -20,7 +20,6 @@ const defaultRoutes = [
 	{ path: '/@:acct/:page?', name: 'user', component: page('user/index'), props: route => ({ acct: route.params.acct, page: route.params.page || 'index' }) },
 	{ path: '/@:user/pages/:page', component: page('page'), props: route => ({ pageName: route.params.page, username: route.params.user }) },
 	{ path: '/@:user/pages/:pageName/view-source', component: page('page-editor/page-editor'), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) },
-	{ path: '/@:acct/room', props: true, component: page('room/room') },
 	{ path: '/settings/:page(.*)?', name: 'settings', component: page('settings/index'), props: route => ({ initialPage: route.params.page || null }) },
 	{ path: '/reset-password/:token?', component: page('reset-password'), props: route => ({ token: route.params.token }) },
 	{ path: '/signup-complete/:code', component: page('signup-complete'), props: route => ({ code: route.params.code }) },
diff --git a/packages/client/src/scripts/room/furniture.ts b/packages/client/src/scripts/room/furniture.ts
deleted file mode 100644
index 7734e32668..0000000000
--- a/packages/client/src/scripts/room/furniture.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-export type RoomInfo = {
-	roomType: string;
-	carpetColor: string;
-	furnitures: Furniture[];
-};
-
-export type Furniture = {
-	id: string; // 同じ家具が複数ある場合にそれぞれを識別するためのIDであり、家具IDではない
-	type: string; // こっちが家具ID(chairとか)
-	position: {
-		x: number;
-		y: number;
-		z: number;
-	};
-	rotation: {
-		x: number;
-		y: number;
-		z: number;
-	};
-	props?: Record<string, any>;
-};
diff --git a/packages/client/src/scripts/room/furnitures.json5 b/packages/client/src/scripts/room/furnitures.json5
deleted file mode 100644
index 4a40994107..0000000000
--- a/packages/client/src/scripts/room/furnitures.json5
+++ /dev/null
@@ -1,407 +0,0 @@
-// 家具メタデータ
-
-// 家具IDはglbファイル及びそのディレクトリ名と一致する必要があります
-
-// 家具にはユーザーが設定できるプロパティを設定可能です:
-//
-// props: {
-//   <propname>: <proptype>
-// }
-//
-// proptype一覧:
-// * image ... 画像選択ダイアログを出し、その画像のURLが格納されます
-// * color ... 色選択コントロールを出し、選択された色が格納されます
-
-// 家具にカスタムテクスチャを適用できるようにするには、textureプロパティに以下の追加の情報を含めます:
-// 便宜上そのUVのどの部分にカスタムテクスチャを貼り合わせるかのエリアをテクスチャエリアと呼びます。
-// UVは1024*1024だと仮定します。
-//
-// <key>: {
-//   prop: <プロパティ名>,
-//   uv: {
-//     x: <テクスチャエリアX座標>,
-//     y: <テクスチャエリアY座標>,
-//     width: <テクスチャエリアの幅>,
-//     height: <テクスチャエリアの高さ>,
-//   },
-// }
-//
-// <key>には、カスタムテクスチャを適用したいメッシュ名を指定します
-// <プロパティ名>には、カスタムテクスチャとして使用する画像を格納するプロパティ(前述)名を指定します
-
-// 家具にカスタムカラーを適用できるようにするには、colorプロパティに以下の追加の情報を含めます:
-//
-// <key>: <プロパティ名>
-//
-// <key>には、カスタムカラーを適用したいマテリアル名を指定します
-// <プロパティ名>には、カスタムカラーとして使用する色を格納するプロパティ(前述)名を指定します
-
-[
-	{
-		id: "milk",
-		place: "floor"
-	},
-	{
-		id: "bed",
-		place: "floor"
-	},
-	{
-		id: "low-table",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Table: 'color'
-		}
-	},
-	{
-		id: "desk",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Board: 'color'
-		}
-	},
-	{
-		id: "chair",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Chair: 'color'
-		}
-	},
-	{
-		id: "chair2",
-		place: "floor",
-		props: {
-			color1: 'color',
-			color2: 'color'
-		},
-		color: {
-			Cushion: 'color1',
-			Leg: 'color2'
-		}
-	},
-	{
-		id: "fan",
-		place: "wall"
-	},
-	{
-		id: "pc",
-		place: "floor"
-	},
-	{
-		id: "plant",
-		place: "floor"
-	},
-	{
-		id: "plant2",
-		place: "floor"
-	},
-	{
-		id: "eraser",
-		place: "floor"
-	},
-	{
-		id: "pencil",
-		place: "floor"
-	},
-	{
-		id: "pudding",
-		place: "floor"
-	},
-	{
-		id: "cardboard-box",
-		place: "floor"
-	},
-	{
-		id: "cardboard-box2",
-		place: "floor"
-	},
-	{
-		id: "cardboard-box3",
-		place: "floor"
-	},
-	{
-		id: "book",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Cover: 'color'
-		}
-	},
-	{
-		id: "book2",
-		place: "floor"
-	},
-	{
-		id: "piano",
-		place: "floor"
-	},
-	{
-		id: "facial-tissue",
-		place: "floor"
-	},
-	{
-		id: "server",
-		place: "floor"
-	},
-	{
-		id: "moon",
-		place: "floor"
-	},
-	{
-		id: "corkboard",
-		place: "wall"
-	},
-	{
-		id: "mousepad",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Pad: 'color'
-		}
-	},
-	{
-		id: "monitor",
-		place: "floor",
-		props: {
-			screen: 'image'
-		},
-		texture: {
-			Screen: {
-				prop: 'screen',
-				uv: {
-					x: 0,
-					y: 434,
-					width: 1024,
-					height: 588,
-				},
-			},
-		},
-	},
-	{
-		id: "tv",
-		place: "floor",
-		props: {
-			screen: 'image'
-		},
-		texture: {
-			Screen: {
-				prop: 'screen',
-				uv: {
-					x: 0,
-					y: 434,
-					width: 1024,
-					height: 588,
-				},
-			},
-		},
-	},
-	{
-		id: "keyboard",
-		place: "floor"
-	},
-	{
-		id: "carpet-stripe",
-		place: "floor",
-		props: {
-			color1: 'color',
-			color2: 'color'
-		},
-		color: {
-			CarpetAreaA: 'color1',
-			CarpetAreaB: 'color2'
-		},
-	},
-	{
-		id: "mat",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Mat: 'color'
-		}
-	},
-	{
-		id: "color-box",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			main: 'color'
-		}
-	},
-	{
-		id: "wall-clock",
-		place: "wall"
-	},
-	{
-		id: "cube",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Cube: 'color'
-		}
-	},
-	{
-		id: "photoframe",
-		place: "wall",
-		props: {
-			photo: 'image',
-			color: 'color'
-		},
-		texture: {
-			Photo: {
-				prop: 'photo',
-				uv: {
-					x: 0,
-					y: 342,
-					width: 1024,
-					height: 683,
-				},
-			},
-		},
-		color: {
-			Frame: 'color'
-		}
-	},
-	{
-		id: "pinguin",
-		place: "floor",
-		props: {
-			body: 'color',
-			belly: 'color'
-		},
-		color: {
-			Body: 'body',
-			Belly: 'belly',
-		}
-	},
-	{
-		id: "rubik-cube",
-		place: "floor",
-	},
-	{
-		id: "poster-h",
-		place: "wall",
-		props: {
-			picture: 'image'
-		},
-		texture: {
-			Poster: {
-				prop: 'picture',
-				uv: {
-					x: 0,
-					y: 277,
-					width: 1024,
-					height: 745,
-				},
-			},
-		},
-	},
-	{
-		id: "poster-v",
-		place: "wall",
-		props: {
-			picture: 'image'
-		},
-		texture: {
-			Poster: {
-				prop: 'picture',
-				uv: {
-					x: 0,
-					y: 0,
-					width: 745,
-					height: 1024,
-				},
-			},
-		},
-	},
-	{
-		id: "sofa",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Sofa: 'color'
-		}
-	},
-	{
-		id: "spiral",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Step: 'color'
-		}
-	},
-	{
-		id: "bin",
-		place: "floor",
-		props: {
-			color: 'color'
-		},
-		color: {
-			Bin: 'color'
-		}
-	},
-	{
-		id: "cup-noodle",
-		place: "floor"
-	},
-	{
-		id: "holo-display",
-		place: "floor",
-		props: {
-			image: 'image'
-		},
-		texture: {
-			Image_Front: {
-				prop: 'image',
-				uv: {
-					x: 0,
-					y: 0,
-					width: 1024,
-					height: 1024,
-				},
-			},
-			Image_Back: {
-				prop: 'image',
-				uv: {
-					x: 0,
-					y: 0,
-					width: 1024,
-					height: 1024,
-				},
-			},
-		},
-	},
-	{
-		id: 'energy-drink',
-		place: "floor",
-	},
-	{
-		id: 'doll-ai',
-		place: "floor",
-	},
-	{
-		id: 'banknote',
-		place: "floor",
-	},
-]
diff --git a/packages/client/src/scripts/room/room.ts b/packages/client/src/scripts/room/room.ts
deleted file mode 100644
index 7e04bec646..0000000000
--- a/packages/client/src/scripts/room/room.ts
+++ /dev/null
@@ -1,775 +0,0 @@
-import autobind from 'autobind-decorator';
-import { v4 as uuid } from 'uuid';
-import * as THREE from 'three';
-import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
-import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
-import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
-import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
-import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
-import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js';
-import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';
-import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
-import { Furniture, RoomInfo } from './furniture';
-import { query as urlQuery } from '@/scripts/url';
-const furnitureDefs = require('./furnitures.json5');
-
-THREE.ImageUtils.crossOrigin = '';
-
-type Options = {
-	graphicsQuality: Room['graphicsQuality'];
-	onChangeSelect: Room['onChangeSelect'];
-	useOrthographicCamera: boolean;
-};
-
-/**
- * MisskeyRoom Core Engine
- */
-export class Room {
-	private clock: THREE.Clock;
-	private scene: THREE.Scene;
-	private renderer: THREE.WebGLRenderer;
-	private camera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
-	private controls: OrbitControls;
-	private composer: EffectComposer;
-	private mixers: THREE.AnimationMixer[] = [];
-	private furnitureControl: TransformControls;
-	private roomInfo: RoomInfo;
-	private graphicsQuality: 'cheep' | 'low' | 'medium' | 'high' | 'ultra';
-	private roomObj: THREE.Object3D;
-	private objects: THREE.Object3D[] = [];
-	private selectedObject: THREE.Object3D = null;
-	private onChangeSelect: Function;
-	private isTransformMode = false;
-	private renderFrameRequestId: number;
-
-	private get canvas(): HTMLCanvasElement {
-		return this.renderer.domElement;
-	}
-
-	private get furnitures(): Furniture[] {
-		return this.roomInfo.furnitures;
-	}
-
-	private set furnitures(furnitures: Furniture[]) {
-		this.roomInfo.furnitures = furnitures;
-	}
-
-	private get enableShadow() {
-		return this.graphicsQuality != 'cheep';
-	}
-
-	private get usePostFXs() {
-		return this.graphicsQuality !== 'cheep' && this.graphicsQuality !== 'low';
-	}
-
-	private get shadowQuality() {
-		return (
-			this.graphicsQuality === 'ultra' ? 16384 :
-			this.graphicsQuality === 'high' ? 8192 :
-			this.graphicsQuality === 'medium' ? 4096 :
-			this.graphicsQuality === 'low' ? 1024 :
-			0); // cheep
-	}
-
-	constructor(user, isMyRoom, roomInfo: RoomInfo, container: Element, options: Options) {
-		this.roomInfo = roomInfo;
-		this.graphicsQuality = options.graphicsQuality;
-		this.onChangeSelect = options.onChangeSelect;
-
-		this.clock = new THREE.Clock(true);
-
-		//#region Init a scene
-		this.scene = new THREE.Scene();
-
-		const width = container.clientWidth;
-		const height = container.clientHeight;
-
-		//#region Init a renderer
-		this.renderer = new THREE.WebGLRenderer({
-			antialias: false,
-			stencil: false,
-			alpha: false,
-			powerPreference:
-				this.graphicsQuality === 'ultra' ? 'high-performance' :
-				this.graphicsQuality === 'high' ? 'high-performance' :
-				this.graphicsQuality === 'medium' ? 'default' :
-				this.graphicsQuality === 'low' ? 'low-power' :
-				'low-power' // cheep
-		});
-
-		this.renderer.setPixelRatio(window.devicePixelRatio);
-		this.renderer.setSize(width, height);
-		this.renderer.autoClear = false;
-		this.renderer.setClearColor(new THREE.Color(0x051f2d));
-		this.renderer.shadowMap.enabled = this.enableShadow;
-		this.renderer.shadowMap.type =
-			this.graphicsQuality === 'ultra' ? THREE.PCFSoftShadowMap :
-			this.graphicsQuality === 'high' ? THREE.PCFSoftShadowMap :
-			this.graphicsQuality === 'medium' ? THREE.PCFShadowMap :
-			this.graphicsQuality === 'low' ? THREE.BasicShadowMap :
-			THREE.BasicShadowMap; // cheep
-
-		container.insertBefore(this.canvas, container.firstChild);
-		//#endregion
-
-		//#region Init a camera
-		this.camera = options.useOrthographicCamera
-			? new THREE.OrthographicCamera(
-				width / - 2, width / 2, height / 2, height / - 2, -10, 10)
-			: new THREE.PerspectiveCamera(45, width / height);
-
-		if (options.useOrthographicCamera) {
-			this.camera.position.x = 2;
-			this.camera.position.y = 2;
-			this.camera.position.z = 2;
-			this.camera.zoom = 100;
-			this.camera.updateProjectionMatrix();
-		} else {
-			this.camera.position.x = 5;
-			this.camera.position.y = 2;
-			this.camera.position.z = 5;
-		}
-
-		this.scene.add(this.camera);
-		//#endregion
-
-		//#region AmbientLight
-		const ambientLight = new THREE.AmbientLight(0xffffff, 1);
-		this.scene.add(ambientLight);
-		//#endregion
-
-		if (this.graphicsQuality !== 'cheep') {
-			//#region Room light
-			const roomLight = new THREE.SpotLight(0xffffff, 0.1);
-
-			roomLight.position.set(0, 8, 0);
-			roomLight.castShadow = this.enableShadow;
-			roomLight.shadow.bias = -0.0001;
-			roomLight.shadow.mapSize.width = this.shadowQuality;
-			roomLight.shadow.mapSize.height = this.shadowQuality;
-			roomLight.shadow.camera.near = 0.1;
-			roomLight.shadow.camera.far = 9;
-			roomLight.shadow.camera.fov = 45;
-
-			this.scene.add(roomLight);
-			//#endregion
-		}
-
-		//#region Out light
-		const outLight1 = new THREE.SpotLight(0xffffff, 0.4);
-		outLight1.position.set(9, 3, -2);
-		outLight1.castShadow = this.enableShadow;
-		outLight1.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある
-		outLight1.shadow.mapSize.width = this.shadowQuality;
-		outLight1.shadow.mapSize.height = this.shadowQuality;
-		outLight1.shadow.camera.near = 6;
-		outLight1.shadow.camera.far = 15;
-		outLight1.shadow.camera.fov = 45;
-		this.scene.add(outLight1);
-
-		const outLight2 = new THREE.SpotLight(0xffffff, 0.2);
-		outLight2.position.set(-2, 3, 9);
-		outLight2.castShadow = false;
-		outLight2.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある
-		outLight2.shadow.camera.near = 6;
-		outLight2.shadow.camera.far = 15;
-		outLight2.shadow.camera.fov = 45;
-		this.scene.add(outLight2);
-		//#endregion
-
-		//#region Init a controller
-		this.controls = new OrbitControls(this.camera, this.canvas);
-
-		this.controls.target.set(0, 1, 0);
-		this.controls.enableZoom = true;
-		this.controls.enablePan = isMyRoom;
-		this.controls.minPolarAngle = 0;
-		this.controls.maxPolarAngle = Math.PI / 2;
-		this.controls.minAzimuthAngle = 0;
-		this.controls.maxAzimuthAngle = Math.PI / 2;
-		this.controls.enableDamping = true;
-		this.controls.dampingFactor = 0.2;
-		//#endregion
-
-		//#region POST FXs
-		if (!this.usePostFXs) {
-			this.composer = null;
-		} else {
-			const renderTarget = new THREE.WebGLRenderTarget(width, height, {
-				minFilter: THREE.LinearFilter,
-				magFilter: THREE.LinearFilter,
-				format: THREE.RGBFormat,
-				stencilBuffer: false,
-			});
-
-			const fxaa = new ShaderPass(FXAAShader);
-			fxaa.uniforms['resolution'].value = new THREE.Vector2(1 / width, 1 / height);
-			fxaa.renderToScreen = true;
-
-			this.composer = new EffectComposer(this.renderer, renderTarget);
-			this.composer.addPass(new RenderPass(this.scene, this.camera));
-			if (this.graphicsQuality === 'ultra') {
-				this.composer.addPass(new BloomPass(0.25, 30, 128.0, 512));
-			}
-			this.composer.addPass(fxaa);
-		}
-		//#endregion
-		//#endregion
-
-		//#region Label
-		//#region Avatar
-		const avatarUrl = `/proxy/?${urlQuery({ url: user.avatarUrl })}`;
-
-		const textureLoader = new THREE.TextureLoader();
-		textureLoader.crossOrigin = 'anonymous';
-
-		const iconTexture = textureLoader.load(avatarUrl);
-		iconTexture.wrapS = THREE.RepeatWrapping;
-		iconTexture.wrapT = THREE.RepeatWrapping;
-		iconTexture.anisotropy = 16;
-
-		const avatarMaterial = new THREE.MeshBasicMaterial({
-			map: iconTexture,
-			side: THREE.DoubleSide,
-			alphaTest: 0.5
-		});
-
-		const iconGeometry = new THREE.PlaneGeometry(1, 1);
-
-		const avatarObject = new THREE.Mesh(iconGeometry, avatarMaterial);
-		avatarObject.position.set(-3, 2.5, 2);
-		avatarObject.rotation.y = Math.PI / 2;
-		avatarObject.castShadow = false;
-
-		this.scene.add(avatarObject);
-		//#endregion
-
-		//#region Username
-		const name = user.username;
-
-		new THREE.FontLoader().load('/assets/fonts/helvetiker_regular.typeface.json', font => {
-			const nameGeometry = new THREE.TextGeometry(name, {
-				size: 0.5,
-				height: 0,
-				curveSegments: 8,
-				font: font,
-				bevelThickness: 0,
-				bevelSize: 0,
-				bevelEnabled: false
-			});
-
-			const nameMaterial = new THREE.MeshLambertMaterial({
-				color: 0xffffff
-			});
-
-			const nameObject = new THREE.Mesh(nameGeometry, nameMaterial);
-			nameObject.position.set(-3, 2.25, 1.25);
-			nameObject.rotation.y = Math.PI / 2;
-			nameObject.castShadow = false;
-
-			this.scene.add(nameObject);
-		});
-		//#endregion
-		//#endregion
-
-		//#region Interaction
-		if (isMyRoom) {
-			this.furnitureControl = new TransformControls(this.camera, this.canvas);
-			this.scene.add(this.furnitureControl);
-
-			// Hover highlight
-			this.canvas.onmousemove = this.onmousemove;
-
-			// Click
-			this.canvas.onmousedown = this.onmousedown;
-		}
-		//#endregion
-
-		//#region Init room
-		this.loadRoom();
-		//#endregion
-
-		//#region Load furnitures
-		for (const furniture of this.furnitures) {
-			this.loadFurniture(furniture).then(obj => {
-				this.scene.add(obj.scene);
-				this.objects.push(obj.scene);
-			});
-		}
-		//#endregion
-
-		// Start render
-		if (this.usePostFXs) {
-			this.renderWithPostFXs();
-		} else {
-			this.renderWithoutPostFXs();
-		}
-	}
-
-	@autobind
-	private renderWithoutPostFXs() {
-		this.renderFrameRequestId =
-			window.requestAnimationFrame(this.renderWithoutPostFXs);
-
-		// Update animations
-		const clock = this.clock.getDelta();
-		for (const mixer of this.mixers) {
-			mixer.update(clock);
-		}
-
-		this.controls.update();
-		this.renderer.render(this.scene, this.camera);
-	}
-
-	@autobind
-	private renderWithPostFXs() {
-		this.renderFrameRequestId =
-			window.requestAnimationFrame(this.renderWithPostFXs);
-
-		// Update animations
-		const clock = this.clock.getDelta();
-		for (const mixer of this.mixers) {
-			mixer.update(clock);
-		}
-
-		this.controls.update();
-		this.renderer.clear();
-		this.composer.render();
-	}
-
-	@autobind
-	private loadRoom() {
-		const type = this.roomInfo.roomType;
-		new GLTFLoader().load(`/client-assets/room/rooms/${type}/${type}.glb`, gltf => {
-			gltf.scene.traverse(child => {
-				if (!(child instanceof THREE.Mesh)) return;
-
-				child.receiveShadow = this.enableShadow;
-
-				child.material = new THREE.MeshLambertMaterial({
-					color: (child.material as THREE.MeshStandardMaterial).color,
-					map: (child.material as THREE.MeshStandardMaterial).map,
-					name: (child.material as THREE.MeshStandardMaterial).name,
-				});
-
-				// 異方性フィルタリング
-				if ((child.material as THREE.MeshLambertMaterial).map && this.graphicsQuality !== 'cheep') {
-					(child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter;
-					(child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter;
-					(child.material as THREE.MeshLambertMaterial).map.anisotropy = 8;
-				}
-			});
-
-			gltf.scene.position.set(0, 0, 0);
-
-			this.scene.add(gltf.scene);
-			this.roomObj = gltf.scene;
-			if (this.roomInfo.roomType === 'default') {
-				this.applyCarpetColor();
-			}
-		});
-	}
-
-	@autobind
-	private loadFurniture(furniture: Furniture) {
-		const def = furnitureDefs.find(d => d.id === furniture.type);
-		return new Promise<GLTF>((res, rej) => {
-			const loader = new GLTFLoader();
-			loader.load(`/client-assets/room/furnitures/${furniture.type}/${furniture.type}.glb`, gltf => {
-				const model = gltf.scene;
-
-				// Load animation
-				if (gltf.animations.length > 0) {
-					const mixer = new THREE.AnimationMixer(model);
-					this.mixers.push(mixer);
-					for (const clip of gltf.animations) {
-						mixer.clipAction(clip).play();
-					}
-				}
-
-				model.name = furniture.id;
-				model.position.x = furniture.position.x;
-				model.position.y = furniture.position.y;
-				model.position.z = furniture.position.z;
-				model.rotation.x = furniture.rotation.x;
-				model.rotation.y = furniture.rotation.y;
-				model.rotation.z = furniture.rotation.z;
-
-				model.traverse(child => {
-					if (!(child instanceof THREE.Mesh)) return;
-					child.castShadow = this.enableShadow;
-					child.receiveShadow = this.enableShadow;
-					(child.material as THREE.MeshStandardMaterial).metalness = 0;
-
-					// 異方性フィルタリング
-					if ((child.material as THREE.MeshStandardMaterial).map && this.graphicsQuality !== 'cheep') {
-						(child.material as THREE.MeshStandardMaterial).map.minFilter = THREE.LinearMipMapLinearFilter;
-						(child.material as THREE.MeshStandardMaterial).map.magFilter = THREE.LinearMipMapLinearFilter;
-						(child.material as THREE.MeshStandardMaterial).map.anisotropy = 8;
-					}
-				});
-
-				if (def.color) { // カスタムカラー
-					this.applyCustomColor(model);
-				}
-
-				if (def.texture) { // カスタムテクスチャ
-					this.applyCustomTexture(model);
-				}
-
-				res(gltf);
-			}, null, rej);
-		});
-	}
-
-	@autobind
-	private applyCarpetColor() {
-		this.roomObj.traverse(child => {
-			if (!(child instanceof THREE.Mesh)) return;
-			if (child.material &&
-				(child.material as THREE.MeshStandardMaterial).name &&
-				(child.material as THREE.MeshStandardMaterial).name === 'Carpet'
-			) {
-				const colorHex = parseInt(this.roomInfo.carpetColor.substr(1), 16);
-				(child.material as THREE.MeshStandardMaterial).color.setHex(colorHex);
-			}
-		});
-	}
-
-	@autobind
-	private applyCustomColor(model: THREE.Object3D) {
-		const furniture = this.furnitures.find(furniture => furniture.id === model.name);
-		const def = furnitureDefs.find(d => d.id === furniture.type);
-		if (def.color == null) return;
-		model.traverse(child => {
-			if (!(child instanceof THREE.Mesh)) return;
-			for (const t of Object.keys(def.color)) {
-				if (!child.material ||
-					!(child.material as THREE.MeshStandardMaterial).name ||
-					(child.material as THREE.MeshStandardMaterial).name !== t
-				) continue;
-
-				const prop = def.color[t];
-				const val = furniture.props ? furniture.props[prop] : undefined;
-
-				if (val == null) continue;
-
-				const colorHex = parseInt(val.substr(1), 16);
-				(child.material as THREE.MeshStandardMaterial).color.setHex(colorHex);
-			}
-		});
-	}
-
-	@autobind
-	private applyCustomTexture(model: THREE.Object3D) {
-		const furniture = this.furnitures.find(furniture => furniture.id === model.name);
-		const def = furnitureDefs.find(d => d.id === furniture.type);
-		if (def.texture == null) return;
-
-		model.traverse(child => {
-			if (!(child instanceof THREE.Mesh)) return;
-			for (const t of Object.keys(def.texture)) {
-				if (child.name !== t) continue;
-
-				const prop = def.texture[t].prop;
-				const val = furniture.props ? furniture.props[prop] : undefined;
-
-				if (val == null) continue;
-
-				const canvas = document.createElement('canvas');
-				canvas.height = 1024;
-				canvas.width = 1024;
-
-				child.material = new THREE.MeshLambertMaterial({
-					emissive: 0x111111,
-					side: THREE.DoubleSide,
-					alphaTest: 0.5,
-				});
-
-				const img = new Image();
-				img.crossOrigin = 'anonymous';
-				img.onload = () => {
-					const uvInfo = def.texture[t].uv;
-
-					const ctx = canvas.getContext('2d');
-					ctx.drawImage(img,
-						0, 0, img.width, img.height,
-						uvInfo.x, uvInfo.y, uvInfo.width, uvInfo.height);
-
-					const texture = new THREE.Texture(canvas);
-					texture.wrapS = THREE.RepeatWrapping;
-					texture.wrapT = THREE.RepeatWrapping;
-					texture.anisotropy = 16;
-					texture.flipY = false;
-
-					(child.material as THREE.MeshLambertMaterial).map = texture;
-					(child.material as THREE.MeshLambertMaterial).needsUpdate = true;
-					(child.material as THREE.MeshLambertMaterial).map.needsUpdate = true;
-				};
-				img.src = val;
-			}
-		});
-	}
-
-	@autobind
-	private onmousemove(ev: MouseEvent) {
-		if (this.isTransformMode) return;
-
-		const rect = (ev.target as HTMLElement).getBoundingClientRect();
-		const x = ((ev.clientX - rect.left) / rect.width) * 2 - 1;
-		const y = -((ev.clientY - rect.top) / rect.height) * 2 + 1;
-		const pos = new THREE.Vector2(x, y);
-
-		this.camera.updateMatrixWorld();
-
-		const raycaster = new THREE.Raycaster();
-		raycaster.setFromCamera(pos, this.camera);
-
-		const intersects = raycaster.intersectObjects(this.objects, true);
-
-		for (const object of this.objects) {
-			if (this.isSelectedObject(object)) continue;
-			object.traverse(child => {
-				if (child instanceof THREE.Mesh) {
-					(child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000);
-				}
-			});
-		}
-
-		if (intersects.length > 0) {
-			const intersected = this.getRoot(intersects[0].object);
-			if (this.isSelectedObject(intersected)) return;
-			intersected.traverse(child => {
-				if (child instanceof THREE.Mesh) {
-					(child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919);
-				}
-			});
-		}
-	}
-
-	@autobind
-	private onmousedown(ev: MouseEvent) {
-		if (this.isTransformMode) return;
-		if (ev.target !== this.canvas || ev.button !== 0) return;
-
-		const rect = (ev.target as HTMLElement).getBoundingClientRect();
-		const x = ((ev.clientX - rect.left) / rect.width) * 2 - 1;
-		const y = -((ev.clientY - rect.top) / rect.height) * 2 + 1;
-		const pos = new THREE.Vector2(x, y);
-
-		this.camera.updateMatrixWorld();
-
-		const raycaster = new THREE.Raycaster();
-		raycaster.setFromCamera(pos, this.camera);
-
-		const intersects = raycaster.intersectObjects(this.objects, true);
-
-		for (const object of this.objects) {
-			object.traverse(child => {
-				if (child instanceof THREE.Mesh) {
-					(child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000);
-				}
-			});
-		}
-
-		if (intersects.length > 0) {
-			const selectedObj = this.getRoot(intersects[0].object);
-			this.selectFurniture(selectedObj);
-		} else {
-			this.selectedObject = null;
-			this.onChangeSelect(null);
-		}
-	}
-
-	@autobind
-	private getRoot(obj: THREE.Object3D): THREE.Object3D {
-		let found = false;
-		let x = obj.parent;
-		while (!found) {
-			if (x.parent.parent == null) {
-				found = true;
-			} else {
-				x = x.parent;
-			}
-		}
-		return x;
-	}
-
-	@autobind
-	private isSelectedObject(obj: THREE.Object3D): boolean {
-		if (this.selectedObject == null) {
-			return false;
-		} else {
-			return obj.name === this.selectedObject.name;
-		}
-	}
-
-	@autobind
-	private selectFurniture(obj: THREE.Object3D) {
-		this.selectedObject = obj;
-		this.onChangeSelect(obj);
-		obj.traverse(child => {
-			if (child instanceof THREE.Mesh) {
-				(child.material as THREE.MeshStandardMaterial).emissive.setHex(0xff0000);
-			}
-		});
-	}
-
-	/**
-	 * 家具の移動/回転モードにします
-	 * @param type 移動か回転か
-	 */
-	@autobind
-	public enterTransformMode(type: 'translate' | 'rotate') {
-		this.isTransformMode = true;
-		this.furnitureControl.setMode(type);
-		this.furnitureControl.attach(this.selectedObject);
-		this.controls.enableRotate = false;
-	}
-
-	/**
-	 * 家具の移動/回転モードを終了します
-	 */
-	@autobind
-	public exitTransformMode() {
-		this.isTransformMode = false;
-		this.furnitureControl.detach();
-		this.controls.enableRotate = true;
-	}
-
-	/**
-	 * 家具プロパティを更新します
-	 * @param key プロパティ名
-	 * @param value 値
-	 */
-	@autobind
-	public updateProp(key: string, value: any) {
-		const furniture = this.furnitures.find(furniture => furniture.id === this.selectedObject.name);
-		if (furniture.props == null) furniture.props = {};
-		furniture.props[key] = value;
-		this.applyCustomColor(this.selectedObject);
-		this.applyCustomTexture(this.selectedObject);
-	}
-
-	/**
-	 * 部屋に家具を追加します
-	 * @param type 家具の種類
-	 */
-	@autobind
-	public addFurniture(type: string) {
-		const furniture = {
-			id: uuid(),
-			type: type,
-			position: {
-				x: 0,
-				y: 0,
-				z: 0,
-			},
-			rotation: {
-				x: 0,
-				y: 0,
-				z: 0,
-			},
-		};
-
-		this.furnitures.push(furniture);
-
-		this.loadFurniture(furniture).then(obj => {
-			this.scene.add(obj.scene);
-			this.objects.push(obj.scene);
-		});
-	}
-
-	/**
-	 * 現在選択されている家具を部屋から削除します
-	 */
-	@autobind
-	public removeFurniture() {
-		this.exitTransformMode();
-		const obj = this.selectedObject;
-		this.scene.remove(obj);
-		this.objects = this.objects.filter(object => object.name !== obj.name);
-		this.furnitures = this.furnitures.filter(furniture => furniture.id !== obj.name);
-		this.selectedObject = null;
-		this.onChangeSelect(null);
-	}
-
-	/**
-	 * 全ての家具を部屋から削除します
-	 */
-	@autobind
-	public removeAllFurnitures() {
-		this.exitTransformMode();
-		for (const obj of this.objects) {
-			this.scene.remove(obj);
-		}
-		this.objects = [];
-		this.furnitures = [];
-		this.selectedObject = null;
-		this.onChangeSelect(null);
-	}
-
-	/**
-	 * 部屋の床の色を変更します
-	 * @param color 色
-	 */
-	@autobind
-	public updateCarpetColor(color: string) {
-		this.roomInfo.carpetColor = color;
-		this.applyCarpetColor();
-	}
-
-	/**
-	 * 部屋の種類を変更します
-	 * @param type 種類
-	 */
-	@autobind
-	public changeRoomType(type: string) {
-		this.roomInfo.roomType = type;
-		this.scene.remove(this.roomObj);
-		this.loadRoom();
-	}
-
-	/**
-	 * 部屋データを取得します
-	 */
-	@autobind
-	public getRoomInfo() {
-		for (const obj of this.objects) {
-			const furniture = this.furnitures.find(f => f.id === obj.name);
-			furniture.position.x = obj.position.x;
-			furniture.position.y = obj.position.y;
-			furniture.position.z = obj.position.z;
-			furniture.rotation.x = obj.rotation.x;
-			furniture.rotation.y = obj.rotation.y;
-			furniture.rotation.z = obj.rotation.z;
-		}
-
-		return this.roomInfo;
-	}
-
-	/**
-	 * 選択されている家具を取得します
-	 */
-	@autobind
-	public getSelectedObject() {
-		return this.selectedObject;
-	}
-
-	@autobind
-	public findFurnitureById(id: string) {
-		return this.furnitures.find(furniture => furniture.id === id);
-	}
-
-	/**
-	 * レンダリングを終了します
-	 */
-	@autobind
-	public destroy() {
-		// Stop render loop
-		window.cancelAnimationFrame(this.renderFrameRequestId);
-
-		this.controls.dispose();
-		this.scene.dispose();
-	}
-}
diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts
index dc9c3b7b9e..f2732c57d3 100644
--- a/packages/client/src/store.ts
+++ b/packages/client/src/store.ts
@@ -257,8 +257,6 @@ export class ColdDeviceStorage {
 		sound_channel: { type: 'syuilo/square-pico', volume: 1 },
 		sound_reversiPutBlack: { type: 'syuilo/kick', volume: 0.3 },
 		sound_reversiPutWhite: { type: 'syuilo/snare', volume: 0.3 },
-		roomGraphicsQuality: 'medium' as 'cheep' | 'low' | 'medium' | 'high' | 'ultra',
-		roomUseOrthographicCamera: true,
 	};
 
 	public static watchers = [];
diff --git a/packages/client/src/stream.ts b/packages/client/src/stream.ts
index de918e6099..dea3459b86 100644
--- a/packages/client/src/stream.ts
+++ b/packages/client/src/stream.ts
@@ -3,8 +3,6 @@ import { markRaw } from 'vue';
 import { $i } from '@/account';
 import { url } from '@/config';
 
-console.log($i.token);
-
 export const stream = markRaw(new Misskey.Stream(url, $i ? {
 	token: $i.token,
 } : null));