From bd469420fa6554db0caff17406f356761dbe1f00 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 21 Jan 2023 20:24:15 +0900
Subject: [PATCH 1/7] =?UTF-8?q?fix(client):=20=E3=82=AF=E3=83=A9=E3=82=A4?=
 =?UTF-8?q?=E3=82=A2=E3=83=B3=E3=83=88=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AB?=
 =?UTF-8?q?=E3=82=82=E8=A8=80=E8=AA=9E=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?=
 =?UTF-8?q?=E3=81=AE=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E3=82=92=E8=A1=8C?=
 =?UTF-8?q?=E3=81=86=E3=82=88=E3=81=86=E3=81=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fix #9005
---
 packages/frontend/src/init.ts          | 13 +++++++++++++
 packages/frontend/src/local-storage.ts |  1 +
 2 files changed, 14 insertions(+)

diff --git a/packages/frontend/src/init.ts b/packages/frontend/src/init.ts
index 09fb7caf14..d90d3b5532 100644
--- a/packages/frontend/src/init.ts
+++ b/packages/frontend/src/init.ts
@@ -80,6 +80,19 @@ import { claimAchievement, claimedAchievements } from './scripts/achievements';
 		});
 	}
 
+	//#region Detect language & fetch translations
+	const localeVersion = miLocalStorage.getItem('localeVersion');
+	const localeOutdated = (localeVersion == null || localeVersion !== version);
+	if (localeOutdated) {
+		const res = await window.fetch(`/assets/locales/${lang}.${version}.json`);
+		if (res.status === 200) {
+			miLocalStorage.setItem('locale', await res.text());
+			miLocalStorage.setItem('localeVersion', version);
+			location.reload();
+		}
+	}
+	//#endregion
+
 	// タッチデバイスでCSSの:hoverを機能させる
 	document.addEventListener('touchend', () => {}, { passive: true });
 
diff --git a/packages/frontend/src/local-storage.ts b/packages/frontend/src/local-storage.ts
index bb8192e980..68dc9ebe41 100644
--- a/packages/frontend/src/local-storage.ts
+++ b/packages/frontend/src/local-storage.ts
@@ -19,6 +19,7 @@ type Keys =
 	'fontSize' |
 	'ui' |
 	'locale' |
+	'localeVersion' |
 	'theme' |
 	'customCss' |
 	'message_drafts' |

From 3e112da486e59d48c415a5bd3a251148ed7312b3 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 21 Jan 2023 20:40:09 +0900
Subject: [PATCH 2/7] =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB?=
 =?UTF-8?q?=E3=81=AE=E3=82=AB=E3=82=B9=E3=82=BF=E3=83=A0=E7=B5=B5=E6=96=87?=
 =?UTF-8?q?=E5=AD=97=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=E3=81=AF=E7=9B=B4?=
 =?UTF-8?q?=E6=8E=A5=E3=82=AA=E3=83=AA=E3=82=B8=E3=83=8A=E3=83=ABURL?=
 =?UTF-8?q?=E3=81=AB=E3=83=AA=E3=82=AF=E3=82=A8=E3=82=B9=E3=83=88=E3=81=99?=
 =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/backend/src/core/entities/EmojiEntityService.ts | 6 ++++--
 packages/backend/src/models/schema/emoji.ts              | 4 ++++
 packages/backend/src/server/api/endpoints/emojis.ts      | 1 +
 packages/frontend/src/components/global/MkEmoji.vue      | 6 +++++-
 packages/frontend/src/custom-emojis.ts                   | 9 +++++++--
 5 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts
index 2a4e09519f..cee85a5688 100644
--- a/packages/backend/src/core/entities/EmojiEntityService.ts
+++ b/packages/backend/src/core/entities/EmojiEntityService.ts
@@ -22,7 +22,7 @@ export class EmojiEntityService {
 	@bindThis
 	public async pack(
 		src: Emoji['id'] | Emoji,
-		opts: { omitHost?: boolean; omitId?: boolean; } = {},
+		opts: { omitHost?: boolean; omitId?: boolean; withUrl?: boolean; } = {},
 	): Promise<Packed<'Emoji'>> {
 		const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src });
 
@@ -32,13 +32,15 @@ export class EmojiEntityService {
 			name: emoji.name,
 			category: emoji.category,
 			host: opts.omitHost ? undefined : emoji.host,
+			// ?? emoji.originalUrl してるのは後方互換性のため
+			url: opts.withUrl ? (emoji.publicUrl ?? emoji.originalUrl) : undefined,
 		};
 	}
 
 	@bindThis
 	public packMany(
 		emojis: any[],
-		opts: { omitHost?: boolean; omitId?: boolean; } = {},
+		opts: { omitHost?: boolean; omitId?: boolean; withUrl?: boolean; } = {},
 	) {
 		return Promise.all(emojis.map(x => this.pack(x, opts)));
 	}
diff --git a/packages/backend/src/models/schema/emoji.ts b/packages/backend/src/models/schema/emoji.ts
index d897a0fc05..143f25373c 100644
--- a/packages/backend/src/models/schema/emoji.ts
+++ b/packages/backend/src/models/schema/emoji.ts
@@ -29,5 +29,9 @@ export const packedEmojiSchema = {
 			optional: true, nullable: true,
 			description: 'The local host is represented with `null`.',
 		},
+		url: {
+			type: 'string',
+			optional: true, nullable: false,
+		},
 	},
 } as const;
diff --git a/packages/backend/src/server/api/endpoints/emojis.ts b/packages/backend/src/server/api/endpoints/emojis.ts
index 97dcfde596..db1eddc80a 100644
--- a/packages/backend/src/server/api/endpoints/emojis.ts
+++ b/packages/backend/src/server/api/endpoints/emojis.ts
@@ -83,6 +83,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 				emojis: await this.emojiEntityService.packMany(emojis, {
 					omitId: true,
 					omitHost: true,
+					withUrl: true,
 				}),
 			};
 		});
diff --git a/packages/frontend/src/components/global/MkEmoji.vue b/packages/frontend/src/components/global/MkEmoji.vue
index b7dd0296cd..aaad81c656 100644
--- a/packages/frontend/src/components/global/MkEmoji.vue
+++ b/packages/frontend/src/components/global/MkEmoji.vue
@@ -12,6 +12,7 @@ import { getStaticImageUrl } from '@/scripts/media-proxy';
 import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base';
 import { defaultStore } from '@/store';
 import { getEmojiName } from '@/scripts/emojilist';
