explotion

This commit is contained in:
sim1222 2024-10-15 02:43:15 +09:00
parent bca8bff586
commit c3d07c8f1e
Signed by: sim1222
GPG Key ID: D1AE30E316E44E5D
9 changed files with 2839 additions and 193 deletions

2
.gitignore vendored
View File

@ -47,3 +47,5 @@ ormconfig.json
*.blend5
start.sh
/packages/client/dist

View File

@ -0,0 +1,84 @@
<!doctype html>
<!---
_____ _ _
| |_|___ ___| |_ ___ _ _
| | | | |_ -|_ -| '_| -_| | |
|_|_|_|_|___|___|_,_|___|_ |
|___|
Thank you for using Misskey!
If you are reading this message... how about joining the development?
https://github.com/misskey-dev/misskey
-->
<html>
<head>
<meta charset="utf-8" />
<meta name="application-name" content="Misskey" />
<meta name="referrer" content="origin" />
<meta name="theme-color" content="#a7dc4e" />
<meta name="theme-color-orig" content="#a7dc4e" />
<meta property="twitter:card" content="summary" />
<meta property="og:site_name" content="simkey.net" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="manifest" href="/manifest.json" />
<link rel="prefetch" href="https://xn--931a.moe/assets/info.jpg" />
<link rel="prefetch" href="https://xn--931a.moe/assets/not-found.jpg" />
<link rel="prefetch" href="https://xn--931a.moe/assets/error.jpg" />
<link rel="stylesheet" href="/assets/fontawesome/css/all.min.css" />
<!-- <link rel="preload" href="/assets/app-CT9YOazo.css" as="style" /> -->
<title>✨🌎✨ A interplanetary communication platform ✨🚀✨</title>
<meta
name="description"
content="✨🌎✨ A interplanetary communication platform ✨🚀✨"
/>
<meta name="og:title" content="Misskey" />
<meta
name="og:description"
content="✨🌎✨ A interplanetary communication platform ✨🚀✨"
/>
<style>
{{{CLIENT_CSS}}}
</style>
<script>
var VERSION = "f";
var CLIENT_ENTRY = "{{{CLIENT_ENTRY_JS_NAME}}}";
</script>
<script type="module" src="/src/boot.js"></script>
</head>
<body>
<div id="splash">
<img id="splashIcon" src="/static-assets/splash.png" />
<div id="splashSpinner">
<svg
class="spinner bg"
viewBox="0 0 152 152"
xmlns="http://www.w3.org/2000/svg"
>
<g transform="matrix(1,0,0,1,12,12)">
<circle
cx="64"
cy="64"
r="64"
style="fill: none; stroke: currentColor; stroke-width: 24px"
/>
</g>
</svg>
<svg
class="spinner fg"
viewBox="0 0 152 152"
xmlns="http://www.w3.org/2000/svg"
>
<g transform="matrix(1,0,0,1,12,12)">
<path
d="M128,64C128,28.654 99.346,0 64,0C99.346,0 128,28.654 128,64Z"
style="fill: none; stroke: currentColor; stroke-width: 24px"
/>
</g>
</svg>
</div>
</div>
<script type="module" src="/src/init.ts"></script>
</body>
</html>

View File

