mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-24 00:01:03 +08:00
Clean the awful code.
This commit is contained in:
parent
98ffbec764
commit
569cd087e7
@ -1,6 +1,7 @@
|
|||||||
# 新聞解析 / News Analyze
|
# 新聞解析 / News Analyze
|
||||||
|
|
||||||
## Stack:
|
## Stack:
|
||||||
|
|
||||||
- Postgres
|
- Postgres
|
||||||
- Passport.js
|
- Passport.js
|
||||||
- Tailwind
|
- Tailwind
|
||||||
|
2
app.vue
2
app.vue
@ -2,7 +2,7 @@
|
|||||||
import "bootstrap-icons/font/bootstrap-icons.css";
|
import "bootstrap-icons/font/bootstrap-icons.css";
|
||||||
import "animate.css";
|
import "animate.css";
|
||||||
import "@fontsource/fira-sans";
|
import "@fontsource/fira-sans";
|
||||||
import '@fontsource-variable/noto-sans-tc';
|
import "@fontsource-variable/noto-sans-tc";
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -13,7 +13,6 @@ const availableLocales = computed(() => {
|
|||||||
const toggleDropdown = () => {
|
const toggleDropdown = () => {
|
||||||
dropdownOpen.value = !dropdownOpen.value;
|
dropdownOpen.value = !dropdownOpen.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<!--Spent too much time trying to set a Navbar....-->
|
<!--Spent too much time trying to set a Navbar....-->
|
||||||
@ -23,7 +22,9 @@ const toggleDropdown = () => {
|
|||||||
<div class="text-3xl text-bold">
|
<div class="text-3xl text-bold">
|
||||||
<NuxtLink :to="localePath('home')" ref="title">BlindSpec</NuxtLink>
|
<NuxtLink :to="localePath('home')" ref="title">BlindSpec</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[0.9em] left-1/2 absolute transform -translate-x-1/2 space-x-4 items-center">
|
<div
|
||||||
|
class="text-[0.9em] left-1/2 absolute transform -translate-x-1/2 space-x-4 items-center"
|
||||||
|
>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
:to="localePath('/home')"
|
:to="localePath('/home')"
|
||||||
class="hover:text-blue-500 cursor-pointer transiton-all duration-100"
|
class="hover:text-blue-500 cursor-pointer transiton-all duration-100"
|
||||||
@ -37,54 +38,56 @@ const toggleDropdown = () => {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row align-center justify-center text-center">
|
<div class="flex flex-row align-center justify-center text-center">
|
||||||
<div class="relative ml-0">
|
<div class="relative ml-0">
|
||||||
<button
|
<button
|
||||||
@click="toggleDropdown"
|
@click="toggleDropdown"
|
||||||
class="flex items-center space-x-1 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100 mr-5"
|
class="flex items-center space-x-1 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100 mr-5"
|
||||||
>
|
|
||||||
<span>{{ locale }}</span>
|
|
||||||
<svg
|
|
||||||
class="w-4 h-4"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
>
|
||||||
<path
|
<span>{{ locale }}</span>
|
||||||
stroke-linecap="round"
|
<svg
|
||||||
stroke-linejoin="round"
|
class="w-4 h-4"
|
||||||
stroke-width="2"
|
fill="none"
|
||||||
d="M19 9l-7 7-7-7"
|
stroke="currentColor"
|
||||||
/>
|
viewBox="0 0 24 24"
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<Transition
|
|
||||||
enter-active-class="animate__animated animate__fadeInDown animate_fastest"
|
|
||||||
leave-active-class="animate__animated animate__fadeOutUp animate_fastest"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-if="dropdownOpen"
|
|
||||||
class="absolute top-full right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
v-for="loc in availableLocales"
|
|
||||||
:key="loc.code"
|
|
||||||
:href="switchLocalePath(loc.code)"
|
|
||||||
v-on:click="dropdownOpen = false"
|
|
||||||
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-all duration-100"
|
|
||||||
>
|
>
|
||||||
{{ loc.name || loc.code }}
|
<path
|
||||||
</a>
|
stroke-linecap="round"
|
||||||
</div>
|
stroke-linejoin="round"
|
||||||
</Transition>
|
stroke-width="2"
|
||||||
</div>
|
d="M19 9l-7 7-7-7"
|
||||||
<div class="mr-2 ml-0">
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<Transition
|
||||||
|
enter-active-class="animate__animated animate__fadeInDown animate_fastest"
|
||||||
|
leave-active-class="animate__animated animate__fadeOutUp animate_fastest"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="dropdownOpen"
|
||||||
|
class="absolute top-full right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
v-for="loc in availableLocales"
|
||||||
|
:key="loc.code"
|
||||||
|
:href="switchLocalePath(loc.code)"
|
||||||
|
v-on:click="dropdownOpen = false"
|
||||||
|
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-all duration-100"
|
||||||
|
>
|
||||||
|
{{ loc.name || loc.code }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
<div class="mr-2 ml-0">
|
||||||
<NuxtLink :to="localePath('/system/login')">
|
<NuxtLink :to="localePath('/system/login')">
|
||||||
<button class="text-white hover:text-[#C6C6C6] transition-all duration-150">
|
<button
|
||||||
|
class="text-white hover:text-[#C6C6C6] transition-all duration-150"
|
||||||
|
>
|
||||||
<i class="bi bi-person text-3xl"></i>
|
<i class="bi bi-person text-3xl"></i>
|
||||||
</button>
|
</button>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -25,7 +25,7 @@ create table if not exists newsProviders (
|
|||||||
logoUrl text not null,
|
logoUrl text not null,
|
||||||
lean text not null
|
lean text not null
|
||||||
)
|
)
|
||||||
`
|
`;
|
||||||
|
|
||||||
const createAdminPosts = await sql`
|
const createAdminPosts = await sql`
|
||||||
create table if not exists adminPosts (
|
create table if not exists adminPosts (
|
||||||
@ -35,7 +35,7 @@ create table if not exists adminPosts (
|
|||||||
created_at timestampz default current_timestamp,
|
created_at timestampz default current_timestamp,
|
||||||
byUser text not null
|
byUser text not null
|
||||||
)
|
)
|
||||||
`
|
`;
|
||||||
const adminUsers = await sql`
|
const adminUsers = await sql`
|
||||||
create table if not exists adminUsers (
|
create table if not exists adminUsers (
|
||||||
uuid text primary key,
|
uuid text primary key,
|
||||||
@ -44,7 +44,6 @@ create table if not exists adminUsers (
|
|||||||
created_at timestampz default current_timestamp,
|
created_at timestampz default current_timestamp,
|
||||||
lastlogged_at timestampz default current_timestamp,
|
lastlogged_at timestampz default current_timestamp,
|
||||||
)
|
)
|
||||||
`
|
`;
|
||||||
|
|
||||||
|
|
||||||
console.log("Creation Complete");
|
console.log("Creation Complete");
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts"></script>
|
||||||
</script>
|
|
||||||
<template>
|
<template>
|
||||||
<main>
|
<main>
|
||||||
<slot />
|
<slot />
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: "admin"
|
layout: "admin",
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="flex justify-center min-h-screen w-full">
|
<div class="flex justify-center min-h-screen w-full">
|
||||||
<input type="text"/>
|
<input type="text" />
|
||||||
<input type="password" />
|
<input type="password" />
|
||||||
<button>登入</button>
|
<button>登入</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
@ -1,3 +1 @@
|
|||||||
<template>
|
<template></template>
|
||||||
|
|
||||||
</template>
|
|
||||||
|
@ -1,47 +1,62 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { gsap } from 'gsap'
|
import { gsap } from "gsap";
|
||||||
import { TextPlugin } from 'gsap/TextPlugin'
|
import { TextPlugin } from "gsap/TextPlugin";
|
||||||
gsap.registerPlugin(TextPlugin)
|
gsap.registerPlugin(TextPlugin);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const popMessage = ref(null);
|
const popMessage = ref(null);
|
||||||
const messages = [t("home.moving.newsPlatform"), t("home.moving.miniWikipedia"), t("home.moving.newsComparePlatform"), "BlindSpec"];
|
const messages = [
|
||||||
|
t("home.moving.newsPlatform"),
|
||||||
|
t("home.moving.miniWikipedia"),
|
||||||
|
t("home.moving.newsComparePlatform"),
|
||||||
|
"BlindSpec",
|
||||||
|
];
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const tl = gsap.timeline({ repeat: -1 })
|
const tl = gsap.timeline({ repeat: -1 });
|
||||||
messages.forEach((message) => {
|
messages.forEach((message) => {
|
||||||
tl.to(popMessage.value, {
|
tl.to(popMessage.value, {
|
||||||
duration:0.5,
|
duration: 0.5,
|
||||||
text:message,
|
text: message,
|
||||||
ease: "none."
|
ease: "none.",
|
||||||
}).to(popMessage.value, {
|
}).to(popMessage.value, {
|
||||||
duration:2,
|
duration: 2,
|
||||||
text:message,
|
text: message,
|
||||||
ease: "none."
|
ease: "none.",
|
||||||
})
|
});
|
||||||
|
|
||||||
for (let i = message.length; i >=0; i--) {
|
for (let i = message.length; i >= 0; i--) {
|
||||||
tl.to(popMessage.value, {
|
tl.to(popMessage.value, {
|
||||||
duration:0.06,
|
duration: 0.06,
|
||||||
text:message.substring(0, i),
|
text: message.substring(0, i),
|
||||||
ease: "none"
|
ease: "none",
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0">
|
<div
|
||||||
<span class="text-3xl">
|
class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0"
|
||||||
<span class="bg-gradient-to-b from-[#eee] to-[#333] bg-clip-text text-transparent">{{ t("home.nonMoving") }}</span>
|
>
|
||||||
<span ref="popMessage" class="bg-gradient-to-r from-[#2a7b9b] then-[#8d57c7] to-[#ed4242] bg-clip-text text-transparent"></span></span>
|
<span class="text-3xl">
|
||||||
<NuxtLink>
|
<span
|
||||||
<button class="m-4 bg-[#8C9393] text-white p-3 rounded-full bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-100">
|
class="bg-gradient-to-b from-[#eee] to-[#333] bg-clip-text text-transparent"
|
||||||
<span>{{ t("home.startusing") }}</span>
|
>{{ t("home.nonMoving") }}</span
|
||||||
</button>
|
>
|
||||||
</NuxtLink>
|
<span
|
||||||
|
ref="popMessage"
|
||||||
|
class="bg-gradient-to-r from-[#2a7b9b] then-[#8d57c7] to-[#ed4242] bg-clip-text text-transparent"
|
||||||
|
></span
|
||||||
|
></span>
|
||||||
|
<NuxtLink>
|
||||||
|
<button
|
||||||
|
class="m-4 bg-[#8C9393] text-white p-3 rounded-full bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-100"
|
||||||
|
>
|
||||||
|
<span>{{ t("home.startusing") }}</span>
|
||||||
|
</button>
|
||||||
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-screen"></div>
|
<div class="h-screen"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,12 +33,12 @@ const {
|
|||||||
} = useFetch("/api/getData/fetchSidebarData", {
|
} = useFetch("/api/getData/fetchSidebarData", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: {
|
body: {
|
||||||
lang: locale,
|
lang: locale,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
loading.value = pending.value;
|
loading.value = pending.value;
|
||||||
@ -90,25 +90,31 @@ import { GlobeAltIcon } from "@heroicons/vue/24/outline";
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-3 text-left justify-right align-right bg-[#AAACAA61] w-[28%] rounded-3xl p-3 mt-3 h-screen">
|
<div
|
||||||
|
class="flex flex-col gap-3 text-left justify-right align-right bg-[#AAACAA61] w-[28%] rounded-3xl p-3 mt-3 h-screen"
|
||||||
|
>
|
||||||
<h3 class="text-2xl mt-2s">其他媒體</h3>
|
<h3 class="text-2xl mt-2s">其他媒體</h3>
|
||||||
<hr/>
|
<hr />
|
||||||
<div v-for="data in fetchOtherData" :key="data.id" class="flex flex-col">
|
<div v-for="data in fetchOtherData" :key="data.id" class="flex flex-col">
|
||||||
<NuxtImg :src="data.image"></NuxtImg>
|
<NuxtImg :src="data.image"></NuxtImg>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<h1 class="text-xl text-bold">{{ data.title }}</h1>
|
<h1 class="text-xl text-bold">{{ data.title }}</h1>
|
||||||
<span class="text-ms ml-2 align-center justify-center text-center">
|
<span class="text-ms ml-2 align-center justify-center text-center">
|
||||||
(
|
(
|
||||||
<span>{{ data.lean }}</span>
|
<span>{{ data.lean }}</span>
|
||||||
-
|
-
|
||||||
<span>文章分數:
|
<span
|
||||||
<span>{{ data.score }}</span>
|
>文章分數:
|
||||||
</span> )
|
<span>{{ data.score }}</span>
|
||||||
</span>
|
</span>
|
||||||
|
)
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<NuxtLink class="justify-center align-center text-center">
|
<NuxtLink class="justify-center align-center text-center">
|
||||||
<button class="bg-red-500 text-black p-2 rounded-full justify-center align-center">
|
<button
|
||||||
|
class="bg-red-500 text-black p-2 rounded-full justify-center align-center"
|
||||||
|
>
|
||||||
<span>查看更多</span>
|
<span>查看更多</span>
|
||||||
</button>
|
</button>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
@ -1,3 +1 @@
|
|||||||
<template>
|
<template></template>
|
||||||
|
|
||||||
</template>
|
|
||||||
|
@ -1,25 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w-full min-h-screen flex items-center justify-center text-center">
|
<div class="w-full min-h-screen flex items-center justify-center text-center">
|
||||||
<div class="border border-white w-[40%] p-16 justify-center align-center text-center rounded-md backdrop-blur-sm bg-gray-900">
|
<div
|
||||||
<h1 class="text-2xl">Login / Register</h1>
|
class="border border-white w-[40%] p-16 justify-center align-center text-center rounded-md backdrop-blur-sm bg-gray-900"
|
||||||
<h4 class="text-sm">via OAuth Providers</h4>
|
>
|
||||||
<div class="m-4 flex flex-col gap-2">
|
<h1 class="text-2xl">Login / Register</h1>
|
||||||
<a href="/api/auth/google">
|
<h4 class="text-sm">via OAuth Providers</h4>
|
||||||
<button class="gap-3 px-10 justify-between align-center text-center bg-gray-500 hover:bg-gray-700 p-2 rounded-md transition-all duration-150">
|
<div class="m-4 flex flex-col gap-2">
|
||||||
<i class="bi bi-google"></i> <span>Google</span>
|
<a href="/api/auth/google">
|
||||||
</button>
|
<button
|
||||||
</a>
|
class="gap-3 px-10 justify-between align-center text-center bg-gray-500 hover:bg-gray-700 p-2 rounded-md transition-all duration-150"
|
||||||
<a href="/api/auth/github">
|
>
|
||||||
<button class="gap-3 px-10 bg-gray-500 hover:bg-gray-700 p-2 rounded-md transition-all duration-150">
|
<i class="bi bi-google"></i> <span>Google</span>
|
||||||
<i class="bi bi-github"></i> <span>Github</span>
|
</button>
|
||||||
</button>
|
</a>
|
||||||
</a>
|
<a href="/api/auth/github">
|
||||||
<a href="/api/auth/discord">
|
<button
|
||||||
<button class="gap-3 px-10 bg-gray-500 hover:bg-gray-700 p-2 rounded-md transition-all duration-150">
|
class="gap-3 px-10 bg-gray-500 hover:bg-gray-700 p-2 rounded-md transition-all duration-150"
|
||||||
<i class="bi bi-discord"></i> <span>Discord</span>
|
>
|
||||||
</button>
|
<i class="bi bi-github"></i> <span>Github</span>
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
<a href="/api/auth/discord">
|
||||||
|
<button
|
||||||
|
class="gap-3 px-10 bg-gray-500 hover:bg-gray-700 p-2 rounded-md transition-all duration-150"
|
||||||
|
>
|
||||||
|
<i class="bi bi-discord"></i> <span>Discord</span>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
@ -1,8 +1,5 @@
|
|||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {});
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
async function findUser(githubUser: any) {
|
async function findUser(githubUser: any) {
|
||||||
console.log("Github User: " + githubUser);
|
console.log("Github User: " + githubUser);
|
||||||
|
|
||||||
}
|
}
|
@ -1,16 +1,16 @@
|
|||||||
import crypto from "node:crypto"
|
import crypto from "node:crypto";
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
const baseUrl = event.node.req.headers.host
|
const baseUrl = event.node.req.headers.host;
|
||||||
const protocol = process.env.NODE_ENV === "production" ? "https": "http"
|
const protocol = process.env.NODE_ENV === "production" ? "https" : "http";
|
||||||
const clientId = process.env.NUXT_GITHUB_CLIENT_ID;
|
const clientId = process.env.NUXT_GITHUB_CLIENT_ID;
|
||||||
const callbackUrl = `${protocol}://${baseUrl}/api/auth/github/callback`;
|
const callbackUrl = `${protocol}://${baseUrl}/api/auth/github/callback`;
|
||||||
const state = crypto.randomBytes(16).toString("hex");
|
const state = crypto.randomBytes(16).toString("hex");
|
||||||
setCookie(event, 'oauth_state', state, {
|
setCookie(event, "oauth_state", state, {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: process.env.NODE_ENV === 'production',
|
secure: process.env.NODE_ENV === "production",
|
||||||
maxAge: 60 * 10,
|
maxAge: 60 * 10,
|
||||||
path: '/',
|
path: "/",
|
||||||
})
|
});
|
||||||
const authorizationUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(callbackUrl)}&scope=read:user,user:email&state=${state}`
|
const authorizationUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(callbackUrl)}&scope=read:user,user:email&state=${state}`;
|
||||||
await sendRedirect(event, authorizationUrl, 302)
|
await sendRedirect(event, authorizationUrl, 302);
|
||||||
})
|
});
|
||||||
|
@ -2,12 +2,12 @@ export default defineEventHandler(async (event) => {
|
|||||||
const body = await readBody(event);
|
const body = await readBody(event);
|
||||||
return {
|
return {
|
||||||
0: {
|
0: {
|
||||||
id: "1",
|
id: "1",
|
||||||
image: "whatever",
|
image: "whatever",
|
||||||
tags: [],
|
tags: [],
|
||||||
title: "三立新聞",
|
title: "三立新聞",
|
||||||
lean: "left",
|
lean: "left",
|
||||||
score: "40"
|
score: "40",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -9,15 +9,17 @@
|
|||||||
body {
|
body {
|
||||||
@apply bg-black m-0 p-0 min-h-screen text-white;
|
@apply bg-black m-0 p-0 min-h-screen text-white;
|
||||||
}
|
}
|
||||||
html,body {
|
html,
|
||||||
font-family: 'Noto Sans TC Variable', "Fira Sans", sans-serif;
|
body {
|
||||||
|
font-family: "Noto Sans TC Variable", "Fira Sans", sans-serif;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Noto Sans TC Variable';
|
font-family: "Noto Sans TC Variable";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: auto;
|
font-display: auto;
|
||||||
font-weight: 100 900;
|
font-weight: 100 900;
|
||||||
src: url(@fontsource-variable/noto-sans-tc/files/noto-sans-tc-chinese-traditional-wght-normal.woff2) format('woff2-variations');
|
src: url(@fontsource-variable/noto-sans-tc/files/noto-sans-tc-chinese-traditional-wght-normal.woff2)
|
||||||
|
format("woff2-variations");
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user