+import { customEmojis } from '@/custom-emojis';
 
 const props = defineProps<{
 	emoji: string;
@@ -30,6 +31,9 @@ const useOsNativeEmojis = computed(() => defaultStore.state.emojiStyle === 'nati
 const url = computed(() => {
 	if (char.value) {
 		return char2path(char.value);
+	} else if (props.host == null) {
+		const found = customEmojis.find(x => x.name === customEmojiName);
+		return found ? found.url : null;
 	} else {
 		const rawUrl = props.host ? `/emoji/${customEmojiName}@${props.host}.webp` : `/emoji/${customEmojiName}.webp`;
 		return defaultStore.state.disableShowingAnimatedImages
@@ -38,7 +42,7 @@ const url = computed(() => {
 	}
 });
 const alt = computed(() => isCustom.value ? `:${customEmojiName}:` : char.value);
-let errored = $ref(false);
+let errored = $ref(isCustom.value && url.value == null);
 
 // Searching from an array with 2000 items for every emoji felt like too energy-consuming, so I decided to do it lazily on pointerenter
 function computeTitle(event: PointerEvent): void {
diff --git a/packages/frontend/src/custom-emojis.ts b/packages/frontend/src/custom-emojis.ts
index 19469999b6..637ee9c06e 100644
--- a/packages/frontend/src/custom-emojis.ts
+++ b/packages/frontend/src/custom-emojis.ts
@@ -2,14 +2,19 @@ import { api } from './os';
 import { miLocalStorage } from './local-storage';
 
 const storageCache = miLocalStorage.getItem('emojis');
-export let customEmojis = storageCache ? JSON.parse(storageCache) : [];
+export let customEmojis: {
+	name: string;
+	aliases: string[];
+	category: string;
+	url: string;
+}[] = storageCache ? JSON.parse(storageCache) : [];
 
 fetchCustomEmojis();
 
 export async function fetchCustomEmojis() {
 	const now = Date.now();
 	const lastFetchedAt = miLocalStorage.getItem('lastEmojisFetchedAt');
-	if (lastFetchedAt && (now - parseInt(lastFetchedAt)) < 1000 * 60 * 60) return;
+	if (lastFetchedAt && (now - parseInt(lastFetchedAt)) < 1000 * 60 * 60 * 24) return;
 
 	const res = await api('emojis', {});
 

From 307a882649691f2d816e8178a6df4a142f4932af Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 21 Jan 2023 20:53:11 +0900
Subject: [PATCH 3/7] tweak fetchCustomEmojis timing

---
 packages/frontend/src/custom-emojis.ts | 2 --
 packages/frontend/src/init.ts          | 5 +++++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/packages/frontend/src/custom-emojis.ts b/packages/frontend/src/custom-emojis.ts
index 637ee9c06e..a7ac4e03ca 100644
--- a/packages/frontend/src/custom-emojis.ts
+++ b/packages/frontend/src/custom-emojis.ts
@@ -9,8 +9,6 @@ export let customEmojis: {
 	url: string;
 }[] = storageCache ? JSON.parse(storageCache) : [];
 
-fetchCustomEmojis();
-
 export async function fetchCustomEmojis() {
 	const now = Date.now();
 	const lastFetchedAt = miLocalStorage.getItem('lastEmojisFetchedAt');
diff --git a/packages/frontend/src/init.ts b/packages/frontend/src/init.ts
index d90d3b5532..079003ee83 100644
--- a/packages/frontend/src/init.ts
+++ b/packages/frontend/src/init.ts
@@ -45,6 +45,7 @@ import { getUrlWithoutLoginId } from '@/scripts/login-id';
 import { getAccountFromId } from '@/scripts/get-account-from-id';
 import { miLocalStorage } from './local-storage';
 import { claimAchievement, claimedAchievements } from './scripts/achievements';
+import { fetchCustomEmojis } from './custom-emojis';
 
 (async () => {
 	console.info(`Misskey v${version}`);
@@ -178,6 +179,10 @@ import { claimAchievement, claimedAchievements } from './scripts/achievements';
 		initializeSw();
 	});
 
+	try {
+		await fetchCustomEmojis();
+	} catch (err) {}
+
 	const app = createApp(
 		window.location.search === '?zen' ? defineAsyncComponent(() => import('@/ui/zen.vue')) :
 		!$i ? defineAsyncComponent(() => import('@/ui/visitor.vue')) :

From a3aafa03ada6cd3fa62cff68929edcc6c23ee664 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 22 Jan 2023 04:17:58 +0900
Subject: [PATCH 4/7] update deps

---
 package.json                   |   6 +-
 packages/backend/package.json  |  20 +-
 packages/frontend/package.json |  20 +-
 pnpm-lock.yaml                 | 516 ++++++++++++++++++++++-----------
 4 files changed, 375 insertions(+), 187 deletions(-)

diff --git a/package.json b/package.json
index 25a74d4040..d30ea8eea3 100644
--- a/package.json
+++ b/package.json
@@ -54,11 +54,11 @@
 	"devDependencies": {
 		"@types/gulp": "4.0.10",
 		"@types/gulp-rename": "2.0.1",
-		"@typescript-eslint/eslint-plugin": "5.48.1",
-		"@typescript-eslint/parser": "5.48.1",
+		"@typescript-eslint/eslint-plugin": "5.48.2",
+		"@typescript-eslint/parser": "5.48.2",
 		"cross-env": "7.0.3",
 		"cypress": "12.3.0",
-		"eslint": "^8.31.0",
+		"eslint": "^8.32.0",
 		"start-server-and-test": "1.15.2"
 	},
 	"optionalDependencies": {
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 68cfbb05ad..be9012021f 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -58,9 +58,9 @@
 		"date-fns": "2.29.3",
 		"deep-email-validator": "0.1.21",
 		"escape-regexp": "0.0.1",
-		"fastify": "4.11.0",
+		"fastify": "4.12.0",
 		"feed": "4.2.2",
-		"file-type": "18.1.0",
+		"file-type": "18.2.0",
 		"fluent-ffmpeg": "2.1.2",
 		"form-data": "^4.0.0",
 		"got": "12.5.3",
@@ -89,7 +89,7 @@
 		"probe-image-size": "7.2.3",
 		"promise-limit": "2.7.0",
 		"pug": "3.0.2",
-		"punycode": "2.2.0",
+		"punycode": "2.3.0",
 		"pureimage": "0.3.15",
 		"qrcode": "1.5.1",
 		"random-seed": "0.3.0",
@@ -120,7 +120,7 @@
 		"typeorm": "0.3.11",
 		"typescript": "4.9.4",
 		"ulid": "2.3.0",
-		"undici": "^5.15.0",
+		"undici": "^5.15.1",
 		"unzipper": "0.10.11",
 		"uuid": "9.0.0",
 		"vary": "1.1.2",
@@ -132,7 +132,7 @@
 	"devDependencies": {
 		"@redocly/openapi-core": "1.0.0-beta.120",
 		"@swc/cli": "^0.1.59",
-		"@swc/core": "1.3.26",
+		"@swc/core": "1.3.27",
 		"@swc/jest": "0.2.24",
 		"@types/accepts": "1.3.5",
 		"@types/archiver": "5.3.1",
@@ -144,7 +144,7 @@
 		"@types/escape-regexp": "0.0.1",
 		"@types/fluent-ffmpeg": "2.1.20",
 		"@types/ioredis": "4.28.10",
-		"@types/jest": "29.2.5",
+		"@types/jest": "29.2.6",
 		"@types/js-yaml": "4.0.5",
 		"@types/jsdom": "20.0.1",
 		"@types/jsonld": "1.5.8",
@@ -176,11 +176,11 @@
 		"@types/web-push": "3.3.2",
 		"@types/websocket": "1.0.5",
 		"@types/ws": "8.5.4",
-		"@typescript-eslint/eslint-plugin": "5.48.1",
-		"@typescript-eslint/parser": "5.48.1",
+		"@typescript-eslint/eslint-plugin": "5.48.2",
+		"@typescript-eslint/parser": "5.48.2",
 		"cross-env": "7.0.3",
-		"eslint": "8.31.0",
-		"eslint-plugin-import": "2.27.4",
+		"eslint": "8.32.0",
+		"eslint-plugin-import": "2.27.5",
 		"execa": "6.1.0",
 		"jest": "29.3.1",
 		"jest-mock": "^29.3.1",
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index 730389a2e6..cdfa96ea82 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -8,7 +8,7 @@
 	},
 	"dependencies": {
 		"@discordapp/twemoji": "14.0.2",
-		"@rollup/plugin-alias": "4.0.2",
+		"@rollup/plugin-alias": "4.0.3",
 		"@rollup/plugin-json": "6.0.0",
 		"@rollup/pluginutils": "5.0.2",
 		"@syuilo/aiscript": "0.12.2",
@@ -18,10 +18,10 @@
 		"autobind-decorator": "2.4.0",
 		"autosize": "5.0.2",
 		"blurhash": "2.0.4",
-		"broadcast-channel": "4.20.1",
+		"broadcast-channel": "4.20.2",
 		"browser-image-resizer": "git+https://github.com/misskey-dev/browser-image-resizer#v2.2.1-misskey.3",
 		"canvas-confetti": "^1.6.0",
-		"chart.js": "4.1.2",
+		"chart.js": "4.2.0",
 		"chartjs-adapter-date-fns": "3.0.0",
 		"chartjs-chart-matrix": "^1.3.0",
 		"chartjs-plugin-gradient": "0.6.1",
@@ -41,10 +41,10 @@
 		"misskey-js": "0.0.14",
 		"photoswipe": "5.3.4",
 		"prismjs": "1.29.0",
-		"punycode": "2.2.0",
+		"punycode": "2.3.0",
 		"querystring": "0.2.1",
 		"rndstr": "1.0.0",
-		"rollup": "3.10.0",
+		"rollup": "3.10.1",
 		"s-age": "1.1.2",
 		"sanitize-html": "^2.8.1",
 		"sass": "1.57.1",
@@ -69,7 +69,7 @@
 	},
 	"devDependencies": {
 		"@types/escape-regexp": "0.0.1",
-		"@types/glob": "8.0.0",
+		"@types/glob": "8.0.1",
 		"@types/gulp": "4.0.10",
 		"@types/gulp-rename": "2.0.1",
 		"@types/matter-js": "0.18.2",
@@ -82,13 +82,13 @@
 		"@types/uuid": "9.0.0",
 		"@types/websocket": "1.0.5",
 		"@types/ws": "8.5.4",
-		"@typescript-eslint/eslint-plugin": "5.48.1",
-		"@typescript-eslint/parser": "5.48.1",
+		"@typescript-eslint/eslint-plugin": "5.48.2",
+		"@typescript-eslint/parser": "5.48.2",
 		"@vue/runtime-core": "3.2.45",
 		"cross-env": "7.0.3",
 		"cypress": "12.3.0",
-		"eslint": "8.31.0",
-		"eslint-plugin-import": "2.27.4",
+		"eslint": "8.32.0",
+		"eslint-plugin-import": "2.27.5",
 		"eslint-plugin-vue": "9.9.0",
 		"start-server-and-test": "1.15.2",
 		"vue-eslint-parser": "^9.1.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e0ffafd129..13b709bb24 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,11 +11,11 @@ importers:
       '@tensorflow/tfjs-core': ^4.2.0
       '@types/gulp': 4.0.10
       '@types/gulp-rename': 2.0.1
-      '@typescript-eslint/eslint-plugin': 5.48.1
-      '@typescript-eslint/parser': 5.48.1
+      '@typescript-eslint/eslint-plugin': 5.48.2
+      '@typescript-eslint/parser': 5.48.2
       cross-env: 7.0.3
       cypress: 12.3.0
-      eslint: ^8.31.0
+      eslint: ^8.32.0
       execa: 5.1.1
       gulp: 4.0.2
       gulp-cssnano: 2.1.3
@@ -39,11 +39,11 @@ importers:
     devDependencies:
       '@types/gulp': 4.0.10
       '@types/gulp-rename': 2.0.1
-      '@typescript-eslint/eslint-plugin': 5.48.1_3jon24igvnqaqexgwtxk6nkpse
-      '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe
+      '@typescript-eslint/eslint-plugin': 5.48.2_caon6io6stgpr7lz2rtbhekxqy
+      '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
       cross-env: 7.0.3
       cypress: 12.3.0
-      eslint: 8.31.0
+      eslint: 8.32.0
       start-server-and-test: 1.15.2
 
   packages/backend:
@@ -66,7 +66,7 @@ importers:
       '@redocly/openapi-core': 1.0.0-beta.120
       '@sinonjs/fake-timers': 10.0.2
       '@swc/cli': ^0.1.59
-      '@swc/core': 1.3.26
+      '@swc/core': 1.3.27
       '@swc/jest': 0.2.24
       '@tensorflow/tfjs': ^4.1.0
       '@tensorflow/tfjs-node': 4.1.0
@@ -80,7 +80,7 @@ importers:
       '@types/escape-regexp': 0.0.1
       '@types/fluent-ffmpeg': 2.1.20
       '@types/ioredis': 4.28.10
-      '@types/jest': 29.2.5
+      '@types/jest': 29.2.6
       '@types/js-yaml': 4.0.5
       '@types/jsdom': 20.0.1
       '@types/jsonld': 1.5.8
@@ -112,8 +112,8 @@ importers:
       '@types/web-push': 3.3.2
       '@types/websocket': 1.0.5
       '@types/ws': 8.5.4
-      '@typescript-eslint/eslint-plugin': 5.48.1
-      '@typescript-eslint/parser': 5.48.1
+      '@typescript-eslint/eslint-plugin': 5.48.2
+      '@typescript-eslint/parser': 5.48.2
       accepts: ^1.3.8
       ajv: 8.12.0
       archiver: 5.3.1
@@ -134,12 +134,12 @@ importers:
       date-fns: 2.29.3
       deep-email-validator: 0.1.21
       escape-regexp: 0.0.1
-      eslint: 8.31.0
-      eslint-plugin-import: 2.27.4
+      eslint: 8.32.0
+      eslint-plugin-import: 2.27.5
       execa: 6.1.0
-      fastify: 4.11.0
+      fastify: 4.12.0
       feed: 4.2.2
-      file-type: 18.1.0
+      file-type: 18.2.0
       fluent-ffmpeg: 2.1.2
       form-data: ^4.0.0
       got: 12.5.3
@@ -171,7 +171,7 @@ importers:
       probe-image-size: 7.2.3
       promise-limit: 2.7.0
       pug: 3.0.2
-      punycode: 2.2.0
+      punycode: 2.3.0
       pureimage: 0.3.15
       qrcode: 1.5.1
       random-seed: 0.3.0
@@ -202,7 +202,7 @@ importers:
       typeorm: 0.3.11
       typescript: 4.9.4
       ulid: 2.3.0
-      undici: ^5.15.0
+      undici: ^5.15.1
       unzipper: 0.10.11
       uuid: 9.0.0
       vary: 1.1.2
@@ -246,9 +246,9 @@ importers:
       date-fns: 2.29.3
       deep-email-validator: 0.1.21
       escape-regexp: 0.0.1
-      fastify: 4.11.0
+      fastify: 4.12.0
       feed: 4.2.2
-      file-type: 18.1.0
+      file-type: 18.2.0
       fluent-ffmpeg: 2.1.2
       form-data: 4.0.0
       got: 12.5.3
@@ -277,7 +277,7 @@ importers:
       probe-image-size: 7.2.3
       promise-limit: 2.7.0
       pug: 3.0.2
-      punycode: 2.2.0
+      punycode: 2.3.0
       pureimage: 0.3.15
       qrcode: 1.5.1
       random-seed: 0.3.0
@@ -308,7 +308,7 @@ importers:
       typeorm: 0.3.11_ioredis@4.28.5+pg@8.8.0
       typescript: 4.9.4
       ulid: 2.3.0
-      undici: 5.15.0
+      undici: 5.15.1
       unzipper: 0.10.11
       uuid: 9.0.0
       vary: 1.1.2
@@ -321,9 +321,9 @@ importers:
       '@tensorflow/tfjs-node': 4.1.0_seedrandom@3.0.5
     devDependencies:
       '@redocly/openapi-core': 1.0.0-beta.120
-      '@swc/cli': 0.1.59_cr4os3zuq4gmhe2qzzjtw2pxeu
-      '@swc/core': 1.3.26
-      '@swc/jest': 0.2.24_@swc+core@1.3.26
+      '@swc/cli': 0.1.59_2w2rsb5d2wh3txrlxuiknf4vra
+      '@swc/core': 1.3.27
+      '@swc/jest': 0.2.24_@swc+core@1.3.27
       '@types/accepts': 1.3.5
       '@types/archiver': 5.3.1
       '@types/bcryptjs': 2.4.2
@@ -334,7 +334,7 @@ importers:
       '@types/escape-regexp': 0.0.1
       '@types/fluent-ffmpeg': 2.1.20
       '@types/ioredis': 4.28.10
-      '@types/jest': 29.2.5
+      '@types/jest': 29.2.6
       '@types/js-yaml': 4.0.5
       '@types/jsdom': 20.0.1
       '@types/jsonld': 1.5.8
@@ -366,11 +366,11 @@ importers:
       '@types/web-push': 3.3.2
       '@types/websocket': 1.0.5
       '@types/ws': 8.5.4
-      '@typescript-eslint/eslint-plugin': 5.48.1_3jon24igvnqaqexgwtxk6nkpse
-      '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe
+      '@typescript-eslint/eslint-plugin': 5.48.2_caon6io6stgpr7lz2rtbhekxqy
+      '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
       cross-env: 7.0.3
-      eslint: 8.31.0
-      eslint-plugin-import: 2.27.4_qdjeohovcytra7xto5vgmxssaq
+      eslint: 8.32.0
+      eslint-plugin-import: 2.27.5_2l6piu6guil2f63lj3qmhzbnn4
       execa: 6.1.0
       jest: 29.3.1_@types+node@18.11.18
       jest-mock: 29.3.1
@@ -379,13 +379,13 @@ importers:
   packages/frontend:
     specifiers:
       '@discordapp/twemoji': 14.0.2
-      '@rollup/plugin-alias': 4.0.2
+      '@rollup/plugin-alias': 4.0.3
       '@rollup/plugin-json': 6.0.0
       '@rollup/pluginutils': 5.0.2
       '@syuilo/aiscript': 0.12.2
       '@tabler/icons': ^1.118.0
       '@types/escape-regexp': 0.0.1
-      '@types/glob': 8.0.0
+      '@types/glob': 8.0.1
       '@types/gulp': 4.0.10
       '@types/gulp-rename': 2.0.1
       '@types/matter-js': 0.18.2
@@ -398,18 +398,18 @@ importers:
       '@types/uuid': 9.0.0
       '@types/websocket': 1.0.5
       '@types/ws': 8.5.4
-      '@typescript-eslint/eslint-plugin': 5.48.1
-      '@typescript-eslint/parser': 5.48.1
+      '@typescript-eslint/eslint-plugin': 5.48.2
+      '@typescript-eslint/parser': 5.48.2
       '@vitejs/plugin-vue': 4.0.0
       '@vue/compiler-sfc': 3.2.45
       '@vue/runtime-core': 3.2.45
       autobind-decorator: 2.4.0
       autosize: 5.0.2
       blurhash: 2.0.4
-      broadcast-channel: 4.20.1
+      broadcast-channel: 4.20.2
       browser-image-resizer: git+https://github.com/misskey-dev/browser-image-resizer#v2.2.1-misskey.3
       canvas-confetti: ^1.6.0
-      chart.js: 4.1.2
+      chart.js: 4.2.0
       chartjs-adapter-date-fns: 3.0.0
       chartjs-chart-matrix: ^1.3.0
       chartjs-plugin-gradient: 0.6.1
@@ -420,8 +420,8 @@ importers:
       cypress: 12.3.0
       date-fns: 2.29.3
       escape-regexp: 0.0.1
-      eslint: 8.31.0
-      eslint-plugin-import: 2.27.4
+      eslint: 8.32.0
+      eslint-plugin-import: 2.27.5
       eslint-plugin-vue: 9.9.0
       eventemitter3: 5.0.0
       gsap: ^3.11.4
@@ -434,10 +434,10 @@ importers:
       misskey-js: 0.0.14
       photoswipe: 5.3.4
       prismjs: 1.29.0
-      punycode: 2.2.0
+      punycode: 2.3.0
       querystring: 0.2.1
       rndstr: 1.0.0
-      rollup: 3.10.0
+      rollup: 3.10.1
       s-age: 1.1.2
       sanitize-html: ^2.8.1
       sass: 1.57.1
@@ -464,9 +464,9 @@ importers:
       vuedraggable: next
     dependencies:
       '@discordapp/twemoji': 14.0.2
-      '@rollup/plugin-alias': 4.0.2_rollup@3.10.0
-      '@rollup/plugin-json': 6.0.0_rollup@3.10.0
-      '@rollup/pluginutils': 5.0.2_rollup@3.10.0
+      '@rollup/plugin-alias': 4.0.3_rollup@3.10.1
+      '@rollup/plugin-json': 6.0.0_rollup@3.10.1
+      '@rollup/pluginutils': 5.0.2_rollup@3.10.1
       '@syuilo/aiscript': 0.12.2
       '@tabler/icons': 1.119.0
       '@vitejs/plugin-vue': 4.0.0_vite@4.0.4+vue@3.2.45
@@ -474,14 +474,14 @@ importers:
       autobind-decorator: 2.4.0
       autosize: 5.0.2
       blurhash: 2.0.4
-      broadcast-channel: 4.20.1
+      broadcast-channel: 4.20.2
       browser-image-resizer: github.com/misskey-dev/browser-image-resizer/0227e860621e55cbed0aabe6dc601096a7748c4a
       canvas-confetti: 1.6.0
-      chart.js: 4.1.2
-      chartjs-adapter-date-fns: 3.0.0_kluv2ktejb2igagp3yc56zuwiy
-      chartjs-chart-matrix: 1.3.0_chart.js@4.1.2
-      chartjs-plugin-gradient: 0.6.1_chart.js@4.1.2
-      chartjs-plugin-zoom: 2.0.0_chart.js@4.1.2
+      chart.js: 4.2.0
+      chartjs-adapter-date-fns: 3.0.0_n6szoxj4ax2zhp2sxsxxj6zdla
+      chartjs-chart-matrix: 1.3.0_chart.js@4.2.0
+      chartjs-plugin-gradient: 0.6.1_chart.js@4.2.0
+      chartjs-plugin-zoom: 2.0.0_chart.js@4.2.0
       compare-versions: 5.0.1
       cropperjs: 2.0.0-beta.2
       date-fns: 2.29.3
@@ -497,10 +497,10 @@ importers:
       misskey-js: 0.0.14
       photoswipe: 5.3.4
       prismjs: 1.29.0
-      punycode: 2.2.0
+      punycode: 2.3.0
       querystring: 0.2.1
       rndstr: 1.0.0
-      rollup: 3.10.0
+      rollup: 3.10.1
       s-age: 1.1.2
       sanitize-html: 2.8.1
       sass: 1.57.1
@@ -524,7 +524,7 @@ importers:
       vuedraggable: 4.1.0_vue@3.2.45
     devDependencies:
       '@types/escape-regexp': 0.0.1
-      '@types/glob': 8.0.0
+      '@types/glob': 8.0.1
       '@types/gulp': 4.0.10
       '@types/gulp-rename': 2.0.1
       '@types/matter-js': 0.18.2
@@ -537,16 +537,16 @@ importers:
       '@types/uuid': 9.0.0
       '@types/websocket': 1.0.5
       '@types/ws': 8.5.4
-      '@typescript-eslint/eslint-plugin': 5.48.1_3jon24igvnqaqexgwtxk6nkpse
-      '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe
+      '@typescript-eslint/eslint-plugin': 5.48.2_caon6io6stgpr7lz2rtbhekxqy
+      '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
       '@vue/runtime-core': 3.2.45
       cross-env: 7.0.3
       cypress: 12.3.0
-      eslint: 8.31.0
-      eslint-plugin-import: 2.27.4_qdjeohovcytra7xto5vgmxssaq
-      eslint-plugin-vue: 9.9.0_eslint@8.31.0
+      eslint: 8.32.0
+      eslint-plugin-import: 2.27.5_2l6piu6guil2f63lj3qmhzbnn4
+      eslint-plugin-vue: 9.9.0_eslint@8.32.0
       start-server-and-test: 1.15.2
-      vue-eslint-parser: 9.1.0_eslint@8.31.0
+      vue-eslint-parser: 9.1.0_eslint@8.32.0
       vue-tsc: 1.0.24_typescript@4.9.4
 
   packages/sw:
@@ -1077,7 +1077,7 @@ packages:
     dependencies:
       ky: 0.30.0
       ky-universal: 0.10.1_ky@0.30.0
-      undici: 5.15.0
+      undici: 5.15.1
     transitivePeerDependencies:
       - web-streams-polyfill
     dev: false
@@ -1402,7 +1402,7 @@ packages:
       fastify-plugin: 4.5.0
       pump: 3.0.0
       tiny-lru: 10.0.1
-      undici: 5.15.0
+      undici: 5.15.1
     dev: false
 
   /@fastify/send/1.0.0:
@@ -2059,8 +2059,8 @@ packages:
       - encoding
     dev: true
 
-  /@rollup/plugin-alias/4.0.2_rollup@3.10.0:
-    resolution: {integrity: sha512-1hv7dBOZZwo3SEupxn4UA2N0EDThqSSS+wI1St1TNTBtOZvUchyIClyHcnDcjjrReTPZ47Faedrhblv4n+T5UQ==}
+  /@rollup/plugin-alias/4.0.3_rollup@3.10.1:
+    resolution: {integrity: sha512-ZuDWE1q4PQDhvm/zc5Prun8sBpLJy41DMptYrS6MhAy9s9kL/doN1613BWfEchGVfKxzliJ3BjbOPizXX38DbQ==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
       rollup: ^1.20.0||^2.0.0||^3.0.0
@@ -2068,11 +2068,11 @@ packages:
       rollup:
         optional: true
     dependencies:
-      rollup: 3.10.0
+      rollup: 3.10.1
       slash: 4.0.0
     dev: false
 
-  /@rollup/plugin-json/6.0.0_rollup@3.10.0:
+  /@rollup/plugin-json/6.0.0_rollup@3.10.1:
     resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -2081,11 +2081,11 @@ packages:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.2_rollup@3.10.0
-      rollup: 3.10.0
+      '@rollup/pluginutils': 5.0.2_rollup@3.10.1
+      rollup: 3.10.1
     dev: false
 
-  /@rollup/pluginutils/5.0.2_rollup@3.10.0:
+  /@rollup/pluginutils/5.0.2_rollup@3.10.1:
     resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -2097,7 +2097,7 @@ packages:
       '@types/estree': 1.0.0
       estree-walker: 2.0.2
       picomatch: 2.3.1
-      rollup: 3.10.0
+      rollup: 3.10.1
     dev: false
 
   /@sideway/address/4.1.4:
@@ -2161,7 +2161,7 @@ packages:
     resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==}
     dev: false
 
-  /@swc/cli/0.1.59_cr4os3zuq4gmhe2qzzjtw2pxeu:
+  /@swc/cli/0.1.59_2w2rsb5d2wh3txrlxuiknf4vra:
     resolution: {integrity: sha512-BlX3wIxYTwdtR22dIqZ3FEIOJPqnlByAp4JY46OMZi2UXMB3ZbOzefawD2ZlLafRUWyy5NtiZZty5waKzaYRnA==}
     engines: {node: '>= 12.13'}
     hasBin: true
@@ -2172,7 +2172,7 @@ packages:
       chokidar:
         optional: true
     dependencies:
-      '@swc/core': 1.3.26
+      '@swc/core': 1.3.27
       bin-wrapper: 4.1.0
       chokidar: 3.5.3
       commander: 7.2.0
@@ -2182,8 +2182,8 @@ packages:
       source-map: 0.7.4
     dev: true
 
-  /@swc/core-darwin-arm64/1.3.26:
-    resolution: {integrity: sha512-FWWflBfKRYrUJtko2xiedC5XCa31O75IZZqnTWuLpe9g3C5tnUuF3M8LSXZS/dn6wprome1MhtG9GMPkSYkhkg==}
+  /@swc/core-darwin-arm64/1.3.27:
+    resolution: {integrity: sha512-IKlxkhEy99CnP9nduaf5IJWIFcr6D5cZCjYmCs7nWkjMV+aAieyDO9AX4LT8AcHy6CF7ByOX7SKoqk+gVMAaKw==}
     engines: {node: '>=10'}
     cpu: [arm64]
     os: [darwin]
@@ -2191,8 +2191,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-darwin-x64/1.3.26:
-    resolution: {integrity: sha512-0uQeebAtsewqJ2b35aPZstGrylwd6oJjUyAJOfVJNbremFSJ5JzytB3NoDCIw7CT5UQrSRpvD3mU95gfdQjDGA==}
+  /@swc/core-darwin-x64/1.3.27:
+    resolution: {integrity: sha512-MtabZIhFf/dL3vs6UMbd+vJsjIkm2NaFqulGV0Jofy2bfVZPTj/b5pXeOlUsTWy7JcH1uixjdx4RvJRyvqJxQA==}
     engines: {node: '>=10'}
     cpu: [x64]
     os: [darwin]
@@ -2200,8 +2200,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-linux-arm-gnueabihf/1.3.26:
-    resolution: {integrity: sha512-06T+LbVFlyciQtwrUB5/a16A1ju1jFoYvd/hq9TWhf7GrtL43U7oJIgqMOPHx2j0+Ps2R3S6R/UUN5YXu618zA==}
+  /@swc/core-linux-arm-gnueabihf/1.3.27:
+    resolution: {integrity: sha512-XELMoGcUTAkk+G4buwIIhu6AIr1U418Odt22HUW8+ZvV+Wty2ICgR/myOIhM3xMb6U2L8ay+evMqoVNMQ0RRTg==}
     engines: {node: '>=10'}
     cpu: [arm]
     os: [linux]
@@ -2209,8 +2209,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-linux-arm64-gnu/1.3.26:
-    resolution: {integrity: sha512-2NT/0xALPfK+U01qIlHxjkGdIj6F0txhu1U2v6B0YP2+k0whL2gCgYeg9QUvkYEXSD5r1Yx+vcb2R/vaSCSClg==}
+  /@swc/core-linux-arm64-gnu/1.3.27:
+    resolution: {integrity: sha512-O6vtT6bnrVR9PzEIuA5U7tIfYo7bv97H9K9Vqy2oyHNeGN0H36DKwS4UqPreHtziXNF5+7ubdUYUkrG/j8UnUQ==}
     engines: {node: '>=10'}
     cpu: [arm64]
     os: [linux]
@@ -2218,8 +2218,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-linux-arm64-musl/1.3.26:
-    resolution: {integrity: sha512-64KrTay9hC0mTvZ1AmEFmNEwV5QDjw9U7PJU5riotSc28I+Q/ZoM0qcSFW9JRRa6F2Tr+IfMtyv8+eB2//BQ5g==}
+  /@swc/core-linux-arm64-musl/1.3.27:
+    resolution: {integrity: sha512-Oa0E1i7dOTWpaEZumKoNbTE/Ap+da6nlhqKVUdYrFDrOBi25tz76SdxZIyvAszzmgY89b5yd1naourKmkPXpww==}
     engines: {node: '>=10'}
     cpu: [arm64]
     os: [linux]
@@ -2227,8 +2227,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-linux-x64-gnu/1.3.26:
-    resolution: {integrity: sha512-Te8G13l3dcRM1Mf3J4JzGUngzNXLKnMYlUmBOYN/ORsx7e+VNelR3zsTLHC0+0jGqELDgqvMyzDfk+dux/C/bQ==}
+  /@swc/core-linux-x64-gnu/1.3.27:
+    resolution: {integrity: sha512-S3v9H8oL2a8Ur6AjQyhkC6HfBVPOxKMdBhcZmdNuVgEUHbHdbf/Lka85F9IOYXEarMn0FtQw3ywowS22O9L5Uw==}
     engines: {node: '>=10'}
     cpu: [x64]
     os: [linux]
@@ -2236,8 +2236,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-linux-x64-musl/1.3.26:
-    resolution: {integrity: sha512-nqQWuSM6OTKepUiQ9+rXgERq/JiO72RBOpXKO2afYppsL96sngjIRewV74v5f6IAfyzw+k+AhC5pgRA4Xu/Jkg==}
+  /@swc/core-linux-x64-musl/1.3.27:
+    resolution: {integrity: sha512-6DDkdXlOADpwICFZTRphCR+cIeS8aEYh4NlyzBito0mOWwIIdfCgALzhkTQOzTOkcD42bP97CIoZ97hqV/puOg==}
     engines: {node: '>=10'}
     cpu: [x64]
     os: [linux]
@@ -2245,8 +2245,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-win32-arm64-msvc/1.3.26:
-    resolution: {integrity: sha512-xx34mx+9IBV1sun7sxoNFiqNom9wiOuvsQFJUyQptCnZHgYwOr9OI204LBF95dCcBCZsTm2hT1wBnySJOeimYw==}
+  /@swc/core-win32-arm64-msvc/1.3.27:
+    resolution: {integrity: sha512-baxfH4AbEcaTNo08wxV0W6hiMXwVCxPS4qc0amHpXPti92unvSqeDR1W3C9GjHqzXlWtmCRsq8Ww1pal6ZVLrw==}
     engines: {node: '>=10'}
     cpu: [arm64]
     os: [win32]
@@ -2254,8 +2254,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-win32-ia32-msvc/1.3.26:
-    resolution: {integrity: sha512-48LZ/HKNuU9zl8c7qG6IQKb5rBCwmJgysGOmEGzTRBYxAf/x6Scmt0aqxCoV4J02HOs2WduCBDnhUKsSQ2kcXQ==}
+  /@swc/core-win32-ia32-msvc/1.3.27:
+    resolution: {integrity: sha512-7iLJnH71k5qCwxv9NcM/P7nIEzTsC7r1sIiQW6bu+CpC8qZvwl0PS+XvQRlLly2gCZM+Le98tksYG14MEh+Hrw==}
     engines: {node: '>=10'}
     cpu: [ia32]
     os: [win32]
@@ -2263,8 +2263,8 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core-win32-x64-msvc/1.3.26:
-    resolution: {integrity: sha512-UPe7S+MezD/S6cKBIc50TduGzmw6PBz1Ms5p+5wDLOKYNS/LSEM4iRmLwvePzP5X8mOyesXrsbwxLy8KHP65Yw==}
+  /@swc/core-win32-x64-msvc/1.3.27:
+    resolution: {integrity: sha512-mFM907PDw/jrQ44+TRjIVGEOy2Mu06mMMz0HPMFuRsBzl5t0Kajp3vmn8FkkpS9wH5982VPi6hPYVTb7QJo5Qg==}
     engines: {node: '>=10'}
     cpu: [x64]
     os: [win32]
@@ -2272,31 +2272,31 @@ packages:
     dev: true
     optional: true
 
-  /@swc/core/1.3.26:
-    resolution: {integrity: sha512-U7vEsaLn3IGg0XCRLJX/GTkK9WIfFHUX5USdrp1L2QD29sWPe25HqNndXmUR9KytzKmpDMNoUuHyiuhpVrnNeQ==}
+  /@swc/core/1.3.27:
+    resolution: {integrity: sha512-praRNgpeYGvwDIm/Cl6JU+yHMvwVraL0U6ejMgGyzvpcm1FVsZd1/EYXGqzbBJ0ALv7Gx4eK56h4GnwV6d4L0w==}
     engines: {node: '>=10'}
     requiresBuild: true
     optionalDependencies:
-      '@swc/core-darwin-arm64': 1.3.26
-      '@swc/core-darwin-x64': 1.3.26
-      '@swc/core-linux-arm-gnueabihf': 1.3.26
-      '@swc/core-linux-arm64-gnu': 1.3.26
-      '@swc/core-linux-arm64-musl': 1.3.26
-      '@swc/core-linux-x64-gnu': 1.3.26
-      '@swc/core-linux-x64-musl': 1.3.26
-      '@swc/core-win32-arm64-msvc': 1.3.26
-      '@swc/core-win32-ia32-msvc': 1.3.26
-      '@swc/core-win32-x64-msvc': 1.3.26
+      '@swc/core-darwin-arm64': 1.3.27
+      '@swc/core-darwin-x64': 1.3.27
+      '@swc/core-linux-arm-gnueabihf': 1.3.27
+      '@swc/core-linux-arm64-gnu': 1.3.27
+      '@swc/core-linux-arm64-musl': 1.3.27
+      '@swc/core-linux-x64-gnu': 1.3.27
+      '@swc/core-linux-x64-musl': 1.3.27
+      '@swc/core-win32-arm64-msvc': 1.3.27
+      '@swc/core-win32-ia32-msvc': 1.3.27
+      '@swc/core-win32-x64-msvc': 1.3.27
     dev: true
 
-  /@swc/jest/0.2.24_@swc+core@1.3.26:
+  /@swc/jest/0.2.24_@swc+core@1.3.27:
     resolution: {integrity: sha512-fwgxQbM1wXzyKzl1+IW0aGrRvAA8k0Y3NxFhKigbPjOJ4mCKnWEcNX9HQS3gshflcxq8YKhadabGUVfdwjCr6Q==}
     engines: {npm: '>= 7.0.0'}
     peerDependencies:
       '@swc/core': '*'
     dependencies:
       '@jest/create-cache-key-function': 27.5.1
-      '@swc/core': 1.3.26
+      '@swc/core': 1.3.27
       jsonc-parser: 3.2.0
     dev: true
 
@@ -2583,7 +2583,7 @@ packages:
   /@types/glob-stream/6.1.1:
     resolution: {integrity: sha512-AGOUTsTdbPkRS0qDeyeS+6KypmfVpbT5j23SN8UPG63qjKXNKjXn6V9wZUr8Fin0m9l8oGYaPK8b2WUMF8xI1A==}
     dependencies:
-      '@types/glob': 8.0.0
+      '@types/glob': 8.0.1
       '@types/node': 18.11.18
     dev: true
 
@@ -2594,6 +2594,13 @@ packages:
       '@types/node': 18.11.18
     dev: true
 
+  /@types/glob/8.0.1:
+    resolution: {integrity: sha512-8bVUjXZvJacUFkJXHdyZ9iH1Eaj5V7I8c4NdH5sQJsdXkqT4CA5Dhb4yb4VE/3asyx4L9ayZr1NIhTsWHczmMw==}
+    dependencies:
+      '@types/minimatch': 5.1.2
+      '@types/node': 18.11.18
+    dev: true
+
   /@types/graceful-fs/4.1.6:
     resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==}
     dependencies:
@@ -2641,8 +2648,8 @@ packages:
       '@types/istanbul-lib-report': 3.0.0
     dev: true
 
-  /@types/jest/29.2.5:
-    resolution: {integrity: sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==}
+  /@types/jest/29.2.6:
+    resolution: {integrity: sha512-XEUC/Tgw3uMh6Ho8GkUtQ2lPhY5Fmgyp3TdlkTJs1W9VgNxs+Ow/x3Elh8lHQKqCbZL0AubQuqWjHVT033Hhrw==}
     dependencies:
       expect: 29.3.1
       pretty-format: 29.3.1
@@ -2949,8 +2956,8 @@ packages:
     dev: true
     optional: true
 
-  /@typescript-eslint/eslint-plugin/5.48.1_3jon24igvnqaqexgwtxk6nkpse:
-    resolution: {integrity: sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==}
+  /@typescript-eslint/eslint-plugin/5.48.2_caon6io6stgpr7lz2rtbhekxqy:
+    resolution: {integrity: sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       '@typescript-eslint/parser': ^5.0.0
@@ -2960,13 +2967,13 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe
-      '@typescript-eslint/scope-manager': 5.48.1
-      '@typescript-eslint/type-utils': 5.48.1_iukboom6ndih5an6iafl45j2fe
-      '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe
+      '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
+      '@typescript-eslint/scope-manager': 5.48.2
+      '@typescript-eslint/type-utils': 5.48.2_7uibuqfxkfaozanbtbziikiqje
+      '@typescript-eslint/utils': 5.48.2_7uibuqfxkfaozanbtbziikiqje
       debug: 4.3.4
-      eslint: 8.31.0
-      ignore: 5.2.1
+      eslint: 8.32.0
+      ignore: 5.2.4
       natural-compare-lite: 1.4.0
       regexpp: 3.2.0
       semver: 7.3.8
@@ -2996,6 +3003,26 @@ packages:
       - supports-color
     dev: true
 
+  /@typescript-eslint/parser/5.48.2_7uibuqfxkfaozanbtbziikiqje:
+    resolution: {integrity: sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/scope-manager': 5.48.2
+      '@typescript-eslint/types': 5.48.2
+      '@typescript-eslint/typescript-estree': 5.48.2_typescript@4.9.4
+      debug: 4.3.4
+      eslint: 8.32.0
+      typescript: 4.9.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@typescript-eslint/scope-manager/5.48.1:
     resolution: {integrity: sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -3004,8 +3031,16 @@ packages:
       '@typescript-eslint/visitor-keys': 5.48.1
     dev: true
 
-  /@typescript-eslint/type-utils/5.48.1_iukboom6ndih5an6iafl45j2fe:
-    resolution: {integrity: sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==}
+  /@typescript-eslint/scope-manager/5.48.2:
+    resolution: {integrity: sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dependencies:
+      '@typescript-eslint/types': 5.48.2
+      '@typescript-eslint/visitor-keys': 5.48.2
+    dev: true
+
+  /@typescript-eslint/type-utils/5.48.2_7uibuqfxkfaozanbtbziikiqje:
+    resolution: {integrity: sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '*'
@@ -3014,10 +3049,10 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
-      '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe
+      '@typescript-eslint/typescript-estree': 5.48.2_typescript@4.9.4
+      '@typescript-eslint/utils': 5.48.2_7uibuqfxkfaozanbtbziikiqje
       debug: 4.3.4
-      eslint: 8.31.0
+      eslint: 8.32.0
       tsutils: 3.21.0_typescript@4.9.4
       typescript: 4.9.4
     transitivePeerDependencies:
@@ -3029,6 +3064,11 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
+  /@typescript-eslint/types/5.48.2:
+    resolution: {integrity: sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dev: true
+
   /@typescript-eslint/typescript-estree/5.48.1_typescript@4.9.4:
     resolution: {integrity: sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -3050,20 +3090,41 @@ packages:
       - supports-color
     dev: true
 
-  /@typescript-eslint/utils/5.48.1_iukboom6ndih5an6iafl45j2fe:
-    resolution: {integrity: sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==}
+  /@typescript-eslint/typescript-estree/5.48.2_typescript@4.9.4:
+    resolution: {integrity: sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/types': 5.48.2
+      '@typescript-eslint/visitor-keys': 5.48.2
+      debug: 4.3.4
+      globby: 11.1.0
+      is-glob: 4.0.3
+      semver: 7.3.8
+      tsutils: 3.21.0_typescript@4.9.4
+      typescript: 4.9.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/utils/5.48.2_7uibuqfxkfaozanbtbziikiqje:
+    resolution: {integrity: sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
       '@types/json-schema': 7.0.11
       '@types/semver': 7.3.13
-      '@typescript-eslint/scope-manager': 5.48.1
-      '@typescript-eslint/types': 5.48.1
-      '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
-      eslint: 8.31.0
+      '@typescript-eslint/scope-manager': 5.48.2
+      '@typescript-eslint/types': 5.48.2
+      '@typescript-eslint/typescript-estree': 5.48.2_typescript@4.9.4
+      eslint: 8.32.0
       eslint-scope: 5.1.1
-      eslint-utils: 3.0.0_eslint@8.31.0
+      eslint-utils: 3.0.0_eslint@8.32.0
       semver: 7.3.8
     transitivePeerDependencies:
       - supports-color
@@ -3078,6 +3139,14 @@ packages:
       eslint-visitor-keys: 3.3.0
     dev: true
 
+  /@typescript-eslint/visitor-keys/5.48.2:
+    resolution: {integrity: sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dependencies:
+      '@typescript-eslint/types': 5.48.2
+      eslint-visitor-keys: 3.3.0
+    dev: true
+
   /@vitejs/plugin-vue/4.0.0_vite@4.0.4+vue@3.2.45:
     resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==}
     engines: {node: ^14.18.0 || >=16.0.0}
@@ -4039,8 +4108,8 @@ packages:
     dependencies:
       fill-range: 7.0.1
 
-  /broadcast-channel/4.20.1:
-    resolution: {integrity: sha512-ob5xyUEMWJRBOggwVGEZpKCXK/Pkfe3LkrokNTwgywhKXFNETRkD5IanLqmpY/roy7bqBsijb7lMEDyc1qlnHQ==}
+  /broadcast-channel/4.20.2:
+    resolution: {integrity: sha512-v0lJgMzC+MX4e2KCFWYXChZ2mKTqm5mnJGId6tqJp3NfylggbNd8c2uKeP4MQxD2ucKOesY68aN98zwl9d6Tvg==}
     dependencies:
       '@babel/runtime': 7.20.7
       oblivious-set: 1.1.1
@@ -4403,45 +4472,45 @@ packages:
       is-regex: 1.1.4
     dev: false
 
-  /chart.js/4.1.2:
-    resolution: {integrity: sha512-9L1w6WLPq6ztiWVVOYtDtpo0CUsBKDWPrUEdwChAyzczaikqeSwNKEv3QpJ7EO4ICcLSi6UDVhgvcnUhRJidRA==}
+  /chart.js/4.2.0:
+    resolution: {integrity: sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==}
     engines: {pnpm: ^7.0.0}
     dependencies:
       '@kurkle/color': 0.3.2
     dev: false
 
-  /chartjs-adapter-date-fns/3.0.0_kluv2ktejb2igagp3yc56zuwiy:
+  /chartjs-adapter-date-fns/3.0.0_n6szoxj4ax2zhp2sxsxxj6zdla:
     resolution: {integrity: sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg==}
     peerDependencies:
       chart.js: '>=2.8.0'
       date-fns: '>=2.0.0'
     dependencies:
-      chart.js: 4.1.2
+      chart.js: 4.2.0
       date-fns: 2.29.3
     dev: false
 
-  /chartjs-chart-matrix/1.3.0_chart.js@4.1.2:
+  /chartjs-chart-matrix/1.3.0_chart.js@4.2.0:
     resolution: {integrity: sha512-oPmyxY60tJDBFbnhXcmcJujs+F1a2uMvb9HOhSeV2/5k8L9LApWtyRJzwNWawMl8vDbWdhAfobq06b4AcdwE3Q==}
     peerDependencies:
       chart.js: '>=3.0.0'
     dependencies:
-      chart.js: 4.1.2
+      chart.js: 4.2.0
     dev: false
 
-  /chartjs-plugin-gradient/0.6.1_chart.js@4.1.2:
+  /chartjs-plugin-gradient/0.6.1_chart.js@4.2.0:
     resolution: {integrity: sha512-TGHNIh8KqQMLdb+UfY80cBHYRyOC47eeokmgkeajRdKGbFt462lJiyiq4ZJ25fiM7BGsmzoBLhmVyEw4B3gQxw==}
     peerDependencies:
       chart.js: '>=2.6.0'
     dependencies:
-      chart.js: 4.1.2
+      chart.js: 4.2.0
     dev: false
 
-  /chartjs-plugin-zoom/2.0.0_chart.js@4.1.2:
+  /chartjs-plugin-zoom/2.0.0_chart.js@4.2.0:
     resolution: {integrity: sha512-bqpi7DGy9a5hX7ThKl/xQaLzXvneSwhS0w/lNimZ8AJaoRVMKz5JfUoqwciJYV5ixKXJbgyvwC9HcJnyVsYmjg==}
     peerDependencies:
       chart.js: '>=3.2.0'
     dependencies:
-      chart.js: 4.1.2
+      chart.js: 4.2.0
       hammerjs: 2.0.8
     dev: false
 
@@ -6040,6 +6109,35 @@ packages:
       - supports-color
     dev: true
 
+  /eslint-module-utils/2.7.4_kvyj4idustix6trhy5lyssy2sq:
+    resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@typescript-eslint/parser': '*'
+      eslint: '*'
+      eslint-import-resolver-node: '*'
+      eslint-import-resolver-typescript: '*'
+      eslint-import-resolver-webpack: '*'
+    peerDependenciesMeta:
+      '@typescript-eslint/parser':
+        optional: true
+      eslint:
+        optional: true
+      eslint-import-resolver-node:
+        optional: true
+      eslint-import-resolver-typescript:
+        optional: true
+      eslint-import-resolver-webpack:
+        optional: true
+    dependencies:
+      '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
+      debug: 3.2.7
+      eslint: 8.32.0
+      eslint-import-resolver-node: 0.3.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /eslint-module-utils/2.7.4_sqt5xxn4ciiurbqrzlaarm6ama:
     resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
     engines: {node: '>=4'}
@@ -6102,19 +6200,52 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-plugin-vue/9.9.0_eslint@8.31.0:
+  /eslint-plugin-import/2.27.5_2l6piu6guil2f63lj3qmhzbnn4:
+    resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@typescript-eslint/parser': '*'
+      eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+    peerDependenciesMeta:
+      '@typescript-eslint/parser':
+        optional: true
+    dependencies:
+      '@typescript-eslint/parser': 5.48.2_7uibuqfxkfaozanbtbziikiqje
+      array-includes: 3.1.6
+      array.prototype.flat: 1.3.1
+      array.prototype.flatmap: 1.3.1
+      debug: 3.2.7
+      doctrine: 2.1.0
+      eslint: 8.32.0
+      eslint-import-resolver-node: 0.3.7
+      eslint-module-utils: 2.7.4_kvyj4idustix6trhy5lyssy2sq
+      has: 1.0.3
+      is-core-module: 2.11.0
+      is-glob: 4.0.3
+      minimatch: 3.1.2
+      object.values: 1.1.6
+      resolve: 1.22.1
+      semver: 6.3.0
+      tsconfig-paths: 3.14.1
+    transitivePeerDependencies:
+      - eslint-import-resolver-typescript
+      - eslint-import-resolver-webpack
+      - supports-color
+    dev: true
+
+  /eslint-plugin-vue/9.9.0_eslint@8.32.0:
     resolution: {integrity: sha512-YbubS7eK0J7DCf0U2LxvVP7LMfs6rC6UltihIgval3azO3gyDwEGVgsCMe1TmDiEkl6GdMKfRpaME6QxIYtzDQ==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      eslint: 8.31.0
-      eslint-utils: 3.0.0_eslint@8.31.0
+      eslint: 8.32.0
+      eslint-utils: 3.0.0_eslint@8.32.0
       natural-compare: 1.4.0
       nth-check: 2.1.1
       postcss-selector-parser: 6.0.11
       semver: 7.3.8
-      vue-eslint-parser: 9.1.0_eslint@8.31.0
+      vue-eslint-parser: 9.1.0_eslint@8.32.0
       xml-name-validator: 4.0.0
     transitivePeerDependencies:
       - supports-color
@@ -6146,6 +6277,16 @@ packages:
       eslint-visitor-keys: 2.1.0
     dev: true
 
+  /eslint-utils/3.0.0_eslint@8.32.0:
+    resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
+    engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
+    peerDependencies:
+      eslint: '>=5'
+    dependencies:
+      eslint: 8.32.0
+      eslint-visitor-keys: 2.1.0
+    dev: true
+
   /eslint-visitor-keys/2.1.0:
     resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
     engines: {node: '>=10'}
@@ -6204,6 +6345,54 @@ packages:
       - supports-color
     dev: true
 
+  /eslint/8.32.0:
+    resolution: {integrity: sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    hasBin: true
+    dependencies:
+      '@eslint/eslintrc': 1.4.1
+      '@humanwhocodes/config-array': 0.11.8
+      '@humanwhocodes/module-importer': 1.0.1
+      '@nodelib/fs.walk': 1.2.8
+      ajv: 6.12.6
+      chalk: 4.1.2
+      cross-spawn: 7.0.3
+      debug: 4.3.4
+      doctrine: 3.0.0
+      escape-string-regexp: 4.0.0
+      eslint-scope: 7.1.1
+      eslint-utils: 3.0.0_eslint@8.32.0
+      eslint-visitor-keys: 3.3.0
+      espree: 9.4.1
+      esquery: 1.4.0
+      esutils: 2.0.3
+      fast-deep-equal: 3.1.3
+      file-entry-cache: 6.0.1
+      find-up: 5.0.0
+      glob-parent: 6.0.2
+      globals: 13.19.0
+      grapheme-splitter: 1.0.4
+      ignore: 5.2.4
+      import-fresh: 3.3.0
+      imurmurhash: 0.1.4
+      is-glob: 4.0.3
+      is-path-inside: 3.0.3
+      js-sdsl: 4.2.0
+      js-yaml: 4.1.0
+      json-stable-stringify-without-jsonify: 1.0.1
+      levn: 0.4.1
+      lodash.merge: 4.6.2
+      minimatch: 3.1.2
+      natural-compare: 1.4.0
+      optionator: 0.9.1
+      regexpp: 3.2.0
+      strip-ansi: 6.0.1
+      strip-json-comments: 3.1.1
+      text-table: 0.2.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /espree/9.4.1:
     resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -6501,6 +6690,10 @@ packages:
       time-stamp: 1.1.0
     dev: false
 
+  /fast-content-type-parse/1.0.0:
+    resolution: {integrity: sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==}
+    dev: false
+
   /fast-decode-uri-component/1.0.1:
     resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
     dev: false
@@ -6569,15 +6762,15 @@ packages:
     resolution: {integrity: sha512-79ak0JxddO0utAXAQ5ccKhvs6vX2MGyHHMMsmZkBANrq3hXc1CHzvNPHOcvTsVMEPl5I+NT+RO4YKMGehOfSIg==}
     dev: false
 
-  /fastify/4.11.0:
-    resolution: {integrity: sha512-JteZ8pjEqd+6n+azQnQfSJV8MUMxAmxbvC2Dx/Mybj039Lf/u3kda9Kq84uy/huCpqCzZoyHIZS5JFGF3wLztw==}
+  /fastify/4.12.0:
+    resolution: {integrity: sha512-Hh2GCsOCqnOuewWSvqXlpq5V/9VA+/JkVoooQWUhrU6gryO9+/UGOoF/dprGcKSDxkM/9TkMXSffYp8eA/YhYQ==}
     dependencies:
       '@fastify/ajv-compiler': 3.5.0
       '@fastify/error': 3.2.0
       '@fastify/fast-json-stringify-compiler': 4.2.0
       abstract-logging: 2.0.1
       avvio: 8.2.0
-      content-type: 1.0.4
+      fast-content-type-parse: 1.0.0
       find-my-way: 7.4.0
       light-my-request: 5.8.0
       pino: 8.8.0
@@ -6636,8 +6829,8 @@ packages:
       flat-cache: 3.0.4
     dev: true
 
-  /file-type/18.1.0:
-    resolution: {integrity: sha512-FqjmVvHjX5C/EnibCENAsCMIg7HgUYO0vDypt5V8RmtKDk7eUa+/6mEWSrY4PStFhUt0K3CoE8stjLJCcMsJFQ==}
+  /file-type/18.2.0:
+    resolution: {integrity: sha512-M3RQMWY3F2ykyWZ+IHwNCjpnUmukYhtdkGGC1ZVEUb0ve5REGF7NNJ4Q9ehCUabtQKtSVFOMbFTXgJlFb0DQIg==}
     engines: {node: '>=14.16'}
     dependencies:
       readable-web-to-node-stream: 3.0.2
@@ -7778,11 +7971,6 @@ packages:
   /ieee754/1.2.1:
     resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
 
-  /ignore/5.2.1:
-    resolution: {integrity: sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==}
-    engines: {node: '>= 4'}
-    dev: true
-
   /ignore/5.2.4:
     resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
     engines: {node: '>= 4'}
@@ -11415,8 +11603,8 @@ packages:
     resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==}
     dev: false
 
-  /punycode/2.2.0:
-    resolution: {integrity: sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==}
+  /punycode/2.3.0:
+    resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
     engines: {node: '>=6'}
 
   /pureimage/0.3.15:
@@ -11971,8 +12159,8 @@ packages:
       seedrandom: 2.4.2
     dev: false
 
-  /rollup/3.10.0:
-    resolution: {integrity: sha512-JmRYz44NjC1MjVF2VKxc0M1a97vn+cDxeqWmnwyAF4FvpjK8YFdHpaqvQB+3IxCvX05vJxKZkoMDU8TShhmJVA==}
+  /rollup/3.10.1:
+    resolution: {integrity: sha512-3Er+yel3bZbZX1g2kjVM+FW+RUWDxbG87fcqFM5/9HbPCTpbVp6JOLn7jlxnNlbu7s/N/uDA4EV/91E2gWnxzw==}
     engines: {node: '>=14.18.0', npm: '>=8.0.0'}
     hasBin: true
     optionalDependencies:
@@ -13065,14 +13253,14 @@ packages:
     engines: {node: '>=0.8'}
     dependencies:
       psl: 1.9.0
-      punycode: 2.2.0
+      punycode: 2.3.0
 
   /tough-cookie/4.1.2:
     resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==}
     engines: {node: '>=6'}
     dependencies:
       psl: 1.9.0
-      punycode: 2.2.0
+      punycode: 2.3.0
       universalify: 0.2.0
       url-parse: 1.5.10
     dev: false
@@ -13084,7 +13272,7 @@ packages:
     resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==}
     engines: {node: '>=12'}
     dependencies:
-      punycode: 2.2.0
+      punycode: 2.3.0
     dev: false
 
   /trace-redirect/1.0.6:
@@ -13353,8 +13541,8 @@ packages:
       undertaker-registry: 1.0.1
     dev: false
 
-  /undici/5.15.0:
-    resolution: {integrity: sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g==}
+  /undici/5.15.1:
+    resolution: {integrity: sha512-XLk8g0WAngdvFqTI+VKfBtM4YWXgdxkf1WezC771Es0Dd+Pm1KmNx8t93WTC+Hh9tnghmVxkclU1HN+j+CvIUA==}
     engines: {node: '>=12.18'}
     dependencies:
       busboy: 1.6.0
@@ -13460,7 +13648,7 @@ packages:
   /uri-js/4.4.1:
     resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
     dependencies:
-      punycode: 2.2.0
+      punycode: 2.3.0
 
   /urix/0.1.0:
     resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==}
@@ -13675,7 +13863,7 @@ packages:
       esbuild: 0.16.17
       postcss: 8.4.21
       resolve: 1.22.1
-      rollup: 3.10.0
+      rollup: 3.10.1
       sass: 1.57.1
     optionalDependencies:
       fsevents: 2.3.2
@@ -13686,14 +13874,14 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: false
 
-  /vue-eslint-parser/9.1.0_eslint@8.31.0:
+  /vue-eslint-parser/9.1.0_eslint@8.32.0:
     resolution: {integrity: sha512-NGn/iQy8/Wb7RrRa4aRkokyCZfOUWk19OP5HP6JEozQFX5AoS/t+Z0ZN7FY4LlmWc4FNI922V7cvX28zctN8dQ==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=6.0.0'
     dependencies:
       debug: 4.3.4
-      eslint: 8.31.0
+      eslint: 8.32.0
       eslint-scope: 7.1.1
       eslint-visitor-keys: 3.3.0
       espree: 9.4.1

From ead931211c6783975d01928fa4636e42208689a1 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 22 Jan 2023 04:24:38 +0900
Subject: [PATCH 5/7] =?UTF-8?q?fix(client):=20=E5=AE=9F=E7=B8=BE=E8=A7=A3?=
 =?UTF-8?q?=E9=99=A4=E3=83=AA=E3=82=AF=E3=82=A8=E3=82=B9=E3=83=88=E3=81=AE?=
 =?UTF-8?q?=E9=96=93=E9=9A=94=E3=82=92=E3=81=82=E3=81=91=E3=82=8B=E3=82=88?=
 =?UTF-8?q?=E3=81=86=E3=81=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fix #9674
---
 packages/frontend/src/scripts/achievements.ts | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/packages/frontend/src/scripts/achievements.ts b/packages/frontend/src/scripts/achievements.ts
index 8f484f8925..c97358e880 100644
--- a/packages/frontend/src/scripts/achievements.ts
+++ b/packages/frontend/src/scripts/achievements.ts
@@ -433,16 +433,22 @@ export const ACHIEVEMENT_BADGES = {
 
 export const claimedAchievements = ($i && $i.achievements) ? $i.achievements.map(x => x.name) : [];
 
-export function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number]) {
+const claimingQueue = new Set<string>();
+
+export async function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number]) {
 	if (claimedAchievements.includes(type)) return;
-	os.api('i/claim-achievement', { name: type });
+	claimingQueue.add(type);
 	claimedAchievements.push(type);
+	await new Promise(resolve => setTimeout(resolve, (claimingQueue.size - 1) * 500));
+	window.setTimeout(() => {
+		claimingQueue.delete(type);
+	}, 500);
+	os.api('i/claim-achievement', { name: type });
 }
 
 if (_DEV_) {
-	(window as any).unlockAllAchievements = async () => {
+	(window as any).unlockAllAchievements = () => {
 		for (const t of ACHIEVEMENT_TYPES) {
-			await new Promise(resolve => setTimeout(resolve, 100));
 			claimAchievement(t);
 		}
 	};

From d6ff50a30b8ec6e1875a539438a116f80b538490 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 22 Jan 2023 04:28:19 +0900
Subject: [PATCH 6/7] New Crowdin updates (#9676)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Traditional)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Chinese Traditional)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Traditional)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Traditional)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Russian)
---
 locales/de-DE.yml | 229 ++++++++++++++++++++++++++++++++++++++++++++++
 locales/en-US.yml | 197 ++++++++++++++++++++++++++++++++++++++-
 locales/ko-KR.yml |  13 +++
 locales/ru-RU.yml | 225 +++++++++++++++++++++++++++++++++++++++++++++
 locales/zh-CN.yml |  77 ++++++++++++++++
 locales/zh-TW.yml | 106 ++++++++++++++++++++-
 6 files changed, 845 insertions(+), 2 deletions(-)

diff --git a/locales/de-DE.yml b/locales/de-DE.yml
index f6095e4db6..ecead98c32 100644
--- a/locales/de-DE.yml
+++ b/locales/de-DE.yml
@@ -938,6 +938,234 @@ cannotPerformTemporary: "Vorübergehend nicht verfügbar"
 cannotPerformTemporaryDescription: "Diese Aktion ist wegen des Überschreitenes des Ausführungslimits temporär nicht verfügbar. Bitte versuche es nach einiger Zeit erneut."
 preset: "Vorlage"
 selectFromPresets: "Aus Vorlagen wählen"
+achievements: "Errungenschaften"
+_achievements:
+  earnedAt: "Freigeschaltet am"
+  _types:
+    _notes1:
+      title: "Hallo Misskey!"
+      description: "Sende deine erste Notiz"
+      flavor: "Hab eine schöne Zeit mit Misskey!"
+    _notes10:
+      title: "Ein paar Notizen"
+      description: "10 Notizen gesendet"
+    _notes100:
+      title: "Viele Notizen"
+      description: "100 Notizen gesendet"
+    _notes500:
+      title: "Überschüttet mit Notizen"
+      description: "500 Notizen gesendet"
+    _notes1000:
+      title: "Berg an Notizen"
+      description: "1.000 Notizen gesendet"
+    _notes5000:
+      title: "Überquellende Notizen"
+      description: "5.000 Notizen gesendet"
+    _notes10000:
+      title: "Supernotiz"
+      description: "10.000 Notizen gesendet"
+    _notes20000:
+      title: "Brauche... mehr... Notizen"
+      description: "20.000 Notizen gesendet"
+    _notes30000:
+      title: "Notizen, Notizen, Notizen"
+      description: "30.000 Notizen gesendet"
+    _notes40000:
+      title: "Notizfabrik"
+      description: "40.000 Notizen gesendet"
+    _notes50000:
+      title: "Planet der Notizen"
+      description: "50.000 Notizen gesendet"
+    _notes60000:
+      title: "Notizquasar"
+      description: "60.000 Notizen gesendet"
+    _notes70000:
+      title: "Schwarzes Notizloch"
+      description: "70.000 Notizen gesendet"
+    _notes80000:
+      title: "Notizgalaxie"
+      description: "80.000 Notizen gesendet"
+    _notes90000:
+      title: "Notizversum"
+      description: "90.000 Notizen gesendet"
+    _notes100000:
+      title: "ALL YOUR NOTE ARE BELONG TO US"
+      description: "100.000 Notizen gesendet"
+      flavor: "Du hast wirklich viel zu sagen."
+    _login3:
+      title: "Anfänger Ⅰ"
+      description: "An 3 Tagen eingeloggt"
+      flavor: "Nenn' mich ab heute Misskist"
+    _login7:
+      title: "Anfänger Ⅱ"
+      description: "An 7 Tagen eingeloggt"
+      flavor: "Na, eingewöht?"
+    _login15:
+      title: "Anfänger Ⅲ"
+      description: "An 15 Tagen eingeloggt"
+    _login30:
+      title: "Misskist Ⅰ"
+      description: "An 30 Tagen eingeloggt"
+    _login60:
+      title: "Misskist Ⅱ"
+      description: "An 60 Tagen eingeloggt"
+    _login100:
+      title: "Misskist Ⅲ"
+      description: "An 100 Tagen eingeloggt"
+      flavor: "Violent Misskist"
+    _login200:
+      title: "Stammbesucher Ⅰ"
+      description: "An 200 Tagen eingeloggt"
+    _login300:
+      title: "Stammbesucher Ⅱ"
+      description: "An 300 Tagen eingeloggt"
+    _login400:
+      title: "Stammbesucher Ⅲ"
+      description: "An 400 Tagen eingeloggt"
+    _login500:
+      title: "Veteran Ⅰ"
+      description: "An 500 Tagen eingeloggt"
+      flavor: "Meine Kameraden, ich liebe sie, die Notizen."
+    _login600:
+      title: "Veteran Ⅱ"
+      description: "An 600 Tagen eingeloggt"
+    _login700:
+      title: "Veteran Ⅲ"
+      description: "An 700 Tagen eingeloggt"
+    _login800:
+      title: "Meister der Notizen Ⅰ"
+      description: "An 800 Tagen eingeloggt"
+    _login900:
+      title: "Meister der Notizen Ⅱ"
+      description: "An 900 Tagen eingeloggt"
+    _login1000:
+      title: "Meister der Notizen Ⅲ"
+      description: "An 1000 Tagen eingeloggt"
+      flavor: "Danke, dass du Misskey nutzt!"
+    _noteClipped1:
+      title: "Muss... clippen..."
+      description: "Die erste Notiz geclippt"
+    _noteFavorited1:
+      title: "Sternengucker"
+      description: "Eine Notiz als Favorit markiert"
+    _profileFilled:
+      title: "Perfekte Vorbereitung"
+      description: "Fülle dein Profil aus"
+    _markedAsCat:
+      title: "Ich der Kater"
+      description: "Markiere dein Konto als Katze"
+      flavor: "Einen Namen bekommst du später. "
+    _following1:
+      title: "Das Folgen beginnt"
+      description: "Du folgst deiner ersten Person"
+    _following10:
+      title: "Folge ihnen... folge ihnen..."
+      description: "Du folgst über 10 Leuten"
+    _following50:
+      title: "Viele Freunde"
+      description: "Du folgst über 50 Leuten"
+    _following100:
+      title: "100 Freunde"
+      description: "Du folgst über 100 Leuten"
+    _following300:
+      title: "Freundeüberschuss"
+      description: "Du folgst über 300 Leuten"
+    _followers1:
+      title: "Der erste Follower"
+      description: "Du hast deinen ersten Follower erhalten"
+    _followers10:
+      title: "Mir nach!"
+      description: "Die Anzahl deiner Follower hat 10 überschritten"
+    _followers50:
+      title: "Wirrwarr"
+      description: "Die Anzahl deiner Follower hat 50 überschritten"
+    _followers100:
+      title: "Beliebt"
+      description: "Die Anzahl deiner Follower hat 100 überschritten"
+    _followers300:
+      title: "Stellt euch bitte in einer Reihe auf"
+      description: "Die Anzahl deiner Follower hat 300 überschritten"
+    _followers500:
+      title: "Funkmast"
+      description: "Die Anzahl deiner Follower hat 500 überschritten"
+    _followers1000:
+      title: "Influencer"
+      description: "Die Anzahl deiner Follower hat 1000 überschritten"
+    _collectAchievements30:
+      title: "Sammler der Errungenschaften"
+      description: "Schalte 30 Errungenschaften frei"
+    _viewAchievements3min:
+      title: "Fan von Errungenschaften"
+      description: "Schau dir die Liste deiner Errungenschaften für mindestens 3 Minuten an"
+    _iLoveMisskey:
+      title: "I Love Misskey"
+      description: "Sende \"I ❤ #Misskey\""
+      flavor: "Danke, dass du Misskey verwendest! - vom Entwicklerteam"
+    _client30min:
+      title: "Kleine Pause"
+      description: "Seit dem Öffnen deines Clients sind 30 Minuten vergangen"
+    _noteDeletedWithin1min:
+      title: "Ups"
+      description: "Lösche eine Notiz innerhalb von 1 Minute nachdem sie gesendet wurde"
+    _postedAtLateNight:
+      title: "Nachtaktiv"
+      description: "Sende mitten in der Nacht eine Notiz"
+      flavor: "Geh bald schlafen."
+    _postedAt0min0sec:
+      title: "Zeitansage"
+      description: "Sende um 00:00 eine Notiz"
+      flavor: "Klick Klick Klick Dooong"
+    _selfQuote:
+      title: "Selbstzitat"
+      description: "Zitiere eine eigene Notiz"
+    _htl20npm:
+      title: "Fließende Chronik"
+      description: "Deine Startseitenchronik erreicht eine Geschwindigkeit von 20 npm (Notizen pro Minute)"
+    _outputHelloWorldOnScratchpad:
+      title: "Hallo Welt!"
+      description: "Gib \"hello world\" in der Testumgebung aus"
+    _open3windows:
+      title: "Splitscreen"
+      description: "Habe zur gleichen Zeit mindestens 3 Fenster offen"
+    _driveFolderCircularReference:
+      title: "Zyklischer Verweis"
+      description: "Versuche, in Drive einen Zirkelbezug von Ordnern herzustellen"
+    _reactWithoutRead:
+      title: "Hast du das wirklich gelesen?"
+      description: "Reagiere auf eine Notiz mit mindestens 100 Zeichen innerhalb von 3 Sekunden der Erstellung der Notiz"
+    _clickedClickHere:
+      title: "Klicke hier"
+      description: "Du hast hier geklickt"
+    _justPlainLucky:
+      title: "Pures Glück"
+      description: "Kann alle 10 Sekunden mit einer Warscheinlichkeit von 0.01% erhalten werden"
+    _setNameToSyuilo:
+      title: "Gottkomplex"
+      description: "Setze deinen Namen auf \"syuilo\""
+    _passedSinceAccountCreated1:
+      title: "Einjahresjubiläum"
+      description: "Seit der Erstellung deines Kontos ist 1 Jahr vergangen"
+    _passedSinceAccountCreated2:
+      title: "Zweijahresjubiläum"
+      description: "Seit der Erstellung deines Kontos sind 2 Jahre vergangen"
+    _passedSinceAccountCreated3:
+      title: "Dreijahresjubiläum"
+      description: "Seit der Erstellung deines Kontos sind 3 Jahre vergangen"
+    _loggedInOnBirthday:
+      title: "Alles Gute Zum Geburtstag"
+      description: "Logge dich an deinem Geburtstag ein"
+    _loggedInOnNewYearsDay:
+      title: "Frohes Neujahr"
+      description: "Logge dich am Neujahrstag ein"
+      flavor: "Auf ein weiteres tolles Jahr in dieser Instanz"
+    _cookieClicked:
+      title: "Ein Spiel, in dem du auf einen Keks klickst"
+      description: "Den Keks geklickt"
+      flavor: "Bist du hier richtig?"
+    _brainDiver:
+      title: "Brain Diver"
+      description: "Sende den Link zu Brain Diver"
+      flavor: "Misskey-Misskey La-Tu-Ma"
 _role:
   new: "Rolle erstellen"
   edit: "Rolle bearbeiten"
@@ -1587,6 +1815,7 @@ _notification:
   pollEnded: "Umfrageergebnisse sind verfügbar"
   unreadAntennaNote: "Antenne {name}"
   emptyPushNotificationMessage: "Push-Benachrichtigungen wurden aktualisiert"
+  achievementEarned: "Errungenschaft freigeschaltet"
   _types:
     all: "Alle"
     follow: "Neue Follower"
diff --git a/locales/en-US.yml b/locales/en-US.yml
index b9f1603d26..e398f1fd58 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -938,8 +938,198 @@ cannotPerformTemporary: "Temporarily unavailable"
 cannotPerformTemporaryDescription: "This action cannot be performed temporarily due to exceeding the execution limit. Please wait for a while and then try again."
 preset: "Preset"
 selectFromPresets: "Choose from presets"
+achievements: "Achievements"
 _achievements:
+  earnedAt: "Unlocked at"
   _types:
+    _notes1:
+      title: "just setting up my msky"
+      description: "Post your first note"
+      flavor: "Have a good Misskey life!"
+    _notes10:
+      title: "Some notes"
+      description: "Post 10 notes"
+    _notes100:
+      title: "A lot of notes"
+      description: "Post 100 notes"
+    _notes500:
+      title: "Covered in notes"
+      description: "Post 500 notes"
+    _notes1000:
+      title: "A mountain of notes"
+      description: "Post 1,000 notes"
+    _notes5000:
+      title: "Overflowing notes"
+      description: "Post 5,000 notes"
+    _notes10000:
+      title: "Supernote"
+      description: "Post 10,000 notes"
+    _notes20000:
+      title: "Need... more... notes..."
+      description: "Post 20,000 notes"
+    _notes30000:
+      title: "Notes notes notes!"
+      description: "Post 30,000 notes"
+    _notes40000:
+      title: "Note factory"
+      description: "Post 40,000 notes"
+    _notes50000:
+      title: "Planet of notes"
+      description: "Post 50,000 notes"
+    _notes60000:
+      title: "Note quasar"
+      description: "Post 60,000 notes"
+    _notes70000:
+      title: "Note black hole"
+      description: "Post 70,000 notes"
+    _notes80000:
+      title: "Note galaxy"
+      description: "Post 80,000 notes"
+    _notes90000:
+      title: "Note universe"
+      description: "Post 90,000 notes"
+    _notes100000:
+      title: "ALL YOUR NOTE ARE BELONG TO US"
+      description: "Post 100,000 notes"
+      flavor: "You sure have a lot to say."
+    _login3:
+      title: "Beginner I"
+      description: "Log in for a total of 3 days"
+      flavor: "Starting today, just call me Misskist"
+    _login7:
+      title: "Beginner II"
+      description: "Log in for a total of 7 days"
+      flavor: "Feel like you've gotten the hang of things yet?"
+    _login15:
+      title: "Beginner III"
+      description: "Log in for a total of 15 days"
+    _login30:
+      title: "Misskist I"
+      description: "Log in for a total of 30 days"
+    _login60:
+      title: "Misskist II"
+      description: "Log in for a total of 60 days"
+    _login100:
+      title: "Misskist III"
+      description: "Log in for a total of 100 days"
+      flavor: "Violent Misskist"
+    _login200:
+      title: "Regular I"
+      description: "Log in for a total of 200 days"
+    _login300:
+      title: "Regular II"
+      description: "Log in for a total of 300 days"
+    _login400:
+      title: "Regular III"
+      description: "Log in for a total of 400 days"
+    _login500:
+      title: "Expert I"
+      description: "Log in for a total of 500 days"
+      flavor: "My friends, it has often been said that I like notes"
+    _login600:
+      title: "Expert II"
+      description: "Log in for a total of 600 days"
+    _login700:
+      title: "Expert III"
+      description: "Log in for a total of 700 days"
+    _login800:
+      title: "Master of Notes I"
+      description: "Log in for a total of 800 days"
+    _login900:
+      title: "Master of Notes II"
+      description: "Log in for a total of 900 days"
+    _login1000:
+      title: "Master of Notes III"
+      description: "Log in for a total of 1,000 days"
+      flavor: "Thank you for using Misskey!"
+    _noteClipped1:
+      title: "Must... clip..."
+      description: "Clip your first note"
+    _noteFavorited1:
+      title: "Stargazer"
+      description: "Favorite your first note"
+    _profileFilled:
+      title: "Well-prepared"
+      description: "Set up your profile"
+    _markedAsCat:
+      title: "I Am a Cat"
+      description: "Mark your account as a cat"
+      flavor: "I'll give you a name later."
+    _following1:
+      title: "Following your first user"
+      description: "Follow a user"
+    _following10:
+      title: "Keep up... keep up..."
+      description: "Follow 10 users"
+    _following50:
+      title: "Lots of friends"
+      description: "Follow 50 accounts"
+    _following100:
+      title: "100 Friends"
+      description: "Follow 100 accounts"
+    _following300:
+      title: "Friend overload"
+      description: "Follow 300 accounts"
+    _followers1:
+      title: "First follower"
+      description: "Gain 1 follower"
+    _followers10:
+      title: "Follow me!"
+      description: "Gain 10 followers"
+    _followers50:
+      title: "Coming in crowds"
+      description: "Gain 50 followers"
+    _followers100:
+      title: "Popular"
+      description: "Gain 100 followers"
+    _followers300:
+      title: "Please form a single line"
+      description: "Gain 300 followers"
+    _followers500:
+      title: "Radio Tower"
+      description: "Gain 500 followers"
+    _followers1000:
+      title: "Influencer"
+      description: "Gain 1,000 followers"
+    _collectAchievements30:
+      title: "Achievement Collector"
+      description: "Earn 30 achievements"
+    _viewAchievements3min:
+      title: "Likes Achievements"
+      description: "Look at your list of achievements for at least 3 minutes"
+    _iLoveMisskey:
+      title: "I Love Misskey"
+      description: "Post \"I ❤ #Misskey\""
+      flavor: "Misskey's development team greatly appreciates your support!"
+    _client30min:
+      title: "Short break"
+      description: "Spend 30 minutes on Misskey"
+    _noteDeletedWithin1min:
+      title: "Nevermind"
+      description: "Delete a note within a minute of posting it"
+    _postedAtLateNight:
+      title: "Nocturnal"
+      description: "Post a note late at night"
+      flavor: "It's about time to go to bed."
+    _postedAt0min0sec:
+      title: "Speaking Clock"
+      description: "Post a note at 00:00"
+      flavor: "Click Click Click Claaang"
+    _selfQuote:
+      title: "Self-Reference"
+      description: "Quote your own note"
+    _htl20npm:
+      title: "Flowing Timeline"
+      description: "Have the speed of your home timeline exceed 20 npm (notes per minute)"
+    _outputHelloWorldOnScratchpad:
+      title: "Hello, world!"
+      description: "Output \"hello world\" in the Scratchpad"
+    _open3windows:
+      title: "Multi-Window"
+      description: "Have at least 3 windows open at the same time"
+    _driveFolderCircularReference:
+      title: "Circular Reference"
+      description: "Attempt to create a recursively nested folder in Drive"
     _reactWithoutRead:
       title: "Did you really read that?"
       description: "React on a note that's over 100 characters long within 3 seconds of it being posted"
@@ -963,10 +1153,15 @@ _achievements:
       description: "Three years have passed since your account was created"
     _loggedInOnBirthday:
       title: "Happy Birthday"
-      description: "Logged in on your birthday"
+      description: "Log in on your birthday"
+    _loggedInOnNewYearsDay:
+      title: "Happy New Year!"
+      description: "Logged in on the first day of the year"
+      flavor: "To another great year on this instance"
     _cookieClicked:
       title: "A game in which you click cookies"
       description: "Clicked the cookie"
+      flavor: "Wait, are you on the correct website?"
     _brainDiver:
       title: "Brain Diver"
       description: "Post the link to Brain Diver"
diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml
index 3e6ab5a2f5..bf747e3cb7 100644
--- a/locales/ko-KR.yml
+++ b/locales/ko-KR.yml
@@ -1094,6 +1094,9 @@ _achievements:
     _collectAchievements30:
       title: "도전과제 콜렉터"
       description: "30개의 도전과제를 획득했습니다"
+    _viewAchievements3min:
+      title: "저 도전과제 좋아해요"
+      description: "도전과제 목록을 3분 이상 보세요"
     _iLoveMisskey:
       title: "I Love Misskey"
       description: "\"I ❤ #Misskey\"를 포스트했습니다"
@@ -1118,6 +1121,12 @@ _achievements:
     _htl20npm:
       title: "타임라인 폭주 중"
       description: "1분 사이에 홈 타임라인에 노트가 20개 넘게 생성되었습니다"
+    _outputHelloWorldOnScratchpad:
+      title: "Hello, world!"
+      description: "스크래치패드에서 hello world를 출력하세요"
+    _open3windows:
+      title: "멀티 윈도우"
+      description: "3개 이상의 창을 여세요"
     _driveFolderCircularReference:
       title: "순환 참조"
       description: "드라이브 폴더를 자신을 가리키도록 만드려 시도했습니다"
@@ -1145,6 +1154,10 @@ _achievements:
     _loggedInOnBirthday:
       title: "생일 축하합니다!"
       description: "설정한 생일에 로그인했습니다"
+    _loggedInOnNewYearsDay:
+      title: "새해 복 많이 받으세요"
+      description: "새해 첫 날에 로그인했습니다"
+      flavor: "올해에도 저희 인스턴스에 관심을 가져 주셔서 감사합니다"
     _cookieClicked:
       title: "쿠키 클리커 게임"
       description: "쿠키를 클릭했습니다"
diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml
index d7aca1c9fc..133169e8da 100644
--- a/locales/ru-RU.yml
+++ b/locales/ru-RU.yml
@@ -2,6 +2,7 @@
 _lang_: "Русский"
 headlineMisskey: "Сеть, сплетённая из заметок"
 introMisskey: "Добро пожаловать! Misskey — это децентрализованный сервис микроблогов с открытым исходным кодом.\nПишите «заметки» — делитесь со всеми происходящим вокруг или рассказывайте о себе 📡\nСтавьте «реакции» — выражайте свои чувства и эмоции от заметок других 👍\nОткройте для себя новый мир 🚀"
+poweredByMisskeyDescription: "{name} – один из инстансов (также называемый экземпляром Misskey), использующий платформу с открытым исходным кодом <b>Misskey</b>."
 monthAndDay: "{day}.{month}"
 search: "Поиск"
 notifications: "Уведомления"
@@ -12,6 +13,7 @@ fetchingAsApObject: "Приём с других сайтов"
 ok: "Окей"
 gotIt: "Ясно!"
 cancel: "Отмена"
+noThankYou: "Нет, спасибо"
 enterUsername: "Введите имя пользователя"
 renotedBy: "{user} делится"
 noNotes: "Нет ни одной заметки"
@@ -47,6 +49,7 @@ deleteAndEdit: "Удалить и отредактировать"
 deleteAndEditConfirm: "Удалить эту заметку и создать отредактированную? Все реакции, ссылки и ответы на существующую будут будут потеряны."
 addToList: "Добавить в список"
 sendMessage: "Отправить сообщение"
+copyRSS: "Скопировать RSS"
 copyUsername: "Скопировать имя пользователя"
 searchUser: "Поиск людей"
 reply: "Ответить"
@@ -452,6 +455,7 @@ language: "Язык"
 uiLanguage: "Язык интерфейса"
 groupInvited: "Приглашение в группу"
 aboutX: "Описание {x}"
+emojiStyle: "Стиль эмодзи"
 disableDrawer: "Не использовать выдвижные меню"
 youHaveNoGroups: "У вас нет ни одной группы"
 joinOrCreateGroup: "Получайте приглашения в группы или создавайте свои собственные"
@@ -709,6 +713,7 @@ accentColor: "Акцент"
 textColor: "Текст"
 saveAs: "Сохранить под названием…"
 advanced: "Для продвинутых"
+advancedSettings: "Расширенные настройки "
 value: "Значения"
 createdAt: "Создано"
 updatedAt: "Обновлено"
@@ -840,34 +845,254 @@ numberOfColumn: "Количество столбцов"
 searchByGoogle: "Поиск"
 instanceDefaultLightTheme: "Светлая тема по умолчанию"
 instanceDefaultDarkTheme: "Темная тема по умолчанию"
+instanceDefaultThemeDescription: "Описание темы по умолчанию для инстанса"
 mutePeriod: "Продолжительность скрытия"
 indefinitely: "вечно"
 tenMinutes: "10 минут"
 oneHour: "1 час"
 oneDay: "1 день"
 oneWeek: "1 неделя"
+reflectMayTakeTime: "Изменения могут занять время для отображения"
+failedToFetchAccountInformation: "Не удалось получить информацию об аккаунте"
 cropImage: "Кадрирование"
 cropImageAsk: "Нужно ли кадрировать изображение?"
 file: "Файлы"
 recentNHours: "Последние {n} ч"
 recentNDays: "Последние {n} сут"
+noEmailServerWarning: "Почтовый сервер не установлен "
+thereIsUnresolvedAbuseReportWarning: "Остались нерешённые жалобы"
 recommended: "Рекомендуем"
 check: "Проверить"
 driveCapOverrideLabel: "Изменение лимита дискового пространства для этого пользователя"
+driveCapOverrideCaption: "Укажите меньше или равное нулю для отмены"
+requireAdminForView: "Для просмотра необходимо иметь аккаунт администратора"
+isSystemAccount: "Данная учётная запись создана автоматически и управляется системой"
+typeToConfirm: "Введите {x} для продолжения"
 deleteAccount: "Удаление учётной записи"
+document: "Документ"
+numberOfPageCache: "Количество сохранённых страниц в кэше"
+numberOfPageCacheDescription: "Описание количества страниц в кэше"
+logoutConfirm: "Вы хотите выйти из аккаунта?"
+lastActiveDate: "Последняя дата использования"
+statusbar: "Статусбар"
+pleaseSelect: "Пожалуйста, выберите"
 reverse: "Переворот"
 colored: "Выделена цветом"
+refreshInterval: "Интервал перезагрузки"
 label: "Метка"
+type: "Тип"
+speed: "Скорость"
+sensitiveMediaDetection: "Определение содержимого деликатного характера"
 localOnly: "Локально"
+remoteOnly: "Только удалённо"
+failedToUpload: "Сбой выгрузки"
+cannotUploadBecauseInappropriate: "Файл не может быть загружен, так как было установлено, что он может содержать неприемлемое содержимое."
+cannotUploadBecauseNoFreeSpace: "Файл не может быть загружен, так как не осталось места на диске"
 beta: "Бета"
 enableAutoSensitive: "Автоматическое определение NSFW"
 enableAutoSensitiveDescription: "Если доступно, используйте машинное обучение для автоматической установки флага NSFW на носителе. Даже если эта функция отключена, она может быть установлена ​​автоматически в зависимости от инстанта."
 account: "Учётные записи"
 windowMaximize: "Развернуть"
 windowRestore: "Восстановить"
+loggedInAsBot: "Вы под аккаунтом бота!"
 like: "Нравится!"
+unlike: "Отменить «нравится»"
 show: "Отображение"
+pleaseDonate: "Сайт {host} работает на Misskey. Это бесплатное программное обеспечение, и ваши пожертвования очень бы помогли продолжать его разработку!"
 color: "Цвет"
+_achievements:
+  _types:
+    _notes1:
+      title: "Первые шаги в Misskey"
+      description: "Опубликована первая заметка"
+    _notes10:
+      title: "Несколько заметок"
+      description: "Опубликовано 10 заметок"
+    _notes100:
+      title: "Много заметок"
+      description: "Опубликовано 100 заметок"
+    _notes500:
+      title: "Всё в заметках"
+      description: "Опубликовано 500 заметок"
+    _notes1000:
+      title: "Гора заметок"
+      description: "Опубликовано 1000 заметок"
+    _notes5000:
+      title: "Заметки льются рекой"
+      description: "Опубликовано 5000 заметок"
+    _notes10000:
+      title: "Превосходство в заметках"
+      description: "Опубликовано 10 000 заметок"
+    _notes20000:
+      title: "Нужно больше заметок!"
+      description: "Опубликовано 20 000 заметок"
+    _notes30000:
+      title: "Заметки, заметки, заметки"
+      description: "Опубликовано 30 000 заметок"
+    _notes40000:
+      title: "Фабрика заметок"
+      description: "Опубликовано 40 000 заметок"
+    _notes50000:
+      title: "Планета заметок"
+      description: "Опубликовано 50 000 заметок"
+    _notes60000:
+      title: "Замет-квазар"
+      description: "Опубликовано 60 000 заметок"
+    _notes70000:
+      title: "Чёрная дыра из заметок"
+      description: "Опубликовано 70 000 заметок"
+    _notes80000:
+      title: "Галактика заметок"
+      description: "Опубликовано 80 000 заметок"
+    _notes90000:
+      title: "Вселенная заметок"
+      description: "Опубликовано 90 000 заметок"
+    _notes100000:
+      title: "ALL YOUR NOTE ARE BELONG TO US"
+      description: "Опубликовано 100 000 заметок"
+    _login3:
+      title: "Новичок Ⅰ"
+      description: "3 дня на сайте"
+    _login7:
+      title: "Новичок Ⅱ"
+      description: "Неделя на сайте"
+      flavor: "Кажется, вы начали свыкаться с этим, нет?"
+    _login15:
+      title: "Новичок Ⅲ"
+      description: "15 дней на сайте"
+    _login30:
+      title: "Мискиец Ⅰ"
+      description: "30 дней на сайте"
+    _login60:
+      title: "Мискиец Ⅱ"
+      description: "60 дней на сайте"
+    _login100:
+      title: "Мискиец Ⅲ"
+      description: "100 дней на сайте"
+    _login200:
+      title: "Завсегдатай Ⅰ"
+      description: "200 дней на сайте"
+    _login300:
+      title: "Завсегдатай Ⅱ"
+      description: "300 дней на сайте"
+    _login400:
+      title: "Завсегдатай Ⅲ"
+      description: "400 дней на сайте"
+    _login500:
+      title: "Ветеран Ⅰ"
+      description: "500 дней на сайте"
+    _login600:
+      title: "Ветеран Ⅱ"
+      description: "600 дней на сайте"
+    _login700:
+      title: "Ветеран Ⅲ"
+      description: "700 дней на сайте"
+    _login800:
+      title: "Повелитель заметок Ⅰ"
+      description: "800 дней на сайте"
+    _login900:
+      title: "Повелитель заметок Ⅱ"
+      description: "900 дней на сайте"
+    _login1000:
+      title: "Повелитель заметок Ⅲ"
+      description: "1000 дней на сайте"
+    _noteClipped1:
+      title: "Нельзя не сохранить"
+      description: "Первая заметка в подборке"
+    _noteFavorited1:
+      title: "Смотрящий на звёзды"
+      description: "Первое добавление в избранное"
+    _profileFilled:
+      title: "Приготовления закончены"
+      description: "Заполнен профиль"
+    _markedAsCat:
+      description: "Включена опция «Аккаунт кота»"
+    _followers50:
+      title: "Один за другим"
+      description: "Подписчиков больше 50"
+    _followers100:
+      title: "Всеобщий любимец"
+      description: "Подписчиков больше 100"
+    _followers300:
+      title: "В очередь!"
+      description: "Подписчиков больше 300"
+    _followers500:
+      title: "Радиостанция"
+      description: "Подписчиков больше 300"
+    _followers1000:
+      title: "Авторитет"
+      description: "Подписчиков больше 1000"
+    _collectAchievements30:
+      title: "Достигатор"
+      description: "Получено 30 достижений"
+    _viewAchievements3min:
+      title: "Любовь к успехам"
+      description: "Более 3 минут любования достижениями"
+    _iLoveMisskey:
+      title: "Я люблю Misskey"
+      description: "Написана заметка «I ❤ #Misskey»"
+    _client30min:
+      title: "Перерыв на обед"
+      description: "Прошло 30 минут с момента запуска клиента"
+    _noteDeletedWithin1min:
+      title: "Ой, нет!"
+      description: "Заметка удалена через минуту после публикации"
+    _postedAtLateNight:
+      title: "Житель ночи"
+      description: "Заметка опубликована в глухую ночь"
+    _postedAt0min0sec:
+      title: "Говорящие часы"
+      description: "Заметка опубликована ровно в 0 минут 0 секунд"
+      flavor: "Дин-дон дин-дон"
+    _selfQuote:
+      title: "Самовоспроизведение"
+      description: "Процитирована собственная заметка"
+    _htl20npm:
+      title: "В потоке"
+      description: "Достигнута скорость домашней ленты в 20 з/мин (заметок минуту)"
+    _outputHelloWorldOnScratchpad:
+      title: "Привет, мир!"
+      description: "Выведен текст «hello world» в Когтеточке"
+    _open3windows:
+      title: "Многооконный"
+      description: "Открыто одновременно 3 окна"
+    _driveFolderCircularReference:
+      description: "Попытка создать на «диске» рекурсивно вложенную папку"
+    _reactWithoutRead:
+      title: "Не читай @ отвечай!"
+      description: "На заметку более чем 100 знаков написан ответ в первые же 3 секунды с её появления."
+    _clickedClickHere:
+      title: "Нажмите здесь"
+      description: "Нажато здесь"
+    _justPlainLucky:
+      title: "Чистая удача"
+      description: "Может достаться с вероятностью 0,01% каждые 10 секунд."
+    _setNameToSyuilo:
+      title: "Комплекс бога"
+      description: "Установлено «syuilo» в качестве имени"
+    _passedSinceAccountCreated1:
+      title: "Первая годовщина"
+      description: "Прошёл 1 год с момента регистрации"
+    _passedSinceAccountCreated2:
+      title: "Вторая годовщина"
+      description: "Прошло 2 года с момента регистрации"
+    _passedSinceAccountCreated3:
+      title: "Третья годовщина"
+      description: "Прошло 3 года с момента регистрации"
+    _loggedInOnBirthday:
+      title: "С днём рождения!"
+      description: "Вход на сайт в свой день рождения"
+    _loggedInOnNewYearsDay:
+      title: "С Новым годом!"
+      description: "Вход на сайт в первый день года"
+    _cookieClicked:
+      title: "Игра, в которой вы щёлкаете по печенькам"
+      description: "Нажато печенье"
+      flavor: "Стоп, вы вообще на том сайте-то?"
+    _brainDiver:
+      title: "Brain Diver"
+      description: "Опубликована ссылка на песню «Brain Diver»"
+      flavor: "Мисски-Мисски Ла-Ту-Ма"
 _role:
   priority: "Приоритет"
   _priority:
diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml
index 817fc69462..33127264b6 100644
--- a/locales/zh-CN.yml
+++ b/locales/zh-CN.yml
@@ -938,6 +938,82 @@ cannotPerformTemporary: "暂时不可用"
 cannotPerformTemporaryDescription: "因操作过于频繁,暂时不可用,请稍后再试。"
 preset: "預設值"
 selectFromPresets: "從預設值中選擇"
+achievements: "成就"
+_achievements:
+  earnedAt: "达成时间"
+  _types:
+    _notes1:
+      title: "初来乍到"
+      description: "第一次发帖"
+      flavor: "祝您在Misskey玩的愉快~"
+    _notes10:
+      title: "一些帖子"
+      description: "发布了10篇帖子"
+    _notes100:
+      title: "很多帖子"
+      description: "发布了100篇帖子"
+    _notes500:
+      title: "满是帖子"
+      description: "发布了500篇帖子"
+    _notes1000:
+      title: "帖子成山"
+      description: "发布了1,000篇帖子"
+    _notes5000:
+      title: "帖如泉涌"
+      description: "发布了5,000篇帖子"
+    _notes10000:
+      title: "超级帖"
+      description: "发布了10,000篇帖子"
+    _notes20000:
+      title: "还想要更多帖子"
+      description: "发布了20,000篇帖子"
+    _notes30000:
+      title: "帖子帖子帖子"
+      description: "发布了30,000篇帖子"
+    _notes40000:
+      title: "帖子工厂"
+      description: "发布了40,000篇帖子"
+    _notes50000:
+      title: "帖子星球"
+      description: "发布了50,000篇帖子"
+    _notes60000:
+      title: "帖子类星体"
+      description: "发布了60,000篇帖子"
+    _notes70000:
+      title: "帖子黑洞"
+      description: "发布了70,000篇帖子"
+    _notes80000:
+      title: "帖子星系"
+      description: "发布了80,000篇帖子"
+    _notes90000:
+      title: "帖子起源"
+      description: "发布了90,000篇帖子"
+    _notes100000:
+      title: "ALL YOUR NOTE ARE BELONG TO US"
+      description: "发布了100,000篇帖子"
+      flavor: "真的有那么多可以写的东西吗?"
+    _login1000:
+      flavor: "感谢您使用Misskey!"
+    _noteFavorited1:
+      title: "观星者"
+    _markedAsCat:
+      title: "我是猫"
+    _following50:
+      title: "我的朋友很多"
+    _viewAchievements3min:
+      description: "盯着成就看三分钟"
+    _iLoveMisskey:
+      title: "I Love Misskey"
+      description: "发布\"I ❤ #Misskey\"帖子"
+      flavor: "感谢您使用 Misskey ! by 开发团队"
+    _outputHelloWorldOnScratchpad:
+      title: "Hello, world!"
+    _loggedInOnBirthday:
+      title: "生日快乐"
+      description: "在生日当天登录"
+    _loggedInOnNewYearsDay:
+      title: "恭贺新禧"
+      description: "在元旦登入"
 _role:
   new: "创建角色"
   edit: "编辑角色"
@@ -1587,6 +1663,7 @@ _notification:
   pollEnded: "问卷调查结果已生成。"
   unreadAntennaNote: "天线 {name}"
   emptyPushNotificationMessage: "推送通知已更新"
+  achievementEarned: "获得成就"
   _types:
     all: "全部"
     follow: "关注中"
diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml
index 025a4c3e5d..b88cfd91ae 100644
--- a/locales/zh-TW.yml
+++ b/locales/zh-TW.yml
@@ -989,11 +989,115 @@ _achievements:
       title: "貼文宇宙"
       description: "發表了90000則貼文"
     _notes100000:
+      title: "ALL YOUR NOTE ARE BELONG TO US"
       description: "發表了100,000則貼文"
       flavor: "有這麼多東西要寫嗎?"
     _login3:
-      title: "初學者 I"
+      title: "初學者Ⅰ"
       description: "總登入天數為3天"
+      flavor: "從今天開始,我就是Misskeyist"
+    _login7:
+      title: "初學者ⅠⅠ"
+      description: "總登入天數為7天"
+      flavor: "您開始習慣了嗎?"
+    _login15:
+      title: "初學者III"
+      description: "總登入天數為15天"
+    _login30:
+      title: "Misskeyist Ⅰ"
+      description: "總登入天數為30天"
+    _login60:
+      title: "Misskeyist ⅠⅠ"
+      description: "總登入天數為60天"
+    _login100:
+      title: "Misskeyist ⅠⅠⅠ"
+      description: "總登入天數為100天"
+      flavor: "辣個 Misskeyist 用戶"
+    _login200:
+      title: "普通Ⅰ"
+      description: "總登入天數為200天"
+    _login300:
+      title: "普通IⅠ"
+      description: "總登入天數為300天"
+    _login400:
+      title: "普通IIⅠ"
+      description: "總登入天數為400天"
+    _login500:
+      title: "老兵Ⅰ"
+      description: "總登入天數為500天"
+      flavor: "諸君,我喜歡貼文"
+    _login600:
+      title: "老兵ⅠⅠ"
+      description: "總登入天數為600天"
+    _login700:
+      title: "老兵ⅠⅠⅠ"
+      description: "總登入天數為700天"
+    _login800:
+      title: "貼文大師Ⅰ"
+      description: "總登入天數為800天"
+    _login900:
+      title: "貼文大師ⅠⅠ"
+      description: "總登入天數為900天"
+    _login1000:
+      title: "貼文大師ⅠⅠⅠ"
+      description: "總登入天數為1,000天"
+      flavor: "感謝您使用Misskey!"
+    _followers500:
+      title: "基站"
+      description: "超過500名追隨者"
+    _followers1000:
+      title: "影響者"
+      description: "超過1000名追隨者"
+    _collectAchievements30:
+      title: "成就收藏家"
+      description: "獲得30個以上的成就"
+    _viewAchievements3min:
+      title: "喜愛成就"
+      description: "看成就列表要花了3分鐘以上"
+    _iLoveMisskey:
+      title: "I Love Misskey"
+      description: "發布「I ❤ #Misskey」"
+      flavor: "感謝您使用Misskey! by 開發團隊"
+    _client30min:
+      title: "休息一下"
+      description: "用戶端啟動已超過30分鐘"
+    _noteDeletedWithin1min:
+      title: "現在沒有"
+      description: "發文後1分鐘內刪文"
+    _postedAtLateNight:
+      title: "夜行性"
+      description: "在深夜發佈貼文"
+      flavor: "該去睡覺了。"
+    _postedAt0min0sec:
+      title: "報時"
+      description: "在0分0秒發佈貼文"
+    _selfQuote:
+      title: "自我引用"
+      description: "引用了自己的貼文"
+    _htl20npm:
+      title: "流動的TL"
+      description: "在首頁時間軸的流速超過20npm"
+    _outputHelloWorldOnScratchpad:
+      title: "Hello world!"
+      description: "在暫存記憶體輸出了 hello world"
+    _open3windows:
+      title: "多重視窗"
+      description: "開啟3個以上的視窗"
+    _driveFolderCircularReference:
+      title: "循環引用"
+      description: "試圖遞迴套入雲端硬碟資料夾"
+    _reactWithoutRead:
+      title: "有好好讀過嗎?"
+      description: "對包含100字以上內容的貼文做出情感反應"
+    _clickedClickHere:
+      title: "點擊這裡"
+      description: "已點擊這裡了"
+    _justPlainLucky:
+      title: "只是運氣好"
+      description: "每10秒有0.01%的機率獲得"
+    _setNameToSyuilo:
+      title: "神的情結"
+      description: "將名稱設定為 syuilo"
 _role:
   new: "建立角色"
   edit: "編輯角色"

From 7800a12e526f839ce3e0b5248e521b67cb51d347 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 22 Jan 2023 04:28:43 +0900
Subject: [PATCH 7/7] 13.1.1

---
 CHANGELOG.md | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca8379bcfd..1841be3fb3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,15 @@
 You should also include the user name that made the change.
 -->
 
+## 13.1.1 (2023/01/22)
+
+### Improvements
+- ローカルのカスタム絵文字を表示する際のパフォーマンスを改善
+- Client: 瞬間的に大量の実績を解除した際の挙動を改善
+
+### Bugfixes
+- Client: アップデート時にローカリゼーションデータが更新されないことがあるのを修正
+
 ## 13.1.0 (2023/01/21)
 
 ### Improvements