@ -3,6 +3,7 @@
"scripts": {
"watch": "vite build --watch --mode development",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint --quiet \"src/**/*.{ts,vue}\"",
"typecheck:vue": "vue-tsc --noEmit",
"typecheck:tsc": "tsc -p . --noEmit"
@ -64,6 +65,7 @@
"uuid": "10.0.0",
"vanilla-tilt": "1.8.1",
"vite": "5.4.8",
"vite-plugin-pug": "0.4.1",
"vue": "3.5.12",
"vue-prism-editor": "2.0.0-alpha.2",
"vuedraggable": "4.0.1"

335
packages/client/src/boot.js Normal file
View File

@ -0,0 +1,335 @@
/**
* BOOT LOADER
* サーバーからレスポンスされるHTMLに埋め込まれるスクリプトで以下の役割を持ちます
* - 翻訳ファイルをフェッチする
* - バージョンに基づいて適切なメインスクリプトを読み込む
* - キャッシュされたコンパイル済みテーマを適用する
* - クライアントの設定値に基づいて対応するHTMLクラス等を設定する
* テーマをこの段階で設定するのはメインスクリプトが読み込まれる間もテーマを適用したいためです
* : webpackは介さないためこのファイルではrequireやimportは使えません
*/
"use strict";
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
(async () => {
window.onerror = (e) => {
console.error(e);
renderError("SOMETHING_HAPPENED", e);
};
window.onunhandledrejection = (e) => {
console.error(e);
renderError("SOMETHING_HAPPENED_IN_PROMISE", e);
};
const v = localStorage.getItem("v") || VERSION;
//#region Detect language & fetch translations
const localeVersion = localStorage.getItem("localeVersion");
const localeOutdated = localeVersion == null || localeVersion !== v;
if (!localStorage.hasOwnProperty("locale") || localeOutdated) {
const supportedLangs = ["ja-NY", "ja-JP", "en-US"];
let lang = localStorage.getItem("lang");
if (lang == null || !supportedLangs.includes(lang)) {
if (supportedLangs.includes(navigator.language)) {
lang = navigator.language;
if (lang === "ja-JP") {
lang = "ja-NY";
}
} else {
lang = supportedLangs.find(
(x) => x.split("-")[0] === navigator.language,
);
// Fallback
if (lang == null) lang = "en-US";
}
}
const res = await fetch(`/assets/locales/${lang}.${v}.json`);
const fallback = await fetch(`/assets/locales/ja-JP.${v}.json`);
if (res.status === 200 && fallback.status === 200) {
const merged = { ...(await fallback.json()), ...(await res.json()) };
localStorage.setItem("lang", lang);
localStorage.setItem("locale", JSON.stringify(merged));
localStorage.setItem("localeVersion", v);
} else {
await checkUpdate();
renderError("LOCALE_FETCH");
return;
}
}
//#endregion
//#region Script
function importAppScript() {
import(`/assets/${CLIENT_ENTRY}`).catch(async (e) => {
await checkUpdate();
console.error(e);
renderError("APP_IMPORT", e);
});
}
// タイミングによっては、この時点でDOMの構築が済んでいる場合とそうでない場合とがある
if (document.readyState !== "loading") {
importAppScript();
} else {
window.addEventListener("DOMContentLoaded", () => {
importAppScript();
});
}
//#endregion
//#region Theme
const theme = localStorage.getItem("theme");
if (theme) {
for (const [k, v] of Object.entries(JSON.parse(theme))) {
document.documentElement.style.setProperty(`--${k}`, v.toString());
// HTMLの theme-color 適用
if (k === "htmlThemeColor") {
for (const tag of document.head.children) {
if (
tag.tagName === "META" &&
tag.getAttribute("name") === "theme-color"
) {
tag.setAttribute("content", v);
break;
}
}
}
}
}
const colorSchema = localStorage.getItem("colorSchema");
if (colorSchema) {
document.documentElement.style.setProperty("color-schema", colorSchema);
}
//#endregion
const fontSize = localStorage.getItem("fontSize");
if (fontSize) {
document.documentElement.classList.add("f-" + fontSize);
}
const useSystemFont = localStorage.getItem("useSystemFont");
if (useSystemFont) {
document.documentElement.classList.add("useSystemFont");
}
const wallpaper = localStorage.getItem("wallpaper");
if (wallpaper) {
document.documentElement.style.backgroundImage = `url(${wallpaper})`;
}
const customCss = localStorage.getItem("customCss");
if (customCss && customCss.length > 0) {
const style = document.createElement("style");
style.innerHTML = customCss;
document.head.appendChild(style);
}
async function addStyle(styleText) {
let css = document.createElement("style");
css.appendChild(document.createTextNode(styleText));
document.head.appendChild(css);
}
function renderError(code, details) {
let errorsElement = document.getElementById("errors");
if (!errorsElement) {
document.body.innerHTML = `
<svg class="icon-warning" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-alert-triangle" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 9v2m0 4v.01"></path>
<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
</svg>
<h1>An error has occurred!</h1>
<button class="button-big" onclick="location.reload(true);">
<span class="button-label-big">Refresh</span>
</button>
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
<p>If the problem persists after refreshing, please contact your instance's administrator.<br>You may also try the following options:</p>
<p>Update your os and browser.</p>
<p>Disable an adblocker.</p>
<a href="/flush">
<button class="button-small">
<span class="button-label-small">Clear preferences and cache</span>
</button>
</a>
<br>
<a href="/cli">
<button class="button-small">
<span class="button-label-small">Start the simple client</span>
</button>
</a>
<br>
<a href="/bios">
<button class="button-small">
<span class="button-label-small">Start the repair tool</span>
</button>
</a>
<br>
<div id="errors"></div>
`;
errorsElement = document.getElementById("errors");
}
const detailsElement = document.createElement("details");
detailsElement.innerHTML = `
<br>
<summary>
<code>ERROR CODE: ${code}</code>
</summary>
<code>${JSON.stringify(details)}</code>`;
errorsElement.appendChild(detailsElement);
addStyle(`
* {
font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
}
#misskey_app,
#splash {
display: none !important;
}
body,
html {
background-color: #222;
color: #dfddcc;
justify-content: center;
margin: auto;
padding: 10px;
text-align: center;
}
button {
border-radius: 999px;
padding: 0px 12px 0px 12px;
border: none;
cursor: pointer;
margin-bottom: 12px;
}
.button-big {
background: linear-gradient(90deg, rgb(134, 179, 0), rgb(74, 179, 0));
line-height: 50px;
}
.button-big:hover {
background: rgb(153, 204, 0);
}
.button-small {
background: #444;
line-height: 40px;
}
.button-small:hover {
background: #555;
}
.button-label-big {
color: #222;
font-weight: bold;
font-size: 20px;
padding: 12px;
}
.button-label-small {
color: rgb(153, 204, 0);
font-size: 16px;
padding: 12px;
}
a {
color: rgb(134, 179, 0);
text-decoration: none;
}
p,
li {
font-size: 16px;
}
.dont-worry,
#msg {
font-size: 18px;
}
.icon-warning {
color: #dec340;
height: 4rem;
padding-top: 2rem;
}
h1 {
font-size: 32px;
}
code {
font-family: Fira, FiraCode, monospace;
}
details {
background: #333;
margin-bottom: 2rem;
padding: 0.5rem 1rem;
width: 40rem;
border-radius: 10px;
justify-content: center;
margin: auto;
}
summary {
cursor: pointer;
}
summary > * {
display: inline;
}
@media screen and (max-width: 500px) {
details {
width: 50%;
}
`);
}
// eslint-disable-next-line no-inner-declarations
async function checkUpdate() {
try {
const res = await fetch("/api/meta", {
method: "POST",
cache: "no-cache",
});
const meta = await res.json();
if (meta.version != v) {
localStorage.setItem("v", meta.version);
refresh();
}
} catch (e) {
console.error(e);
renderError("UPDATE_CHECK", e);
throw e;
}
}
// eslint-disable-next-line no-inner-declarations
function refresh() {
// Clear cache (service worker)
try {
navigator.serviceWorker.controller.postMessage("clear");
navigator.serviceWorker.getRegistrations().then((registrations) => {
registrations.forEach((registration) => registration.unregister());
});
} catch (e) {
console.error(e);
}
location.reload();
}
})();

File diff suppressed because it is too large Load Diff

View File

@ -1,56 +1,64 @@
/**
* Client entry point
*/
import "@/style.css";
import '@/style.scss';
import "@/style.scss";
//#region account indexedDB migration
import { set } from '@/scripts/idb-proxy';
import { set } from "@/scripts/idb-proxy";
if (localStorage.getItem('accounts') != null) {
set('accounts', JSON.parse(localStorage.getItem('accounts')));
localStorage.removeItem('accounts');
if (localStorage.getItem("accounts") != null) {
set("accounts", JSON.parse(localStorage.getItem("accounts")));
localStorage.removeItem("accounts");
}
//#endregion
import { computed, createApp, watch, markRaw, version as vueVersion, defineAsyncComponent } from 'vue';
import { compareVersions } from 'compare-versions';
import JSON5 from 'json5';
import {
computed,
createApp,
watch,
markRaw,
version as vueVersion,
defineAsyncComponent,
} from "vue";
import { compareVersions } from "compare-versions";
import JSON5 from "json5";
import widgets from '@/widgets';
import directives from '@/directives';
import components from '@/components';
import { version, ui, lang, host } from '@/config';
import { applyTheme } from '@/scripts/theme';
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode';
import { i18n } from '@/i18n';
import { confirm, alert, post, popup, toast } from '@/os';
import { stream } from '@/stream';
import * as sound from '@/scripts/sound';
import { $i, refreshAccount, login, updateAccount, signout } from '@/account';
import { defaultStore, ColdDeviceStorage } from '@/store';
import { fetchInstance, instance } from '@/instance';
import { makeHotkey } from '@/scripts/hotkey';
import { search } from '@/scripts/search';
import { deviceKind } from '@/scripts/device-kind';
import { initializeSw } from '@/scripts/initialize-sw';
import { reloadChannel } from '@/scripts/unison-reload';
import { reactionPicker } from '@/scripts/reaction-picker';
import { getUrlWithoutLoginId } from '@/scripts/login-id';
import { getAccountFromId } from '@/scripts/get-account-from-id';
import widgets from "@/widgets";
import directives from "@/directives";
import components from "@/components";
import { version, ui, lang, host } from "@/config";
import { applyTheme } from "@/scripts/theme";
import { isDeviceDarkmode } from "@/scripts/is-device-darkmode";
import { i18n } from "@/i18n";
import { confirm, alert, post, popup, toast } from "@/os";
import { stream } from "@/stream";
import * as sound from "@/scripts/sound";
import { $i, refreshAccount, login, updateAccount, signout } from "@/account";
import { defaultStore, ColdDeviceStorage } from "@/store";
import { fetchInstance, instance } from "@/instance";
import { makeHotkey } from "@/scripts/hotkey";
import { search } from "@/scripts/search";
import { deviceKind } from "@/scripts/device-kind";
import { initializeSw } from "@/scripts/initialize-sw";
import { reloadChannel } from "@/scripts/unison-reload";
import { reactionPicker } from "@/scripts/reaction-picker";
import { getUrlWithoutLoginId } from "@/scripts/login-id";
import { getAccountFromId } from "@/scripts/get-account-from-id";
(async () => {
console.info(`Misskey v${version}`);
if (_DEV_) {
console.warn('Development mode!!!');
console.warn("Development mode!!!");
console.info(`vue ${vueVersion}`);
(window as any).$i = $i;
(window as any).$store = defaultStore;
window.addEventListener('error', event => {
window.addEventListener("error", (event) => {
console.error(event);
/*
alert({
@ -61,7 +69,7 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
*/
});
window.addEventListener('unhandledrejection', event => {
window.addEventListener("unhandledrejection", (event) => {
console.error(event);
/*
alert({
@ -74,10 +82,10 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
}
// タッチデバイスでCSSの:hoverを機能させる
document.addEventListener('touchend', () => {}, { passive: true });
document.addEventListener("touchend", () => { }, { passive: true });
// 一斉リロード
reloadChannel.addEventListener('message', path => {
reloadChannel.addEventListener("message", (path) => {
if (path !== null) location.href = path;
else location.reload();
});
@ -85,28 +93,30 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
//#region SEE: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
// TODO: いつの日にか消したい
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
window.addEventListener('resize', () => {
document.documentElement.style.setProperty("--vh", `${vh}px`);
window.addEventListener("resize", () => {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
document.documentElement.style.setProperty("--vh", `${vh}px`);
});
//#endregion
// If mobile, insert the viewport meta tag
if (['smartphone', 'tablet'].includes(deviceKind)) {
const viewport = document.getElementsByName('viewport').item(0);
viewport.setAttribute('content',
`${viewport.getAttribute('content')}, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`);
if (["smartphone", "tablet"].includes(deviceKind)) {
const viewport = document.getElementsByName("viewport").item(0);
viewport.setAttribute(
"content",
`${viewport.getAttribute("content")}, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`,
);
}
//#region Set lang attr
const html = document.documentElement;
html.setAttribute('lang', lang);
html.setAttribute("lang", lang);
//#endregion
//#region loginId
const params = new URLSearchParams(location.search);
const loginId = params.get('loginId');
const loginId = params.get("loginId");
if (loginId) {
const target = getUrlWithoutLoginId(location.href);
@ -118,7 +128,7 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
}
}
history.replaceState({ misskey: 'loginId' }, '', target);
history.replaceState({ misskey: "loginId" }, "", target);
}
//#endregion
@ -126,25 +136,25 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
//#region Fetch user
if ($i && $i.token) {
if (_DEV_) {
console.log('account cache found. refreshing...');
console.log("account cache found. refreshing...");
}
refreshAccount();
} else {
if (_DEV_) {
console.log('no account cache found.');
console.log("no account cache found.");
}
// 連携ログインの場合用にCookieを参照する
const i = (document.cookie.match(/igi=(\w+)/) || [null, null])[1];
if (i != null && i !== 'null') {
if (i != null && i !== "null") {
if (_DEV_) {
console.log('signing...');
console.log("signing...");
}
try {
document.body.innerHTML = '<div>Please wait...</div>';
document.body.innerHTML = "<div>Please wait...</div>";
await login(i);
} catch (err) {
// Render the error screen
@ -153,7 +163,7 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
}
} else {
if (_DEV_) {
console.log('not signed in');
console.log("not signed in");
}
}
}
@ -162,19 +172,24 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
const fetchInstanceMetaPromise = fetchInstance();
fetchInstanceMetaPromise.then(() => {
localStorage.setItem('v', instance.version);
localStorage.setItem("v", instance.version);
// Init service worker
initializeSw();
});
const app = createApp(
window.location.search === '?zen' ? defineAsyncComponent(() => import('@/ui/zen.vue')) :
!$i ? defineAsyncComponent(() => import('@/ui/visitor.vue')) :
ui === 'deck' ? defineAsyncComponent(() => import('@/ui/deck.vue')) :
ui === 'deckold' ? defineAsyncComponent(() => import('@/ui/deckold.vue')) :
ui === 'classic' ? defineAsyncComponent(() => import('@/ui/classic.vue')) :
defineAsyncComponent(() => import('@/ui/universal.vue')),
window.location.search === "?zen"
? defineAsyncComponent(() => import("@/ui/zen.vue"))
: !$i
? defineAsyncComponent(() => import("@/ui/visitor.vue"))
: ui === "deck"
? defineAsyncComponent(() => import("@/ui/deck.vue"))
: ui === "deckold"
? defineAsyncComponent(() => import("@/ui/deckold.vue"))
: ui === "classic"
? defineAsyncComponent(() => import("@/ui/classic.vue"))
: defineAsyncComponent(() => import("@/ui/universal.vue")),
);
if (_DEV_) {
@ -193,25 +208,26 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
directives(app);
components(app);
const splash = document.getElementById('splash');
const splash = document.getElementById("splash");
// 念のためnullチェック(HTMLが古い場合があるため(そのうち消す))
if (splash) splash.addEventListener('transitionend', () => {
if (splash)
splash.addEventListener("transitionend", () => {
splash.remove();
});
// https://github.com/misskey-dev/misskey/pull/8575#issuecomment-1114239210
// なぜかinit.tsの内容が2回実行されることがあるため、mountするdivを1つに制限する
const rootEl = (() => {
const MISSKEY_MOUNT_DIV_ID = 'misskey_app';
const MISSKEY_MOUNT_DIV_ID = "misskey_app";
const currentEl = document.getElementById(MISSKEY_MOUNT_DIV_ID);
if (currentEl) {
console.warn('multiple import detected');
console.warn("multiple import detected");
return currentEl;
}
const rootEl = document.createElement('div');
const rootEl = document.createElement("div");
rootEl.id = MISSKEY_MOUNT_DIV_ID;
document.body.appendChild(rootEl);
return rootEl;
@ -226,36 +242,49 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
reactionPicker.init();
if (splash) {
splash.style.opacity = '0';
splash.style.pointerEvents = 'none';
splash.style.opacity = "0";
splash.style.pointerEvents = "none";
}
// クライアントが更新されたか?
const lastVersion = localStorage.getItem('lastVersion');
const lastVersion = localStorage.getItem("lastVersion");
if (lastVersion !== version) {
localStorage.setItem('lastVersion', version);
localStorage.setItem("lastVersion", version);
// テーマリビルドするため
localStorage.removeItem('theme');
localStorage.removeItem("theme");
try { // 変なバージョン文字列来るとcompareVersionsでエラーになるため
try {
// 変なバージョン文字列来るとcompareVersionsでエラーになるため
if (lastVersion != null && compareVersions(version, lastVersion) === 1) {
// ログインしてる場合だけ
if ($i) {
popup(defineAsyncComponent(() => import('@/components/MkUpdated.vue')), {}, {}, 'closed');
popup(
defineAsyncComponent(() => import("@/components/MkUpdated.vue")),
{},
{},
"closed",
);
}
}
} catch (err) {
}
} catch (err) { }
}
// NOTE: この処理は必ず↑のクライアント更新時処理より後に来ること(テーマ再構築のため)
watch(defaultStore.reactiveState.darkMode, (darkMode) => {
applyTheme(darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme'));
}, { immediate: localStorage.theme == null });
watch(
defaultStore.reactiveState.darkMode,
(darkMode) => {
applyTheme(
darkMode
? ColdDeviceStorage.get("darkTheme")
: ColdDeviceStorage.get("lightTheme"),
);
},
{ immediate: localStorage.theme == null },
);
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter('darkTheme'));
const lightTheme = computed(ColdDeviceStorage.makeGetterSetter('lightTheme'));
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter("darkTheme"));
const lightTheme = computed(ColdDeviceStorage.makeGetterSetter("lightTheme"));
watch(darkTheme, (theme) => {
if (defaultStore.state.darkMode) {
@ -270,46 +299,65 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
});
//#region Sync dark mode
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
defaultStore.set('darkMode', isDeviceDarkmode());
if (ColdDeviceStorage.get("syncDeviceDarkMode")) {
defaultStore.set("darkMode", isDeviceDarkmode());
}
window.matchMedia('(prefers-color-scheme: dark)').addListener(mql => {
if (ColdDeviceStorage.get('syncDeviceDarkMode')) {
defaultStore.set('darkMode', mql.matches);
window.matchMedia("(prefers-color-scheme: dark)").addListener((mql) => {
if (ColdDeviceStorage.get("syncDeviceDarkMode")) {
defaultStore.set("darkMode", mql.matches);
}
});
//#endregion
fetchInstanceMetaPromise.then(() => {
if (defaultStore.state.themeInitial) {
if (instance.defaultLightTheme != null) ColdDeviceStorage.set('lightTheme', JSON5.parse(instance.defaultLightTheme));
if (instance.defaultDarkTheme != null) ColdDeviceStorage.set('darkTheme', JSON5.parse(instance.defaultDarkTheme));
defaultStore.set('themeInitial', false);
if (instance.defaultLightTheme != null)
ColdDeviceStorage.set(
"lightTheme",
JSON5.parse(instance.defaultLightTheme),
);
if (instance.defaultDarkTheme != null)
ColdDeviceStorage.set(
"darkTheme",
JSON5.parse(instance.defaultDarkTheme),
);
defaultStore.set("themeInitial", false);
}
});
watch(defaultStore.reactiveState.useBlurEffectForModal, v => {
document.documentElement.style.setProperty('--modalBgFilter', v ? 'blur(4px)' : 'none');
}, { immediate: true });
watch(
defaultStore.reactiveState.useBlurEffectForModal,
(v) => {
document.documentElement.style.setProperty(
"--modalBgFilter",
v ? "blur(4px)" : "none",
);
},
{ immediate: true },
);
watch(defaultStore.reactiveState.useBlurEffect, v => {
watch(
defaultStore.reactiveState.useBlurEffect,
(v) => {
if (v) {
document.documentElement.style.removeProperty('--blur');
document.documentElement.style.removeProperty("--blur");
} else {
document.documentElement.style.setProperty('--blur', 'none');
document.documentElement.style.setProperty("--blur", "none");
}
}, { immediate: true });
},
{ immediate: true },
);
let reloadDialogShowing = false;
stream.on('_disconnected_', async () => {
if (defaultStore.state.serverDisconnectedBehavior === 'reload') {
stream.on("_disconnected_", async () => {
if (defaultStore.state.serverDisconnectedBehavior === "reload") {
location.reload();
} else if (defaultStore.state.serverDisconnectedBehavior === 'dialog') {
} else if (defaultStore.state.serverDisconnectedBehavior === "dialog") {
if (reloadDialogShowing) return;
reloadDialogShowing = true;
const { canceled } = await confirm({
type: 'warning',
type: "warning",
title: i18n.ts.disconnectedFromServer,
text: i18n.ts.reloadConfirm,
});
@ -320,127 +368,134 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
}
});
stream.on('emojiAdded', emojiData => {
stream.on("emojiAdded", (emojiData) => {
// TODO
//store.commit('instance/set', );
});
for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) {
import('./plugin').then(({ install }) => {
for (const plugin of ColdDeviceStorage.get("plugins").filter(
(p) => p.active,
)) {
import("./plugin").then(({ install }) => {
install(plugin);
});
}
const hotkeys = {
'd': (): void => {
defaultStore.set('darkMode', !defaultStore.state.darkMode);
d: (): void => {
defaultStore.set("darkMode", !defaultStore.state.darkMode);
},
's': search,
s: search,
};
if (!$i) {
localStorage.setItem('wallpaper', 'https://simkey.net/files/c2f30819-64f7-42df-91b6-0e7fb122a413');
localStorage.setItem(
"wallpaper",
"https://simkey.net/files/c2f30819-64f7-42df-91b6-0e7fb122a413",
);
}
if ($i) {
// only add post shortcuts if logged in
hotkeys['p|n'] = post;
hotkeys["p|n"] = post;
if ($i.isDeleted) {
alert({
type: 'warning',
type: "warning",
text: i18n.ts.accountDeletionInProgress,
});
}
const lastUsed = localStorage.getItem('lastUsed');
const lastUsed = localStorage.getItem("lastUsed");
if (lastUsed) {
const lastUsedDate = parseInt(lastUsed, 10);
// 二時間以上前なら
if (Date.now() - lastUsedDate > 1000 * 60 * 60 * 2) {
toast(i18n.t('welcomeBackWithName', {
toast(
i18n.t("welcomeBackWithName", {
name: $i.name || $i.username,
}));
}),
);
}
}
localStorage.setItem('lastUsed', Date.now().toString());
localStorage.setItem("lastUsed", Date.now().toString());
if ('Notification' in window) {
if ("Notification" in window) {
// 許可を得ていなかったらリクエスト
if (Notification.permission === 'default') {
if (Notification.permission === "default") {
Notification.requestPermission();
}
}
const main = markRaw(stream.useChannel('main', null, 'System'));
const main = markRaw(stream.useChannel("main", null, "System"));
// 自分の情報が更新されたとき
main.on('meUpdated', i => {
main.on("meUpdated", (i) => {
updateAccount(i);
});
main.on('readAllNotifications', () => {
main.on("readAllNotifications", () => {
updateAccount({ hasUnreadNotification: false });
});
main.on('unreadNotification', () => {
main.on("unreadNotification", () => {
updateAccount({ hasUnreadNotification: true });
});
main.on('unreadMention', () => {
main.on("unreadMention", () => {
updateAccount({ hasUnreadMentions: true });
});
main.on('readAllUnreadMentions', () => {
main.on("readAllUnreadMentions", () => {
updateAccount({ hasUnreadMentions: false });
});
main.on('unreadSpecifiedNote', () => {
main.on("unreadSpecifiedNote", () => {
updateAccount({ hasUnreadSpecifiedNotes: true });
});
main.on('readAllUnreadSpecifiedNotes', () => {
main.on("readAllUnreadSpecifiedNotes", () => {
updateAccount({ hasUnreadSpecifiedNotes: false });
});
main.on('readAllMessagingMessages', () => {
main.on("readAllMessagingMessages", () => {
updateAccount({ hasUnreadMessagingMessage: false });
});
main.on('unreadMessagingMessage', () => {
main.on("unreadMessagingMessage", () => {
updateAccount({ hasUnreadMessagingMessage: true });
sound.play('chatBg');
sound.play("chatBg");
});
main.on('readAllAntennas', () => {
main.on("readAllAntennas", () => {
updateAccount({ hasUnreadAntenna: false });
});
main.on('unreadAntenna', () => {
main.on("unreadAntenna", () => {
updateAccount({ hasUnreadAntenna: true });
sound.play('antenna');
sound.play("antenna");
});
main.on('readAllAnnouncements', () => {
main.on("readAllAnnouncements", () => {
updateAccount({ hasUnreadAnnouncement: false });
});
main.on('readAllChannels', () => {
main.on("readAllChannels", () => {
updateAccount({ hasUnreadChannel: false });
});
main.on('unreadChannel', () => {
main.on("unreadChannel", () => {
updateAccount({ hasUnreadChannel: true });
sound.play('channel');
sound.play("channel");
});
// トークンが再生成されたとき
// このままではMisskeyが利用できないので強制的にサインアウトさせる
main.on('myTokenRegenerated', () => {
main.on("myTokenRegenerated", () => {
signout();
});
}
// shortcut
document.addEventListener('keydown', makeHotkey(hotkeys));
document.addEventListener("keydown", makeHotkey(hotkeys));
})();

View File

@ -0,0 +1,70 @@
html {
background-color: var(--bg);
color: var(--fg);
}
#splash {
position: fixed;
z-index: 10000;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
cursor: wait;
background-color: var(--bg);
opacity: 1;
transition: opacity 0.5s ease;
}
#splashIcon {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 64px;
height: 64px;
pointer-events: none;
}
#splashSpinner {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
display: inline-block;
width: 28px;
height: 28px;
transform: translateY(70px);
color: var(--accent);
}
#splashSpinner > .spinner {
position: absolute;
top: 0;
left: 0;
width: 28px;
height: 28px;
fill-rule: evenodd;
clip-rule: evenodd;
stroke-linecap: round;
stroke-linejoin: round;
stroke-miterlimit: 1.5;
}
#splashSpinner > .spinner.bg {
opacity: 0.275;
}
#splashSpinner > .spinner.fg {
animation: splashSpinner 0.5s linear infinite;
}
@keyframes splashSpinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@ -1,43 +1,59 @@
import * as fs from 'fs';
import pluginVue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';
import * as fs from "fs";
import pluginVue from "@vitejs/plugin-vue";
import { defineConfig } from "vite";
import locales from '../../locales';
import meta from '../../package.json';
import pluginJson5 from './vite.json5';
import locales from "../../locales";
import meta from "../../package.json";
import pluginJson5 from "./vite.json5";
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json', '.json5', '.svg', '.sass', '.scss', '.css', '.vue'];
const extensions = [
".ts",
".tsx",
".js",
".jsx",
".mjs",
".json",
".json5",
".svg",
".sass",
".scss",
".css",
".vue",
];
export default defineConfig(({ command, mode }) => {
fs.mkdirSync(__dirname + '/../../built', { recursive: true });
fs.writeFileSync(__dirname + '/../../built/meta.json', JSON.stringify({ version: meta.version }), 'utf-8');
fs.mkdirSync(__dirname + "/../../built", { recursive: true });
fs.writeFileSync(
__dirname + "/../../built/meta.json",
JSON.stringify({ version: meta.version }),
"utf-8",
);
return {
base: '/assets/',
// base: '/assets/',
plugins: [
pluginVue(),
pluginJson5(),
],
plugins: [pluginVue(), pluginJson5()],
resolve: {
extensions,
alias: {
'@/': __dirname + '/src/',
'/client-assets/': __dirname + '/assets/',
'/static-assets/': __dirname + '/../backend/assets/',
"@/": __dirname + "/src/",
"/client-assets/": __dirname + "/assets/",
"/static-assets/": __dirname + "/../backend/assets/",
},
},
define: {
_VERSION_: JSON.stringify(meta.version),
_LANGS_: JSON.stringify(Object.entries(locales).map(([k, v]) => [k, v._lang_])),
_LANGS_: JSON.stringify(
Object.entries(locales).map(([k, v]) => [k, v._lang_]),
),
_ENV_: JSON.stringify(process.env.NODE_ENV),
_DEV_: process.env.NODE_ENV !== 'production',
_PERF_PREFIX_: JSON.stringify('Misskey:'),
_DATA_TRANSFER_DRIVE_FILE_: JSON.stringify('mk_drive_file'),
_DATA_TRANSFER_DRIVE_FOLDER_: JSON.stringify('mk_drive_folder'),
_DATA_TRANSFER_DECK_COLUMN_: JSON.stringify('mk_deck_column'),
_DEV_: process.env.NODE_ENV !== "production",
_PERF_PREFIX_: JSON.stringify("Misskey:"),
_DATA_TRANSFER_DRIVE_FILE_: JSON.stringify("mk_drive_file"),
_DATA_TRANSFER_DRIVE_FOLDER_: JSON.stringify("mk_drive_folder"),
_DATA_TRANSFER_DECK_COLUMN_: JSON.stringify("mk_deck_column"),
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
},
@ -45,34 +61,35 @@ export default defineConfig(({ command, mode }) => {
css: {
preprocessorOptions: {
scss: {
api: "modern-compiler"
}
}
api: "modern-compiler",
},
},
},
build: {
target: [
'chrome100',
'firefox100',
'safari15',
'es2017', // TODO: そのうち消す
"chrome100",
"firefox100",
"safari15",
"es2017", // TODO: そのうち消す
],
manifest: 'manifest.json',
manifest: "manifest.json",
rollupOptions: {
input: {
app: './src/init.ts',
},
output: {
manualChunks: {
vue: ['vue'],
},
app: "./index.html",
// app: "./src/init.ts",
},
// output: {
// manualChunks: {
// vue: ["vue"],
// },
// },
},
cssCodeSplit: true,
outDir: __dirname + '/../../built/_client_dist_',
assetsDir: '.',
// outDir: __dirname + '/../../built/_client_dist_',
assetsDir: "assets",
emptyOutDir: false,
sourcemap: process.env.NODE_ENV !== 'production',
sourcemap: process.env.NODE_ENV !== "production",
reportCompressedSize: false,
},
};

View File

@ -12,7 +12,7 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5"
integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==
"@babel/parser@^7.25.3":
"@babel/parser@^7.25.3", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6":
version "7.25.8"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2"
integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==
@ -26,7 +26,7 @@
dependencies:
regenerator-runtime "^0.14.0"
"@babel/types@^7.25.8":
"@babel/types@^7.25.8", "@babel/types@^7.6.1", "@babel/types@^7.9.6":
version "7.25.8"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1"
integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==
@ -1028,6 +1028,11 @@ acorn-jsx@^5.3.2:
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn@^7.1.1:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.12.0, acorn@^8.9.0:
version "8.12.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248"
@ -1169,6 +1174,11 @@ arraybuffer.prototype.slice@^1.0.3:
is-array-buffer "^3.0.4"
is-shared-array-buffer "^1.0.2"
asap@~2.0.3:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
asn1@~0.2.3:
version "0.2.6"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
@ -1176,6 +1186,11 @@ asn1@~0.2.3:
dependencies:
safer-buffer "~2.1.0"
assert-never@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.3.0.tgz#c53cf3ad8fcdb67f400a941dea66dac7fe82dd2e"
integrity sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ==
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
@ -1247,6 +1262,13 @@ axios@^1.7.7:
form-data "^4.0.0"
proxy-from-env "^1.1.0"
babel-walk@3.0.0-canary-5:
version "3.0.0-canary-5"
resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11"
integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==
dependencies:
"@babel/types" "^7.9.6"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -1385,6 +1407,13 @@ char-regex@^1.0.2:
resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
character-parser@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0"
integrity sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==
dependencies:
is-regex "^1.0.3"
chart.js@4.4.4:
version "4.4.4"
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.4.tgz#b682d2e7249f7a0cbb1b1d31c840266ae9db64b7"
@ -1529,6 +1558,14 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
constantinople@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151"
integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==
dependencies:
"@babel/parser" "^7.6.0"
"@babel/types" "^7.6.1"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@ -1731,6 +1768,11 @@ doctrine@^2.1.0:
dependencies:
esutils "^2.0.2"
doctypes@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9"
integrity sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==
duplexer@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
@ -2632,6 +2674,14 @@ is-date-object@^1.0.1:
dependencies:
has-tostringtag "^1.0.0"
is-expression@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab"
integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==
dependencies:
acorn "^7.1.1"
object-assign "^4.1.1"
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@ -2679,7 +2729,12 @@ is-path-inside@^3.0.2:
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
is-regex@^1.1.4:
is-promise@^2.0.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
is-regex@^1.0.3, is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
@ -2763,6 +2818,11 @@ joi@^17.13.3:
"@sideway/formula" "^3.0.1"
"@sideway/pinpoint" "^2.0.0"
js-stringify@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db"
integrity sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
@ -2847,6 +2907,14 @@ jsprim@^2.0.2:
json-schema "0.4.0"
verror "1.10.0"
jstransformer@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3"
integrity sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==
dependencies:
is-promise "^2.0.0"
promise "^7.0.1"
katex@0.16.11:
version "0.16.11"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.11.tgz#4bc84d5584f996abece5f01c6ad11304276a33f5"
@ -3070,6 +3138,11 @@ nth-check@^2.1.1:
dependencies:
boolbase "^1.0.0"
object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
object-inspect@^1.13.1:
version "1.13.2"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff"
@ -3249,7 +3322,7 @@ photoswipe@5.4.4:
resolved "https://registry.yarnpkg.com/photoswipe/-/photoswipe-5.4.4.tgz#e045dc036453493188d5c8665b0e8f1000ac4d6e"
integrity sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==
picocolors@^1.1.0:
picocolors@^1.1.0, picocolors@~1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59"
integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==
@ -3318,6 +3391,13 @@ process@^0.11.10:
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
promise@^7.0.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
dependencies:
asap "~2.0.3"
proxy-from-env@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
@ -3340,6 +3420,109 @@ psl@^1.1.33:
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
pug-attrs@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41"
integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==
dependencies:
constantinople "^4.0.1"
js-stringify "^1.0.2"
pug-runtime "^3.0.0"
pug-code-gen@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.3.tgz#58133178cb423fe1716aece1c1da392a75251520"
integrity sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==
dependencies:
constantinople "^4.0.1"
doctypes "^1.1.0"
js-stringify "^1.0.2"
pug-attrs "^3.0.0"
pug-error "^2.1.0"
pug-runtime "^3.0.1"
void-elements "^3.1.0"
with "^7.0.0"
pug-error@^2.0.0, pug-error@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.1.0.tgz#17ea37b587b6443d4b8f148374ec27b54b406e55"
integrity sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==
pug-filters@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e"
integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==
dependencies:
constantinople "^4.0.1"
jstransformer "1.0.0"
pug-error "^2.0.0"
pug-walk "^2.0.0"
resolve "^1.15.1"
pug-lexer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5"
integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==
dependencies:
character-parser "^2.2.0"
is-expression "^4.0.0"
pug-error "^2.0.0"
pug-linker@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708"
integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==
dependencies:
pug-error "^2.0.0"
pug-walk "^2.0.0"
pug-load@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662"
integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==
dependencies:
object-assign "^4.1.1"
pug-walk "^2.0.0"
pug-parser@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260"
integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==
dependencies:
pug-error "^2.0.0"
token-stream "1.0.0"
pug-runtime@^3.0.0, pug-runtime@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7"
integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==
pug-strip-comments@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e"
integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==
dependencies:
pug-error "^2.0.0"
pug-walk@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe"
integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==
pug@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.3.tgz#e18324a314cd022883b1e0372b8af3a1a99f7597"
integrity sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==
dependencies:
pug-code-gen "^3.0.3"
pug-filters "^4.0.0"
pug-lexer "^5.0.1"
pug-linker "^4.0.0"
pug-load "^3.0.0"
pug-parser "^6.0.0"
pug-runtime "^3.0.1"
pug-strip-comments "^2.0.0"
pump@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8"
@ -3434,7 +3617,7 @@ resolve-from@^4.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve@^1.22.4:
resolve@^1.15.1, resolve@^1.22.4:
version "1.22.8"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
@ -3849,6 +4032,11 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
token-stream@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4"
integrity sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==
tough-cookie@^4.1.3:
version "4.1.4"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36"
@ -4072,6 +4260,14 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
vite-plugin-pug@0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/vite-plugin-pug/-/vite-plugin-pug-0.4.1.tgz#81052780039c25995e5e54921c1feccaea9f2215"
integrity sha512-2M4qNpIgUV+zA63w566jyp3LpaIuSBMfghOzue7PYnFTms48Ux78Bp/ccRSaGRbFW9BkTxdqgi5h7xvBN7YruQ==
dependencies:
picocolors "~1"
pug "^3.0.3"
vite@5.4.8:
version "5.4.8"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.8.tgz#af548ce1c211b2785478d3ba3e8da51e39a287e8"
@ -4083,6 +4279,11 @@ vite@5.4.8:
optionalDependencies:
fsevents "~2.3.3"
void-elements@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==
vscode-uri@^3.0.8:
version "3.0.8"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f"
@ -4173,6 +4374,16 @@ which@^2.0.1:
dependencies:
isexe "^2.0.0"
with@^7.0.0:
version "7.0.2"
resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac"
integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==
dependencies:
"@babel/parser" "^7.9.6"
"@babel/types" "^7.9.6"
assert-never "^1.2.1"
babel-walk "3.0.0-canary-5"
word-wrap@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"