Merge pull request #66 from pengzhanbo/RC-52

RC-50
This commit is contained in:
pengzhanbo 2024-04-17 12:18:35 +08:00 committed by GitHub
commit 3f348cb00d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
52 changed files with 1233 additions and 212 deletions

10
docs/.vuepress/client.ts Normal file
View File

@ -0,0 +1,10 @@
import { type ClientConfig, defineClientConfig } from 'vuepress/client'
import HeroTintPlateConfig from './themes/components/HeroTintPlateConfig.vue'
import CanIUseConfig from './themes/components/CanIUseConfig.vue'
export default defineClientConfig({
enhance({ app }) {
app.component('HeroTintPlateConfig', HeroTintPlateConfig)
app.component('CanIUseConfig', CanIUseConfig)
},
}) as ClientConfig

View File

@ -33,6 +33,7 @@ export const zhNavbar = [
text: '更多',
icon: 'icon-park-outline:more-three',
items: [
{ text: '主题工具', link: '/tools/' },
{ text: '友情链接', link: '/friends/' },
{
text: 'Vuepress',

View File

@ -124,6 +124,18 @@ export const zhNotes = definePlumeNotesConfig({
},
],
},
{
dir: 'tools',
link: '/tools/',
sidebar: [
{
text: '工具',
icon: 'tabler:tools',
link: '/tools/',
items: ['home-hero-tint-plate', 'caniuse'],
},
],
},
],
})

View File

@ -0,0 +1,267 @@
<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { onClickOutside, useLocalStorage, useThrottleFn } from '@vueuse/core'
import { resolveCanIUse } from '../composables/caniuse.js'
import CodeViewer from './CodeViewer.vue'
interface Feature {
label: string
value: string
}
const api = 'https://api.caniuse.bitsofco.de/features'
const features = useLocalStorage('caniuse-features', [] as Feature[])
onMounted(async () => {
const res = await fetch(api)
const data = await res.json()
features.value = data?.map((item: any) => ({ label: item.title, value: item.id })) || []
})
const browserVersionList = ref([
{ label: '未来版本 (当前版本 + 3', value: 3, checked: false },
{ label: '未来版本 (当前版本 + 2', value: 2, checked: false },
{ label: '未来版本 (当前版本 + 1', value: 1, checked: false },
{ label: '当前版本', value: 0, disabled: true, checked: true },
{ label: '过去版本 (当前版本 - 1', value: -1, checked: false },
{ label: '过去版本 (当前版本 - 2', value: -2, checked: false },
{ label: '过去版本 (当前版本 - 3', value: -3, checked: false },
{ label: '过去版本 (当前版本 - 4', value: -4, checked: false },
{ label: '过去版本 (当前版本 - 5', value: -5, checked: false },
])
const input = ref('')
const isFocus = ref(false)
const searched = ref<Feature[]>()
const selected = ref<Feature | null>(null)
const embedType = ref('')
const browserVersion = computed(() => {
const values = browserVersionList.value.filter(item => item.checked).map(item => item.value)
if (values.length === 1 && values[0] === 0)
return ''
return values.join(',')
})
watch(() => [features.value, isFocus.value], () => {
if (!isFocus.value)
searched.value = features.value
}, { immediate: true })
const listEl = ref<HTMLUListElement | null>(null)
const inputEl = ref<HTMLInputElement | null>(null)
onClickOutside(listEl, () => {
isFocus.value = false
}, { ignore: [inputEl] })
const onInput = useThrottleFn(() => {
selected.value = null
if (!input.value) {
searched.value = features.value
}
else {
searched.value = features.value.filter(item => item.label.includes(input.value) || item.value.includes(input.value))
if (searched.value.length === 1)
selected.value = searched.value[0]
}
}, 300)
function onSelect(item: Feature) {
selected.value = item
input.value = item.label
isFocus.value = false
}
const output = computed(() => {
let content = '@[caniuse'
if (embedType.value)
content += ` ${embedType.value}`
if (browserVersion.value)
content += `{${browserVersion.value}}`
content += ']('
if (selected.value)
content += selected.value.value
return `${content})`
})
const rendered = ref('')
function render() {
if (!selected.value)
return
rendered.value = resolveCanIUse(selected.value.value, embedType.value, browserVersion.value)
}
</script>
<template>
<div class="caniuse-config-wrapper">
<form>
<div class="caniuse-form-item">
<label for="feature">选择特性</label>
<div class="feature-input">
<input
ref="inputEl" v-model="input" class="feature-input__input" type="text" name="feature"
placeholder="输入特性" @focus="isFocus = true" @input="onInput"
>
<span class="vpi-chevron-down" />
<ul v-show="isFocus" ref="listEl" class="feature-list">
<li v-for="item in searched" :key="item.value" @click="onSelect(item)">
{{ item.label }}
</li>
</ul>
</div>
</div>
<div class="caniuse-form-item">
<label for="embedType">嵌入方式</label>
<div class="caniuse-embed-type">
<label>
<input type="radio" name="embedType" value="" :checked="embedType === ''" @click="embedType = ''">
<span>iframe</span>
</label>
<label>
<input
type="radio" name="embedType" value="image" :checked="embedType === 'image'"
@click="embedType = 'image'"
> <span>image</span>
</label>
</div>
</div>
<div class="caniuse-form-item">
<label for="browserVersion">浏览器版本</label>
<div class="caniuse-browser-version">
<label v-for="item in browserVersionList" :key="item.value">
<input
v-model="item.checked" type="checkbox" name="browserVersion" :checked="item.checked"
:disabled="item.disabled"
>
<span>{{ item.label }}</span>
</label>
</div>
</div>
</form>
<div class="caniuse-output">
<h4>输出</h4>
<CodeViewer lang="md" :content="output" />
</div>
<div class="caniuse-render">
<button class="caniuse-render-button" type="button" :disabled="!selected" @click="render">
生成预览
</button>
</div>
<div v-html="rendered" />
</div>
</template>
<style scoped>
.caniuse-config-wrapper form {
padding: 20px;
border: solid 1px var(--vp-c-divider);
border-radius: 5px;
}
.caniuse-form-item {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 16px;
}
.feature-input {
position: relative;
flex: 1;
margin-left: 10px;
}
.feature-input .vpi-chevron-down {
position: absolute;
top: 8px;
right: 10px;
width: 1em;
}
.feature-input__input {
width: 100%;
padding: 3px 40px 3px 16px;
border: solid 1px var(--vp-c-divider);
}
.feature-input__input:focus {
border-color: var(--vp-c-brand-1);
}
.feature-list {
position: absolute;
top: 100%;
left: 0;
z-index: 20;
width: 100%;
max-height: 420px;
padding: 10px 16px;
margin: 0;
overflow-y: auto;
list-style: none;
background: var(--vp-c-bg);
border: solid 1px var(--vp-c-divider);
border-top: none;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
box-shadow: var(--vp-shadow-2);
}
.feature-list li {
color: var(--vp-c-text-1);
cursor: pointer;
}
.feature-list li:hover {
color: var(--vp-c-brand-1);
}
.caniuse-embed-type {
margin-left: 10px;
}
.caniuse-embed-type label {
margin-right: 20px;
cursor: pointer;
}
.caniuse-browser-version {
display: flex;
flex: 1;
flex-wrap: wrap;
gap: 10px 30px;
margin-left: 10px;
}
.caniuse-render {
display: flex;
justify-content: flex-end;
padding-right: 20px;
padding-bottom: 20px;
}
.caniuse-render-button {
padding: 5px 20px;
font-weight: 500;
color: var(--vp-c-bg);
background-color: var(--vp-c-brand-1);
border-radius: 8px;
transition: background-color var(--t-color);
}
.caniuse-render-button:hover {
background-color: var(--vp-c-brand-2);
}
.caniuse-render-button[disabled] {
cursor: not-allowed;
background-color: var(--vp-c-brand-1);
opacity: 0.5;
}
</style>

View File

@ -0,0 +1,13 @@
<script setup lang="ts">
defineProps<{
content: string
lang: string
}>()
</script>
<template>
<div :class="`language-${lang}`" :data-ext="lang">
<button class="copy-code-button" :data-lang="lang" />
<pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code>{{ content }}</code></pre>
</div>
</template>

View File

@ -0,0 +1,65 @@
<script setup lang="ts">
import type { PlumeThemeHomeHeroTintPlate } from 'vuepress-theme-plume/client'
import { computed, watch } from 'vue'
import InputRange from './InputRange.vue'
const min = 20
const max = 240
const tintPlate = defineModel<PlumeThemeHomeHeroTintPlate>({
required: true,
})
const offsetRMax = computed(() => 256 - tintPlate.value.r.value)
const offsetGMax = computed(() => 256 - tintPlate.value.g.value)
const offsetBMax = computed(() => 256 - tintPlate.value.b.value)
function addWatch(key: 'r' | 'g' | 'b') {
return watch(() => tintPlate.value[key].value, (value) => {
const max = 256 - value
const offset = tintPlate.value[key].offset
if (offset > max)
tintPlate.value[key].offset = max
})
}
addWatch('r')
addWatch('g')
addWatch('b')
</script>
<template>
<p>浅色模式建议使用 "150 ~ 240" 之间的值 深色模式建议使用 "20 ~ 80" 之间的值</p>
<div class="custom-tint-plate">
<span>R:</span>
<InputRange v-model="tintPlate.r.value" :min="min" :max="max" />
<span class="offset">offset</span>
<InputRange v-model="tintPlate.r.offset" :max="offsetRMax" />
</div>
<div class="custom-tint-plate">
<span>G:</span>
<InputRange v-model="tintPlate.g.value" :min="min" :max="max" />
<span class="offset">offset</span>
<InputRange v-model="tintPlate.g.offset" :max="offsetGMax" />
</div>
<div class="custom-tint-plate">
<span>B:</span>
<InputRange v-model="tintPlate.b.value" :min="min" :max="max" />
<span class="offset">offset</span>
<InputRange v-model="tintPlate.b.offset" :max="offsetBMax" />
</div>
</template>
<style scoped>
.custom-tint-plate {
display: flex;
align-items: center;
padding: 16px 0 0;
}
.custom-tint-plate .offset {
margin: 0 5px;
font-size: 0.9em;
color: var(--vp-c-text-2);
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div class="demo-wrapper no-padding has-title">
<div class="demo-head">
<div class="demo-ctrl">
<i /><i /><i />
</div>
</div>
<div class="demo-container">
<slot />
</div>
</div>
</template>

View File

@ -0,0 +1,155 @@
<script setup lang="ts">
import HomeHero from 'vuepress-theme-plume/client/components/Home/HomeHero.vue'
import { useDarkMode } from 'vuepress-theme-plume/client/composables/darkMode'
import type { PlumeThemeHomeHeroTintPlate } from 'vuepress-theme-plume/client'
import { computed, ref, watch } from 'vue'
import DemoWrapper from './DemoWrapper.vue'
import SingleTintPlate from './SingleTintPlate.vue'
import TripletTintPlate from './TripletTintPlate.vue'
import CustomTintPlate from './CustomTintPlate.vue'
import CodeViewer from './CodeViewer.vue'
type Mode = 'single' | 'triplet' | 'custom'
const hero = { name: 'Theme Plume', tagline: 'Next Theme', text: '简约的,功能丰富', actions: [] }
const modeList: { value: Mode, label: string }[] = [
{ value: 'single', label: '单色' },
{ value: 'triplet', label: '三色' },
{ value: 'custom', label: '三色+偏移' },
]
const mode = ref<Mode>('single')
const singleTintPlate = ref<number>(220)
const tripletTintPlate = ref<[number, number, number]>([220, 220, 220])
const customTintPlate = ref<PlumeThemeHomeHeroTintPlate>({
r: { value: 220, offset: 36 },
g: { value: 220, offset: 36 },
b: { value: 220, offset: 36 },
})
const tintPlate = computed(() => {
switch (mode.value) {
case 'single':
return singleTintPlate.value
case 'triplet':
return tripletTintPlate.value.join(',')
case 'custom':
return customTintPlate.value
default:
return ''
}
})
const isDark = ref(false)
watch(useDarkMode(), (value) => {
isDark.value = value
}, { immediate: true })
const output = computed(() => {
const tint = tintPlate.value
let content = `---\nhome: true\nconfig:\n -\n type: hero\n background: tint-plate\n tintPlate:`
if (typeof tint === 'number' || typeof tint === 'string')
content += ` ${tint}`
if (typeof tint === 'object') {
content += `
r:
value: ${tint.r.value}
offset: ${tint.r.offset}
g:
value: ${tint.g.value}
offset: ${tint.g.offset}
b:
value: ${tint.b.value}
offset: ${tint.b.offset}`
}
return `${content}\n---`
})
</script>
<template>
<div class="hero-tint-plate-wrapper">
<h4>效果预览</h4>
<div :class="{ dark: isDark }">
<DemoWrapper>
<HomeHero type="hero" background="tint-plate" :tint-plate="tintPlate" :hero="hero" />
</DemoWrapper>
</div>
<p>
<label>
<input v-model="isDark" type="checkbox"> 深色模式
</label>
</p>
<div class="mode-content">
<div
v-for="item in modeList" :key="item.value" class="mode" :class="{ active: mode === item.value }"
@click="mode = item.value"
>
{{ item.label }}
</div>
</div>
<div class="tint-plate-">
<SingleTintPlate v-if="mode === 'single'" v-model="singleTintPlate" />
<TripletTintPlate v-if="mode === 'triplet'" v-model="tripletTintPlate" />
<CustomTintPlate v-if="mode === 'custom'" v-model="customTintPlate" />
</div>
<div class="hero-tint-plate-output">
<h4>输出</h4>
<CodeViewer lang="text" :content="output" />
</div>
</div>
</template>
<style scoped>
@media (min-width: 960px) {
.hero-tint-plate-wrapper :deep(.hero-name),
.hero-tint-plate-wrapper :deep(.hero-tagline) {
font-size: 48px;
}
}
.mode-content {
display: flex;
align-items: center;
justify-content: flex-start;
}
.hero-tint-plate-wrapper :deep(.demo-wrapper) {
overflow: hidden;
}
.hero-tint-plate-wrapper :deep(.demo-head) {
background-color: var(--vp-c-bg);
}
.hero-tint-plate-wrapper :deep(.bg-filter::after) {
background: linear-gradient(to bottom, #fff 0, transparent 40%, transparent 60%, #fff 140%);
}
.hero-tint-plate-wrapper .dark :deep(.bg-filter::after) {
background: linear-gradient(to bottom, #1b1b1f 0, transparent 40%, transparent 60%, #1b1b1f 140%);
}
.mode-content .mode {
flex: 1;
padding: 5px 0;
color: var(--vp-c-text-1);
text-align: center;
cursor: pointer;
background-color: transparent;
border-bottom: 1px solid var(--vp-c-divider);
border-top-left-radius: 5px;
border-top-right-radius: 5px;
transition: var(--t-color);
transition-property: background-color, border-bottom-color, color;
}
.mode-content .mode.active {
font-weight: 500;
color: var(--vp-c-bg);
background-color: var(--vp-c-brand);
border-bottom-color: var(--vp-c-brand);
}
</style>

View File

@ -0,0 +1,36 @@
<script setup lang="ts">
interface Props {
min?: number
max: number
step?: number
}
const props = withDefaults(defineProps<Props>(), {
min: 0,
step: 1,
})
const value = defineModel<number>({
required: true,
set(v) {
return Math.min(Math.max(v, props.min), props.max)
},
})
</script>
<template>
<input v-model="value" type="range" :min="min" :max="max" :step="step">
<input v-model="value" type="number" :min="min" :max="max" :step="step">
</template>
<style scoped>
input[type="range"] {
flex: 1;
}
input[type="number"] {
width: 50px;
margin-left: 10px;
text-align: center;
border: 1px solid var(--vp-c-divider);
}
</style>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import InputRange from './InputRange.vue'
const tintPlate = defineModel<number>({
required: true,
})
</script>
<template>
<p>浅色模式建议使用 "150 ~ 240" 之间的值 深色模式建议使用 "20 ~ 80" 之间的值</p>
<div class="single-tint-plate">
<span>RGB:</span>
<InputRange v-model="tintPlate" :max="240" :min="20" />
</div>
</template>
<style scoped>
.single-tint-plate {
display: flex;
align-items: center;
padding: 16px 0 0;
}
</style>

View File

@ -0,0 +1,34 @@
<script setup lang="ts">
import InputRange from './InputRange.vue'
const min = 20
const max = 240
const tintPlate = defineModel<[number, number, number]>({
required: true,
})
</script>
<template>
<p>浅色模式建议使用 "150 ~ 240" 之间的值 深色模式建议使用 "20 ~ 80" 之间的值</p>
<div class="triplet-tint-plate">
<span>R:</span>
<InputRange v-model="tintPlate[0]" :min="min" :max="max" />
</div>
<div class="triplet-tint-plate">
<span>G:</span>
<InputRange v-model="tintPlate[1]" :min="min" :max="max" />
</div>
<div class="triplet-tint-plate">
<span>B:</span>
<InputRange v-model="tintPlate[2]" :min="min" :max="max" />
</div>
</template>
<style scoped>
.triplet-tint-plate {
display: flex;
align-items: center;
padding: 16px 0 0;
}
</style>

View File

@ -0,0 +1,46 @@
export function resolveCanIUse(feature: string, mode: string, versions: string): string {
if (!feature)
return ''
if (mode === 'image') {
const link = 'https://caniuse.bitsofco.de/image/'
const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`
return `<p><picture>
<source type="image/webp" srcset="${link}${feature}.webp">
<source type="image/png" srcset="${link}${feature}.png">
<img src="${link}${feature}.jpg" alt="${alt}" width="100%">
</picture></p>`
}
const periods = resolveVersions(versions)
const accessible = 'false'
const image = 'none'
const url = 'https://caniuse.bitsofco.de/embed/index.html'
const src = `${url}?feat=${feature}&periods=${periods}&accessible-colours=${accessible}&image-base=${image}`
return `<div class="ciu_embed" style="margin:16px 0" data-feature="${feature}"><iframe src="${src}" frameborder="0" width="100%" height="400px" title="Can I use ${feature}"></iframe></div>`
}
function resolveVersions(versions: string): string {
if (!versions)
return 'future_1,current,past_1,past_2'
const list = versions
.split(',')
.map(v => Number(v.trim()))
.filter(v => !Number.isNaN(v) && v >= -5 && v <= 3)
list.push(0)
const uniq = [...new Set(list)].sort((a, b) => b - a)
const result: string[] = []
uniq.forEach((v) => {
if (v < 0)
result.push(`past_${Math.abs(v)}`)
if (v === 0)
result.push('current')
if (v > 0)
result.push(`future_${v}`)
})
return result.join(',')
}

View File

@ -5,7 +5,7 @@ config:
-
type: hero
full: true
background: filter-blur
background: tint-plate
hero:
name: Theme Plume
tagline: VuePress Next Theme

View File

@ -5,7 +5,7 @@ config:
-
type: hero
full: true
background: filter-blur
background: tint-plate
hero:
name: Theme Plume
tagline: Vuepress Next Theme

View File

@ -121,9 +121,13 @@ interface NotesSidebarItem {
*/
items?: NotesSidebar
/**
* 侧边栏图标
* - 支持 iconify 图标,直接使用 iconify name 即可自动加载
* @see https://icon-sets.iconify.design/
*
* - 如果 iconify 图标不满足您的需求,也可以支持传入 svg 字符串。
* - 还支持使用 本地图片 或 远程图片,本地图片的路径需要以 `/` 开头。
*/
icon?: string
icon?: string | { svg: string }
}
```
@ -135,7 +139,8 @@ interface NotesSidebarItem {
### 侧边栏图标
主题不仅可以通过 侧边栏配置中 `icon` 配置图标,还可以通过 文件中的 frontmatter 中 `icon` 字段 配置图标。
主题不仅可以通过 侧边栏配置中 `icon` 配置图标,还可以通过 文件中的 frontmatter 中 `icon` 字段 配置图标,
与 侧边栏配置中的 `icon` 一致。
```md
---

View File

@ -91,10 +91,13 @@ type NavItem = string | {
*/
link: string
/**
* 支持 iconify 图标,直接使用 iconify name 即可自动加载
* - 支持 iconify 图标,直接使用 iconify name 即可自动加载
* @see https://icon-sets.iconify.design/
*
* - 如果 iconify 图标不满足您的需求,也可以支持传入 svg 字符串。
* - 还支持使用 本地图片 或 远程图片,本地图片的路径需要以 `/` 开头。
*/
icon?: string
icon?: string | { svg: string }
/**
* 控制元素何时被激活
*/

View File

@ -327,6 +327,9 @@ export default defineUserConfig({
@[caniuse](feature)
```
为了方便使用,主题提供了工具支持:[caniuse 特性搜索](/tools/caniuse/),你可以直接使用该工具
帮助生成 markdown 代码。
### 语法
``` md

View File

@ -144,6 +144,8 @@ config:
适用于 文档 类型站点,放置于 首位。
**工具支持: [首页背景色板配置工具](/tools/home-hero-tint-plate/)**
```ts
interface PlumeThemeHomeHero extends PlumeHomeConfigBase {
type: 'hero'
@ -158,14 +160,36 @@ interface PlumeThemeHomeHero extends PlumeHomeConfigBase {
}
}
/**
* 背景图片,"filter-blur" 为预设效果
* 背景图片,"tint-plate" 为预设效果, 也可以配置为图片地址
*/
background?: 'filter-blur' | string
background?: 'tint-plate' | string
/**
* 当 background 为预设背景时,可以配置 RGB 值,用于调整背景
* 该配置仅在 `background``tint-plate` 时生效
*/
tintPlate?: TintPlate
/**
* 如果是非预设背景,可以设置背景图片的滤镜效果
*/
filter?: string
}
interface TintPlateObj {
// value 表示 基准色值,范围为 0 ~ 255
// offset 表示 基准色值的偏移量,范围为 0 ~ (255 - value)
r: { value: number, offset: number }
g: { value: number, offset: number }
b: { value: number, offset: number }
}
type TintPlate =
| number // 210
| string // '210,210,210' => red,green,blue
// { r: { value: 220, offset: 36 }, g: { value: 220, offset: 36 }, b: { value: 220, offset: 36 } }
| TintPlate
// { light: 210, dark: 20 }
// { light: '210,210,210', dark: '20,20,20' }
| { light: number | string, dark: number | string }
| { light: TintPlate, dark: TintPlate }
```
**示例:**
@ -177,7 +201,7 @@ config:
-
type: hero
full: true
background: filter-blur
background: tint-plate
hero:
name: Theme Plume
tagline: Vuepress Next Theme
@ -200,6 +224,32 @@ config:
<img src="/images/custom-hero.png" alt="Theme Plume" />
:::
`background` 配置为 `tint-plate` 时,还可以额外配置 `tintPlate` 调整 背景色调,范围为 `0 ~ 255`
```md
---
home: true
config:
-
type: hero
full: true
background: tint-plate
tintPlate: 210
---
```
`tintPlate` 用于配置 RGB 值:
- 配置为单个值时,表示配置 red,green,blue 三个颜色值为相同值,范围: 0 - 255。示例 `210`
- 配置为三个值时,表示配置 red,green,blue 三个颜色值为不同值,范围: 0 - 255。示例 `210,210,210`
- 配置为 `TintPlate`,则可以更加灵活的控制每个颜色值和对应的偏移量。
- 还可以配置为 `{ light, dark }`,在深色模式和浅色模式下使用不同的颜色值。
::: info
为了便于用户配置 美观的个性化的背景,主题还提供了 [首页背景色板配置工具](/tools/home-hero-tint-plate/)
进行可视化操作,生成配置内容,你可以直接复制它们用于自己的项目中。
:::
### features
- 类型: `PlumeThemeHomeFeatures`

View File

@ -0,0 +1,15 @@
---
title: 主题工具包
author: pengzhanbo
createTime: 2024/04/16 16:27:03
permalink: /tools/
---
## 概述
主题工具包 旨在帮助用户在使用本主题提供的一些功能时,降低其使用门槛。
## 工具列表
- [caniuse 特性搜索](./caniuse.md)
- [首页背景色板配置](./home-hero-tint-plate.md)

View File

@ -0,0 +1,15 @@
---
title: caniuse 特性搜索
author: pengzhanbo
icon: fa-brands:css3
createTime: 2024/04/16 12:41:26
permalink: /tools/caniuse/
readingTime: false
editLink: false
contributors: false
lastUpdated: false
---
本工具用于帮助搜索 caniuse 中的特性。并生成 caniuse markdown 代码。
<CanIUseConfig />

View File

@ -0,0 +1,16 @@
---
title: 首页背景色板配置
author: pengzhanbo
icon: icon-park-outline:hand-painted-plate
createTime: 2024/04/15 20:17:42
permalink: /tools/home-hero-tint-plate/
readingTime: false
editLink: false
contributors: false
lastUpdated: false
---
为了更直观更方便的配置首页 Hero 区域 的 背景色板,主题提供了 色板配置工具,
帮助生成相对应的配置信息。
<HeroTintPlateConfig />

View File

@ -12,14 +12,14 @@
"vuepress": "2.0.0-rc.9"
},
"dependencies": {
"@iconify/json": "^2.2.200",
"@iconify/json": "^2.2.201",
"@vuepress/bundler-vite": "2.0.0-rc.9",
"anywhere": "^1.6.0",
"chart.js": "^4.4.2",
"echarts": "^5.5.0",
"flowchart.ts": "^3.0.0",
"mermaid": "^10.9.0",
"vue": "^3.4.21",
"vue": "^3.4.22",
"vuepress-theme-plume": "workspace:*"
},
"devDependencies": {

View File

@ -59,7 +59,7 @@
"stylelint": "^16.3.1",
"tsconfig-vuepress": "^4.5.0",
"typescript": "^5.4.5",
"vite": "^5.2.8"
"vite": "^5.2.9"
},
"pnpm": {
"patchedDependencies": {

View File

@ -43,7 +43,7 @@
"@vue/devtools-api": "6.5.1",
"chokidar": "^3.6.0",
"create-filter": "^1.0.1",
"vue": "^3.4.21"
"vue": "^3.4.22"
},
"publishConfig": {
"access": "public"

View File

@ -40,7 +40,7 @@
"vuepress": "2.0.0-rc.9"
},
"dependencies": {
"vue": "^3.4.21"
"vue": "^3.4.22"
},
"publishConfig": {
"access": "public"

View File

@ -41,7 +41,7 @@
},
"dependencies": {
"@vuepress-plume/plugin-content-update": "workspace:*",
"vue": "^3.4.21"
"vue": "^3.4.22"
},
"publishConfig": {
"access": "public"

View File

@ -41,7 +41,7 @@
},
"dependencies": {
"@iconify/vue": "^4.1.1",
"vue": "^3.4.21"
"vue": "^3.4.22"
},
"publishConfig": {
"access": "public"

View File

@ -46,15 +46,15 @@
}
},
"dependencies": {
"@iconify/utils": "^2.1.22",
"@iconify/utils": "^2.1.23",
"@vueuse/core": "^10.9.0",
"local-pkg": "^0.5.0",
"markdown-it-container": "^4.0.0",
"nanoid": "^5.0.7",
"vue": "^3.4.21"
"vue": "^3.4.22"
},
"devDependencies": {
"@iconify/json": "^2.2.200",
"@iconify/json": "^2.2.201",
"@types/markdown-it": "^14.0.1"
},
"publishConfig": {

View File

@ -43,7 +43,7 @@
"@vue/devtools-api": "6.5.1",
"chokidar": "^3.6.0",
"create-filter": "^1.0.1",
"vue": "^3.4.21"
"vue": "^3.4.22"
},
"publishConfig": {
"access": "public"

View File

@ -71,7 +71,7 @@ export interface NotesSidebarItem {
/**
*
*/
icon?: string
icon?: string | { svg: string }
}
export type NotesData = Record<string, NotesSidebarItem[]>

View File

@ -36,7 +36,7 @@
"dependencies": {
"@netlify/functions": "^2.6.0",
"leancloud-storage": "^4.15.2",
"vue": "^3.4.21",
"vue": "^3.4.22",
"vue-router": "4.3.0",
"vuepress-plugin-netlify-functions": "workspace:*"
},

View File

@ -48,7 +48,7 @@
"mark.js": "^8.11.1",
"minisearch": "^6.3.0",
"p-map": "^7.0.2",
"vue": "^3.4.21"
"vue": "^3.4.22"
},
"publishConfig": {
"access": "public"

351
pnpm-lock.yaml generated
View File

@ -74,14 +74,14 @@ importers:
specifier: ^5.4.5
version: 5.4.5
vite:
specifier: ^5.2.8
version: 5.2.8(@types/node@20.9.1)
specifier: ^5.2.9
version: 5.2.9(@types/node@20.9.1)
docs:
dependencies:
'@iconify/json':
specifier: ^2.2.200
version: 2.2.200
specifier: ^2.2.201
version: 2.2.201
'@vuepress/bundler-vite':
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@types/node@20.9.1)(typescript@5.4.5)
@ -101,11 +101,11 @@ importers:
specifier: ^10.9.0
version: 10.9.0
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
vuepress-theme-plume:
specifier: workspace:*
version: link:../theme
@ -133,13 +133,13 @@ importers:
version: 1.1.0
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-baidu-tongji:
dependencies:
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-blog-data:
dependencies:
@ -153,11 +153,11 @@ importers:
specifier: ^1.0.1
version: 1.0.1
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-caniuse:
dependencies:
@ -166,7 +166,7 @@ importers:
version: 4.0.0
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
devDependencies:
'@types/markdown-it':
specifier: ^14.0.1
@ -175,11 +175,11 @@ importers:
plugins/plugin-content-update:
dependencies:
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-copy-code:
dependencies:
@ -187,32 +187,32 @@ importers:
specifier: workspace:*
version: link:../plugin-content-update
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-iconify:
dependencies:
'@iconify/vue':
specifier: ^4.1.1
version: 4.1.1(vue@3.4.21)
version: 4.1.1(vue@3.4.22)
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-md-power:
dependencies:
'@iconify/utils':
specifier: ^2.1.22
version: 2.1.22
specifier: ^2.1.23
version: 2.1.23
'@vueuse/core':
specifier: ^10.9.0
version: 10.9.0(vue@3.4.21)
version: 10.9.0(vue@3.4.22)
local-pkg:
specifier: ^0.5.0
version: 0.5.0
@ -223,15 +223,15 @@ importers:
specifier: ^5.0.7
version: 5.0.7
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
devDependencies:
'@iconify/json':
specifier: ^2.2.200
version: 2.2.200
specifier: ^2.2.201
version: 2.2.201
'@types/markdown-it':
specifier: ^14.0.1
version: 14.0.1
@ -270,7 +270,7 @@ importers:
version: 1.0.32
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
devDependencies:
'@types/node':
specifier: ^20.12.7
@ -288,11 +288,11 @@ importers:
specifier: ^1.0.1
version: 1.0.1
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-search:
dependencies:
@ -301,10 +301,10 @@ importers:
version: 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
'@vueuse/core':
specifier: ^10.9.0
version: 10.9.0(vue@3.4.21)
version: 10.9.0(vue@3.4.22)
'@vueuse/integrations':
specifier: ^10.9.0
version: 10.9.0(focus-trap@7.5.4)(vue@3.4.21)
version: 10.9.0(focus-trap@7.5.4)(vue@3.4.22)
chokidar:
specifier: ^3.6.0
version: 3.6.0
@ -321,11 +321,11 @@ importers:
specifier: ^7.0.2
version: 7.0.2
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
plugins/plugin-shikiji:
dependencies:
@ -340,7 +340,7 @@ importers:
version: 3.0.4
floating-vue:
specifier: ^5.2.2
version: 5.2.2(vue@3.4.21)
version: 5.2.2(vue@3.4.22)
mdast-util-from-markdown:
specifier: ^2.0.0
version: 2.0.0
@ -364,7 +364,7 @@ importers:
version: 0.2.5(typescript@5.4.5)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
theme:
dependencies:
@ -445,7 +445,7 @@ importers:
version: 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
'@vueuse/core':
specifier: ^10.9.0
version: 10.9.0(vue@3.4.21)
version: 10.9.0(vue@3.4.22)
bcrypt-ts:
specifier: ^5.0.2
version: 5.0.2
@ -462,14 +462,14 @@ importers:
specifier: ^5.0.7
version: 5.0.7
vue:
specifier: ^3.4.21
version: 3.4.21(typescript@5.4.5)
specifier: ^3.4.22
version: 3.4.22(typescript@5.4.5)
vue-router:
specifier: 4.3.0
version: 4.3.0(vue@3.4.21)
version: 4.3.0(vue@3.4.22)
vuepress:
specifier: 2.0.0-rc.9
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
version: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
vuepress-plugin-md-enhance:
specifier: 2.0.0-rc.32
version: 2.0.0-rc.32(katex@0.16.10)(markdown-it@14.1.0)(typescript@5.4.5)(vuepress@2.0.0-rc.9)
@ -523,9 +523,6 @@ packages:
peerDependencies:
'@algolia/client-search': '>= 4.9.1 < 6'
algoliasearch: '>= 4.9.1 < 6'
peerDependenciesMeta:
'@algolia/client-search':
optional: true
dependencies:
'@algolia/client-search': 4.20.0
algoliasearch: 4.20.0
@ -668,6 +665,14 @@ packages:
dependencies:
'@babel/types': 7.23.6
/@babel/parser@7.24.4:
resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.23.6
dev: false
/@babel/runtime@7.21.5:
resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==}
engines: {node: '>=6.9.0'}
@ -1771,8 +1776,8 @@ packages:
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
dev: false
/@iconify/json@2.2.200:
resolution: {integrity: sha512-hnGvv2qeQD+DYhbCZSjnIlSi63dPFNmnMWCqLh0cL0kOqQBYsL61ViMjiusjVHKgBWf+fI4Sp6/bsoFuEWbhQg==}
/@iconify/json@2.2.201:
resolution: {integrity: sha512-5jM9TAa55YSEfx2WX1/GsHL9FSSH1PsA38V3p26SDmnOSmfb3V7r5yBgO8oIFkXdFQFk59MgESEOziapNtTGkw==}
dependencies:
'@iconify/types': 2.0.0
pathe: 1.1.2
@ -1780,8 +1785,8 @@ packages:
/@iconify/types@2.0.0:
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
/@iconify/utils@2.1.22:
resolution: {integrity: sha512-6UHVzTVXmvO8uS6xFF+L/QTSpTzA/JZxtgU+KYGFyDYMEObZ1bu/b5l+zNJjHy+0leWjHI+C0pXlzGvv3oXZMA==}
/@iconify/utils@2.1.23:
resolution: {integrity: sha512-YGNbHKM5tyDvdWZ92y2mIkrfvm5Fvhe6WJSkWu7vvOFhMtYDP0casZpoRz0XEHZCrYsR4stdGT3cZ52yp5qZdQ==}
dependencies:
'@antfu/install-pkg': 0.1.1
'@antfu/utils': 0.7.7
@ -1794,13 +1799,13 @@ packages:
- supports-color
dev: false
/@iconify/vue@4.1.1(vue@3.4.21):
/@iconify/vue@4.1.1(vue@3.4.22):
resolution: {integrity: sha512-RL85Bm/DAe8y6rT6pux7D2FJSiUEM/TPfyK7GrbAOfTSwrhvwJW+S5yijdGcmtXouA8MtuH9C7l4hiSE4mLMjg==}
peerDependencies:
vue: '>=3'
dependencies:
'@iconify/types': 2.0.0
vue: 3.4.21(typescript@5.4.5)
vue: 3.4.22(typescript@5.4.5)
dev: false
/@import-maps/resolve@1.0.1:
@ -4033,7 +4038,7 @@ packages:
- supports-color
dev: false
/@vitejs/plugin-vue@5.0.4(vite@5.2.2)(vue@3.4.21):
/@vitejs/plugin-vue@5.0.4(vite@5.2.2)(vue@3.4.22):
resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==}
engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies:
@ -4041,7 +4046,7 @@ packages:
vue: ^3.2.25
dependencies:
vite: 5.2.2(@types/node@20.9.1)
vue: 3.4.21(typescript@5.4.5)
vue: 3.4.22(typescript@5.4.5)
dev: false
/@volar/language-core@1.11.1:
@ -4065,12 +4070,29 @@ packages:
estree-walker: 2.0.2
source-map-js: 1.2.0
/@vue/compiler-core@3.4.22:
resolution: {integrity: sha512-FBDRCBE/rFPA8OfTUrARx2c49N7zoImlGT7hsFikv0pZxQlFhffQwewpEXaLynZW0/DspVXmNA+QQ9dXINpWmg==}
dependencies:
'@babel/parser': 7.24.4
'@vue/shared': 3.4.22
entities: 4.5.0
estree-walker: 2.0.2
source-map-js: 1.2.0
dev: false
/@vue/compiler-dom@3.4.21:
resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==}
dependencies:
'@vue/compiler-core': 3.4.21
'@vue/shared': 3.4.21
/@vue/compiler-dom@3.4.22:
resolution: {integrity: sha512-YkAS+jZc6Ip360kT3lZbMQZteiYBbHDSVKr94Jdd8Zjr7VjSkkXKAFFR/FW+2tNtBYXOps6xrWlOquy3GeYB0w==}
dependencies:
'@vue/compiler-core': 3.4.22
'@vue/shared': 3.4.22
dev: false
/@vue/compiler-sfc@3.4.21:
resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==}
dependencies:
@ -4083,12 +4105,35 @@ packages:
magic-string: 0.30.7
postcss: 8.4.38
source-map-js: 1.2.0
dev: true
/@vue/compiler-sfc@3.4.22:
resolution: {integrity: sha512-Pncp5Vc8E2Ef1o5uveO8WA1IqM7rt0R1jN8D4qitQYOUxC97iITGYA8oMInQ3UcDS7ip+SegyA2HbAEB4V6NMQ==}
dependencies:
'@babel/parser': 7.24.4
'@vue/compiler-core': 3.4.22
'@vue/compiler-dom': 3.4.22
'@vue/compiler-ssr': 3.4.22
'@vue/shared': 3.4.22
estree-walker: 2.0.2
magic-string: 0.30.9
postcss: 8.4.38
source-map-js: 1.2.0
dev: false
/@vue/compiler-ssr@3.4.21:
resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==}
dependencies:
'@vue/compiler-dom': 3.4.21
'@vue/shared': 3.4.21
dev: true
/@vue/compiler-ssr@3.4.22:
resolution: {integrity: sha512-ycb2sL0SW6AkgVMrvaU/TIAEk7FQWyv/oYya44E/V9xURM+ij9Oev5bVobSS7GLJzkUieWW3SrYcK/PZpb5i4A==}
dependencies:
'@vue/compiler-dom': 3.4.22
'@vue/shared': 3.4.22
dev: false
/@vue/devtools-api@6.5.1:
resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==}
@ -4118,44 +4163,48 @@ packages:
vue-template-compiler: 2.7.16
dev: false
/@vue/reactivity@3.4.21:
resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==}
/@vue/reactivity@3.4.22:
resolution: {integrity: sha512-+golHRRfcGoahBrhoTauFNIIAhxntRV3BI8HHqVvCdsuWivxW1MI0E9AOXVsz4H/ZlWM1ahudWTX6PhUrNR2yQ==}
dependencies:
'@vue/shared': 3.4.21
'@vue/shared': 3.4.22
dev: false
/@vue/runtime-core@3.4.21:
resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==}
/@vue/runtime-core@3.4.22:
resolution: {integrity: sha512-cbA8lcL4g1907EdY1a1KmP5IRWfbqjgBRcgJPkF//yn96XSC1/VAJBZiAGLiyw0P77Rw2Ao7d9U51vU1GC6yUQ==}
dependencies:
'@vue/reactivity': 3.4.21
'@vue/shared': 3.4.21
'@vue/reactivity': 3.4.22
'@vue/shared': 3.4.22
dev: false
/@vue/runtime-dom@3.4.21:
resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==}
/@vue/runtime-dom@3.4.22:
resolution: {integrity: sha512-AXxRHrFkLX1y2+70CO2wDKRxW0WZcQKTOXS31AK+jZ1RLPtI6sEHVpYNfyE9WgbgXOqPtX4gfIfuoFYi8iCu2w==}
dependencies:
'@vue/runtime-core': 3.4.21
'@vue/shared': 3.4.21
'@vue/runtime-core': 3.4.22
'@vue/shared': 3.4.22
csstype: 3.1.3
dev: false
/@vue/server-renderer@3.4.21(vue@3.4.21):
resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==}
/@vue/server-renderer@3.4.22(vue@3.4.22):
resolution: {integrity: sha512-okiNxiCOhJlx6IOrTZvhIVwf2UYKay0hnIPqWu4h19bkNv1gmG4Ic6U3zXY287AWF26lQuFMa515Qzc+R0aAYg==}
peerDependencies:
vue: 3.4.21
vue: 3.4.22
dependencies:
'@vue/compiler-ssr': 3.4.21
'@vue/shared': 3.4.21
vue: 3.4.21(typescript@5.4.5)
'@vue/compiler-ssr': 3.4.22
'@vue/shared': 3.4.22
vue: 3.4.22(typescript@5.4.5)
dev: false
/@vue/shared@3.4.21:
resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==}
/@vue/shared@3.4.22:
resolution: {integrity: sha512-cg7R9XNk4ovV3bKka/1a464O2oY0l5Fyt0rwGR4hSJRPjUJ0WVjrPdsr4W0JbUriwiM8EKcCcCjeKN5pRMs2Zg==}
dev: false
/@vuepress/bundler-vite@2.0.0-rc.9(@types/node@20.9.1)(typescript@5.4.5):
resolution: {integrity: sha512-GcM2eSqW2mPY5xXX4i5kuZujvwUeiTpsLX5kgau9LzPox+FdA3SMUkppCY3hsou2o2RxXPTfjocE7OlYQrUqvA==}
dependencies:
'@vitejs/plugin-vue': 5.0.4(vite@5.2.2)(vue@3.4.21)
'@vitejs/plugin-vue': 5.0.4(vite@5.2.2)(vue@3.4.22)
'@vuepress/client': 2.0.0-rc.9(typescript@5.4.5)
'@vuepress/core': 2.0.0-rc.9(typescript@5.4.5)
'@vuepress/shared': 2.0.0-rc.9
@ -4166,8 +4215,8 @@ packages:
postcss-load-config: 5.0.3(postcss@8.4.38)
rollup: 4.13.0
vite: 5.2.2(@types/node@20.9.1)
vue: 3.4.21(typescript@5.4.5)
vue-router: 4.3.0(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vue-router: 4.3.0(vue@3.4.22)
transitivePeerDependencies:
- '@types/node'
- jiti
@ -4202,8 +4251,8 @@ packages:
dependencies:
'@vue/devtools-api': 6.6.1
'@vuepress/shared': 2.0.0-rc.9
vue: 3.4.21(typescript@5.4.5)
vue-router: 4.3.0(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vue-router: 4.3.0(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4215,7 +4264,7 @@ packages:
'@vuepress/markdown': 2.0.0-rc.9(patch_hash=f3on36z73gmvj4jugj25dg7wje)
'@vuepress/shared': 2.0.0-rc.9
'@vuepress/utils': 2.0.0-rc.9
vue: 3.4.21(typescript@5.4.5)
vue: 3.4.22(typescript@5.4.5)
transitivePeerDependencies:
- supports-color
- typescript
@ -4230,8 +4279,8 @@ packages:
cheerio: 1.0.0-rc.12
fflate: 0.8.2
gray-matter: 4.0.3
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4245,8 +4294,8 @@ packages:
cheerio: 1.0.0-rc.12
fflate: 0.8.2
gray-matter: 4.0.3
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4280,9 +4329,9 @@ packages:
peerDependencies:
vuepress: 2.0.0-rc.9
dependencies:
'@vueuse/core': 10.9.0(vue@3.4.21)
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
'@vueuse/core': 10.9.0(vue@3.4.22)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
@ -4308,8 +4357,8 @@ packages:
dependencies:
'@vuepress/helper': 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
giscus: 1.5.0
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4322,7 +4371,7 @@ packages:
'@types/markdown-it': 13.0.7
markdown-it: 14.1.0
markdown-it-container: 4.0.0
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
dev: false
/@vuepress/plugin-docsearch@2.0.0-rc.24(@algolia/client-search@4.20.0)(search-insights@2.7.0)(typescript@5.4.5)(vuepress@2.0.0-rc.9):
@ -4334,10 +4383,10 @@ packages:
'@docsearch/js': 3.6.0(@algolia/client-search@4.20.0)(search-insights@2.7.0)
'@docsearch/react': 3.6.0(@algolia/client-search@4.20.0)(search-insights@2.7.0)
'@vuepress/helper': 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
'@vueuse/core': 10.9.0(vue@3.4.21)
'@vueuse/core': 10.9.0(vue@3.4.22)
ts-debounce: 4.0.0
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- '@algolia/client-search'
- '@types/react'
@ -4353,8 +4402,8 @@ packages:
peerDependencies:
vuepress: 2.0.0-rc.9
dependencies:
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4365,7 +4414,7 @@ packages:
vuepress: 2.0.0-rc.9
dependencies:
execa: 8.0.1
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
dev: false
/@vuepress/plugin-medium-zoom@2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9):
@ -4375,8 +4424,8 @@ packages:
dependencies:
'@vuepress/helper': 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
medium-zoom: 1.1.0
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4386,8 +4435,8 @@ packages:
peerDependencies:
vuepress: 2.0.0-rc.9
dependencies:
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4398,7 +4447,7 @@ packages:
vuepress: 2.0.0-rc.9
dependencies:
chokidar: 3.6.0
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
dev: false
/@vuepress/plugin-reading-time@2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9):
@ -4407,8 +4456,8 @@ packages:
vuepress: 2.0.0-rc.9
dependencies:
'@vuepress/helper': 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4419,7 +4468,7 @@ packages:
vuepress: 2.0.0-rc.9
dependencies:
'@vuepress/helper': 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4431,7 +4480,7 @@ packages:
dependencies:
'@vuepress/helper': 2.0.0-rc.24(typescript@5.4.5)(vuepress@2.0.0-rc.9)
sitemap: 7.1.1
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4442,8 +4491,8 @@ packages:
vuepress: 2.0.0-rc.9
dependencies:
'@vue/devtools-api': 6.6.1
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4453,9 +4502,9 @@ packages:
peerDependencies:
vuepress: 2.0.0-rc.9
dependencies:
vue: 3.4.21(typescript@5.4.5)
vue-router: 4.3.0(vue@3.4.21)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vue-router: 4.3.0(vue@3.4.22)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- typescript
dev: false
@ -4484,19 +4533,19 @@ packages:
- supports-color
dev: false
/@vueuse/core@10.9.0(vue@3.4.21):
/@vueuse/core@10.9.0(vue@3.4.22):
resolution: {integrity: sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==}
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 10.9.0
'@vueuse/shared': 10.9.0(vue@3.4.21)
vue-demi: 0.14.7(vue@3.4.21)
'@vueuse/shared': 10.9.0(vue@3.4.22)
vue-demi: 0.14.7(vue@3.4.22)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: false
/@vueuse/integrations@10.9.0(focus-trap@7.5.4)(vue@3.4.21):
/@vueuse/integrations@10.9.0(focus-trap@7.5.4)(vue@3.4.22):
resolution: {integrity: sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q==}
peerDependencies:
async-validator: '*'
@ -4537,10 +4586,10 @@ packages:
universal-cookie:
optional: true
dependencies:
'@vueuse/core': 10.9.0(vue@3.4.21)
'@vueuse/shared': 10.9.0(vue@3.4.21)
'@vueuse/core': 10.9.0(vue@3.4.22)
'@vueuse/shared': 10.9.0(vue@3.4.22)
focus-trap: 7.5.4
vue-demi: 0.14.7(vue@3.4.21)
vue-demi: 0.14.7(vue@3.4.22)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
@ -4550,10 +4599,10 @@ packages:
resolution: {integrity: sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==}
dev: false
/@vueuse/shared@10.9.0(vue@3.4.21):
/@vueuse/shared@10.9.0(vue@3.4.22):
resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
dependencies:
vue-demi: 0.14.7(vue@3.4.21)
vue-demi: 0.14.7(vue@3.4.22)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
@ -8503,7 +8552,7 @@ packages:
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
dev: true
/floating-vue@5.2.2(vue@3.4.21):
/floating-vue@5.2.2(vue@3.4.22):
resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==}
peerDependencies:
'@nuxt/kit': ^3.2.0
@ -8513,8 +8562,8 @@ packages:
optional: true
dependencies:
'@floating-ui/dom': 1.1.1
vue: 3.4.21(typescript@5.4.5)
vue-resize: 2.0.0-alpha.1(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vue-resize: 2.0.0-alpha.1(vue@3.4.22)
dev: false
/flowchart.ts@3.0.0:
@ -10656,6 +10705,14 @@ packages:
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/magic-string@0.30.9:
resolution: {integrity: sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
dev: false
/make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
@ -15284,8 +15341,8 @@ packages:
fsevents: 2.3.3
dev: false
/vite@5.2.8(@types/node@20.9.1):
resolution: {integrity: sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==}
/vite@5.2.9(@types/node@20.9.1):
resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@ -15320,7 +15377,7 @@ packages:
fsevents: 2.3.3
dev: true
/vue-demi@0.14.7(vue@3.4.21):
/vue-demi@0.14.7(vue@3.4.22):
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
engines: {node: '>=12'}
hasBin: true
@ -15332,7 +15389,7 @@ packages:
'@vue/composition-api':
optional: true
dependencies:
vue: 3.4.21(typescript@5.4.5)
vue: 3.4.22(typescript@5.4.5)
dev: false
/vue-eslint-parser@9.4.2(eslint@9.0.0):
@ -15353,21 +15410,21 @@ packages:
- supports-color
dev: true
/vue-resize@2.0.0-alpha.1(vue@3.4.21):
/vue-resize@2.0.0-alpha.1(vue@3.4.22):
resolution: {integrity: sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==}
peerDependencies:
vue: ^3.0.0
dependencies:
vue: 3.4.21(typescript@5.4.5)
vue: 3.4.22(typescript@5.4.5)
dev: false
/vue-router@4.3.0(vue@3.4.21):
/vue-router@4.3.0(vue@3.4.22):
resolution: {integrity: sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==}
peerDependencies:
vue: ^3.2.0
dependencies:
'@vue/devtools-api': 6.5.1
vue: 3.4.21(typescript@5.4.5)
vue: 3.4.22(typescript@5.4.5)
dev: false
/vue-template-compiler@2.7.16:
@ -15377,19 +15434,19 @@ packages:
he: 1.2.0
dev: false
/vue@3.4.21(typescript@5.4.5):
resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
/vue@3.4.22(typescript@5.4.5):
resolution: {integrity: sha512-CIx7NiP+n5WHBCG/fDNaUPP4qbQ5CIa8XIHZE3HpfS/rb2vmSIsp74BxsZyrrGKF0vHW3GoToqP3l0hzrMTecw==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@vue/compiler-dom': 3.4.21
'@vue/compiler-sfc': 3.4.21
'@vue/runtime-dom': 3.4.21
'@vue/server-renderer': 3.4.21(vue@3.4.21)
'@vue/shared': 3.4.21
'@vue/compiler-dom': 3.4.22
'@vue/compiler-sfc': 3.4.22
'@vue/runtime-dom': 3.4.22
'@vue/server-renderer': 3.4.22(vue@3.4.22)
'@vue/shared': 3.4.22
typescript: 5.4.5
dev: false
@ -15468,12 +15525,12 @@ packages:
'@mdit/plugin-uml': 0.8.0(markdown-it@14.1.0)
'@types/markdown-it': 13.0.7
'@vuepress/helper': 2.0.0-rc.21(typescript@5.4.5)(vuepress@2.0.0-rc.9)
'@vueuse/core': 10.9.0(vue@3.4.21)
'@vueuse/core': 10.9.0(vue@3.4.22)
balloon-css: 1.2.0
js-yaml: 4.1.0
katex: 0.16.10
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
vuepress-plugin-sass-palette: 2.0.0-rc.32(typescript@5.4.5)(vuepress@2.0.0-rc.9)
vuepress-shared: 2.0.0-rc.32(typescript@5.4.5)(vuepress@2.0.0-rc.9)
transitivePeerDependencies:
@ -15495,7 +15552,7 @@ packages:
'@vuepress/helper': 2.0.0-rc.21(typescript@5.4.5)(vuepress@2.0.0-rc.9)
chokidar: 3.6.0
sass: 1.72.0
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
vuepress-shared: 2.0.0-rc.32(typescript@5.4.5)(vuepress@2.0.0-rc.9)
transitivePeerDependencies:
- '@vue/composition-api'
@ -15509,21 +15566,21 @@ packages:
vuepress: 2.0.0-rc.9
dependencies:
'@vuepress/helper': 2.0.0-rc.21(typescript@5.4.5)(vuepress@2.0.0-rc.9)
'@vueuse/core': 10.9.0(vue@3.4.21)
'@vueuse/core': 10.9.0(vue@3.4.22)
cheerio: 1.0.0-rc.12
dayjs: 1.11.10
execa: 8.0.1
fflate: 0.8.2
gray-matter: 4.0.3
semver: 7.6.0
vue: 3.4.21(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21)
vue: 3.4.22(typescript@5.4.5)
vuepress: 2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
dev: false
/vuepress@2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.21):
/vuepress@2.0.0-rc.9(@vuepress/bundler-vite@2.0.0-rc.9)(typescript@5.4.5)(vue@3.4.22):
resolution: {integrity: sha512-jT1ln2lawdph+vVI6n2JfEUhQIcyc1RQWDdQu9DffhJGywJunFcumnUJudpqd1SNIES2Fz1hVCD6gdrE/rVKOQ==}
engines: {node: '>=18.16.0'}
hasBin: true
@ -15544,7 +15601,7 @@ packages:
'@vuepress/markdown': 2.0.0-rc.9(patch_hash=f3on36z73gmvj4jugj25dg7wje)
'@vuepress/shared': 2.0.0-rc.9
'@vuepress/utils': 2.0.0-rc.9
vue: 3.4.21(typescript@5.4.5)
vue: 3.4.22(typescript@5.4.5)
transitivePeerDependencies:
- supports-color
- typescript

View File

@ -30,6 +30,17 @@
"types": "./lib/client/index.d.ts",
"import": "./lib/client/index.js"
},
"./client/components/*": {
"import": "./lib/client/components/*"
},
"./client/composables": {
"types": "./lib/client/composables/index.d.ts",
"import": "./lib/client/composables/index.js"
},
"./client/composables/*": {
"types": "./lib/client/composables/*.d.ts",
"import": "./lib/client/composables/*.js"
},
"./shared": {
"types": "./lib/shared/index.d.ts",
"import": "./lib/shared/index.js"
@ -86,7 +97,7 @@
"katex": "^0.16.10",
"lodash.merge": "^4.6.2",
"nanoid": "^5.0.7",
"vue": "^3.4.21",
"vue": "^3.4.22",
"vue-router": "4.3.0",
"vuepress-plugin-md-enhance": "2.0.0-rc.32",
"vuepress-plugin-md-power": "workspace:*"

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import VIcon from '../VIcon.vue'
import MenuLink from './MenuLink.vue'
defineProps<{
text?: string
icon?: string
icon?: string | { svg: string }
items: any[]
}>()
</script>
@ -11,7 +12,7 @@ defineProps<{
<template>
<div class="menu-group">
<p v-if="text" class="title">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<span v-text="text" />
</p>

View File

@ -2,6 +2,7 @@
import { usePageData } from 'vuepress/client'
import { isActive } from '../../utils/index.js'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
item: any
@ -22,7 +23,7 @@ const page = usePageData()
}"
:href="item.link"
>
<Icon v-if="item.icon" :name="item.icon" />
<VIcon v-if="item.icon" :name="item.icon" />
<i v-text="item.text" />
</AutoLink>
</div>

View File

@ -1,10 +1,11 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { useFlyout } from '../../composables/flyout.js'
import VIcon from '../VIcon.vue'
import VMenu from './VMenu.vue'
defineProps<{
prefixIcon?: string
prefixIcon?: string | { svg: string }
icon?: any
button?: string
label?: string
@ -44,7 +45,7 @@ export default {
@click="open = !open"
>
<span v-if="button || icon" class="text">
<Icon v-if="prefixIcon" :name="prefixIcon" />
<VIcon v-if="prefixIcon" :name="prefixIcon" />
<span v-if="icon" class="option-icon" :class="[icon]" />
<span v-if="button" v-html="button" />
<span class="vpi-chevron-down text-icon" />

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { usePageFrontmatter } from 'vuepress/client'
import { type Component, computed, resolveComponent } from 'vue'
import { type Component, computed, nextTick, onUnmounted, resolveComponent, watch } from 'vue'
import type { PlumeThemeHomeFrontmatter } from '../../../shared/index.js'
import HomeBanner from './HomeBanner.vue'
import HomeHero from './HomeHero.vue'
@ -46,7 +46,7 @@ const config = computed(() => {
return [{
type: 'hero',
full: true,
background: 'filter',
background: 'tint-plate',
hero: matter.value.hero ?? DEFAULT_HERO,
}]
})
@ -56,6 +56,19 @@ const onlyOnce = computed(() => config.value.length === 1)
function resolveComponentName(type: string) {
return components[type] ?? resolveComponent(type)
}
let el: HTMLDivElement | null = null
watch(() => onlyOnce.value, value => nextTick(() => {
if (typeof document !== 'undefined') {
el ??= document.querySelector('#LayoutContent')
el?.classList.toggle('footer-no-border', value)
}
}), { immediate: true })
onUnmounted(() => {
el?.classList.remove('footer-no-border')
})
</script>
<template>

View File

@ -4,7 +4,7 @@ import { isLinkHttp } from 'vuepress/shared'
import { computed, ref } from 'vue'
import VButton from '../VButton.vue'
import { useDarkMode } from '../../composables/index.js'
import { useHomeHeroFilterBackground } from '../../composables/home.js'
import { useHomeHeroTintPlate } from '../../composables/home.js'
import type { PlumeThemeHomeFrontmatter, PlumeThemeHomeHero } from '../../../shared/index.js'
const props = defineProps<PlumeThemeHomeHero>()
@ -13,7 +13,7 @@ const matter = usePageFrontmatter<PlumeThemeHomeFrontmatter>()
const isDark = useDarkMode()
const heroBackground = computed(() => {
if (props.background === 'filter-blur')
if (props.background === 'tint-plate')
return null
const image = props.backgroundImage
? typeof props.backgroundImage === 'string'
@ -37,14 +37,18 @@ const hero = computed(() => props.hero ?? matter.value.hero ?? {})
const actions = computed(() => hero.value.actions ?? [])
const canvas = ref<HTMLCanvasElement>()
useHomeHeroFilterBackground(canvas, computed(() => props.background === 'filter-blur'))
useHomeHeroTintPlate(
canvas,
computed(() => props.background === 'tint-plate'),
computed(() => props.tintPlate),
)
</script>
<template>
<div class="home-hero" :class="{ full: props.full, once: props.onlyOnce }">
<div v-if="heroBackground" class="home-hero-bg" :style="heroBackground" />
<div v-if="background === 'filter-blur'" class="bg-filter">
<div v-if="background === 'tint-plate'" class="bg-filter">
<canvas ref="canvas" width="32" height="32" />
</div>
@ -188,9 +192,9 @@ useHomeHeroFilterBackground(canvas, computed(() => props.background === 'filter-
top: 0;
left: 0;
width: 100%;
height: 20%;
height: 100%;
content: "";
background: linear-gradient(var(--vp-c-bg) 0, transparent 100%);
background: linear-gradient(to bottom, var(--vp-c-bg) 0, transparent 40%, transparent 60%, var(--vp-c-bg) 140%);
}
.bg-filter canvas {

View File

@ -3,6 +3,7 @@ import { usePageData } from 'vuepress/client'
import type { NavItemWithLink } from '../../../shared/index.js'
import { isActive } from '../../utils/index.js'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
item: NavItemWithLink
@ -23,7 +24,7 @@ const page = usePageData()
:href="item.link"
:no-icon="true"
>
<Icon v-if="item.icon" :name="item.icon" />
<VIcon v-if="item.icon" :name="item.icon" />
<i v-text="item.text" />
</AutoLink>
</template>

View File

@ -1,11 +1,12 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import VIcon from '../VIcon.vue'
import NavScreenMenuGroupLink from './NavScreenMenuGroupLink.vue'
import NavScreenMenuGroupSection from './NavScreenMenuGroupSection.vue'
const props = defineProps<{
text: string
icon?: string
icon?: string | { svg: string }
items: any[]
}>()
@ -29,7 +30,7 @@ function toggle() {
@click="toggle"
>
<span class="button-text">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<i v-text="text" />
</span>
<span class="vpi-plus button-icon" />

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import { inject } from 'vue'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
icon?: string
icon?: string | { svg: string }
text: string
link: string
}>()
@ -17,7 +18,7 @@ const closeScreen = inject('close-screen') as () => void
:href="link"
@click="closeScreen"
>
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<i v-text="text" />
</AutoLink>
</template>

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import type { NavItemWithLink } from '../../../shared/index.js'
import VIcon from '../VIcon.vue'
import NavScreenMenuGroupLink from './NavScreenMenuGroupLink.vue'
defineProps<{
icon?: string
icon?: string | { svg: string }
text?: string
items: NavItemWithLink[]
}>()
@ -12,7 +13,7 @@ defineProps<{
<template>
<div class="nav-screen-menu-group-section">
<p v-if="text" class="title">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
{{ text }}
</p>
<NavScreenMenuGroupLink

View File

@ -1,11 +1,12 @@
<script lang="ts" setup>
import { inject } from 'vue'
import AutoLink from '../AutoLink.vue'
import VIcon from '../VIcon.vue'
defineProps<{
text: string
link: string
icon?: string
icon?: string | { svg: string }
}>()
const closeScreen = inject('close-screen') as () => void
@ -13,7 +14,7 @@ const closeScreen = inject('close-screen') as () => void
<template>
<AutoLink class="nav-screen-menu-link" :href="link" @click="closeScreen">
<Icon v-if="icon" :name="icon" />
<VIcon v-if="icon" :name="icon" />
<i v-text="text" />
</AutoLink>
</template>

View File

@ -3,6 +3,7 @@ import type { NotesSidebarItem } from '@vuepress-plume/plugin-notes-data'
import { computed } from 'vue'
import { useSidebarControl } from '../composables/sidebar.js'
import AutoLink from './AutoLink.vue'
import VIcon from './VIcon.vue'
const props = defineProps<{
item: NotesSidebarItem
@ -68,7 +69,7 @@ function onCaretClick() {
>
<div class="indicator" />
<Icon v-if="item.icon" :name="item.icon" />
<VIcon v-if="item.icon" :name="item.icon" />
<AutoLink
v-if="item.link"
@ -222,6 +223,11 @@ function onCaretClick() {
transition: color var(--t-color);
}
.item :deep(.vp__img) {
height: 0.9em;
margin: 0 0.25rem 0 0;
}
.item:hover .caret {
color: var(--vp-c-text-2);
}

View File

@ -11,15 +11,20 @@ const props = withDefaults(defineProps<Props>(), {
let _transition = ''
function setStyle(item: Element) {
function beforeAppear(item: Element) {
const el = item as HTMLElement
if (_transition === '') {
const value = window.getComputedStyle(el).transition
_transition = value && !value.includes('all') ? `${value}, ` : ''
}
el.style.transform = 'translateY(-20px)'
el.style.opacity = '0'
el.style.transition = `transform ${props.duration}s ease-in-out ${props.delay}s, opacity ${props.duration}s ease-in-out ${props.delay}s`
}
function setStyle(item: Element) {
const el = item as HTMLElement
if (!_transition) {
const value = typeof window !== 'undefined' && window.getComputedStyle ? window.getComputedStyle(el).transition : ''
_transition = value && !value.includes('all') ? `${value}, ` : ''
}
el.style.transition = `${_transition}transform ${props.duration}s ease-in-out ${props.delay}s, opacity ${props.duration}s ease-in-out ${props.delay}s`
}
function unsetStyle(item: Element) {
@ -35,7 +40,8 @@ function unsetStyle(item: Element) {
name="drop"
mode="out-in"
:appear="appear"
@before-appear="setStyle"
@appear="setStyle"
@before-appear="beforeAppear"
@after-appear="unsetStyle"
@enter="setStyle"
@after-enter="unsetStyle"

View File

@ -47,6 +47,10 @@ onMounted(() => {
transition: all var(--t-color);
}
.footer-no-border .plume-footer {
border-top: none;
}
.plume-footer p {
color: var(--vp-c-text-2);
transition: color var(--t-color);

View File

@ -0,0 +1,43 @@
<script setup lang="ts">
import { computed } from 'vue'
import { isLinkHttp } from 'vuepress/shared'
import { withBase } from 'vuepress/client'
const props = defineProps<{
name: string | { svg: string }
}>()
const isLink = computed(() =>
typeof props.name === 'string' && (isLinkHttp(props.name) || props.name[0] === '/'),
)
const isSvg = computed(() => typeof props.name === 'object' && !!props.name.svg)
const svg = computed(() => {
if (isSvg.value)
return (props.name as { svg: string }).svg
return ''
})
const link = computed(() => {
if (isLink.value) {
const link = props.name as string
return isLinkHttp(link) ? link : withBase(link)
}
return ''
})
</script>
<template>
<img v-if="isLink" class="vp__img" :src="link" alt="">
<span v-else-if="isSvg" class="vp-iconify" v-html="svg" />
<Icon v-else :name="name" />
</template>
<style scoped>
.vp__img {
display: inline-block;
height: 1em;
margin: 0.3em;
vertical-align: middle;
}
</style>

View File

@ -1,10 +1,30 @@
import type { Ref } from 'vue'
import { computed, onMounted, onUnmounted } from 'vue'
import type { PlumeThemeHomeHero } from '../../shared/index.js'
import { useDarkMode } from './darkMode.js'
export function useHomeHeroFilterBackground(
export interface TintPlate {
r: { value: number, offset: number }
g: { value: number, offset: number }
b: { value: number, offset: number }
}
const lightTint = {
r: { value: 200, offset: 36 },
g: { value: 200, offset: 36 },
b: { value: 200, offset: 36 },
}
const darkTint = {
r: { value: 32, offset: 36 },
g: { value: 32, offset: 36 },
b: { value: 32, offset: 36 },
}
export function useHomeHeroTintPlate(
canvas: Ref<HTMLCanvasElement | undefined>,
enable: Ref<boolean>,
tintPlate: Ref<PlumeThemeHomeHero['tintPlate']>,
) {
const isDark = useDarkMode()
@ -12,7 +32,61 @@ export function useHomeHeroFilterBackground(
let t = 0
let timer: number
const F = computed(() => isDark.value ? 32 : 220)
const plate = computed<TintPlate>(() => {
const defaultTint = isDark.value ? darkTint : lightTint
if (!tintPlate.value)
return defaultTint
const plate = tintPlate.value
if (typeof plate === 'string' || typeof plate === 'number') {
if (isDark.value)
return darkTint
const values = toPlate(plate)
return values.length !== 3 ? lightTint : toTint(values)
}
if (typeof plate === 'object') {
if ('r' in plate) {
if (isDark.value)
return darkTint
return toNumber({ ...lightTint, ...plate })
}
const key = isDark.value ? 'dark' : 'light'
if (key in plate) {
const _plate = plate[key]
if (typeof _plate === 'string' || typeof _plate === 'number') {
const values = toPlate(_plate)
return values.length !== 3 ? lightTint : toTint(values)
}
return toNumber({ ...defaultTint, ...plate })
}
}
return defaultTint
})
function toPlate(plate: number | string) {
return typeof plate === 'number' || Number(plate) === Number.parseInt(plate)
? [plate, plate, plate].map(n => Number(n))
: plate.includes(',') ? plate.replace(/\s/g, '').split(',').map(n => Number(n)) : []
}
function toTint([r, g, b]: number[]) {
return { r: toColor(r), g: toColor(g), b: toColor(b) }
}
function toColor(num: number) {
const offset = 256 - num
return { value: num, offset: offset > 64 ? 64 : offset }
}
function toNumber(tint: TintPlate): TintPlate {
Object.keys(tint).forEach((key) => {
const p = tint[key]
p.value = Number(p.value)
p.offset = Number(p.offset)
})
return tint
}
onMounted(() => {
if (canvas.value && enable.value) {
@ -43,14 +117,17 @@ export function useHomeHeroFilterBackground(
}
function R(x: number, y: number, t: number) {
return (Math.floor(F.value + 36 * Math.cos((x * x - y * y) / 300 + t)))
const r = plate.value.r
return (Math.floor(r.value + r.offset * Math.cos((x * x - y * y) / 300 + t)))
}
function G(x: number, y: number, t: number) {
return (Math.floor(F.value + 36 * Math.sin((x * x * Math.cos(t / 4) + y * y * Math.sin(t / 3)) / 300)))
const g = plate.value.g
return (Math.floor(g.value + g.offset * Math.sin((x * x * Math.cos(t / 4) + y * y * Math.sin(t / 3)) / 300)))
}
function B(x: number, y: number, t: number) {
return (Math.floor(F.value + 36 * Math.sin(5 * Math.sin(t / 9) + ((x - 100) * (x - 100) + (y - 100) * (y - 100)) / 1100)))
const b = plate.value.b
return (Math.floor(b.value + b.offset * Math.sin(5 * Math.sin(t / 9) + ((x - 100) * (x - 100) + (y - 100) * (y - 100)) / 1100)))
}
}

View File

@ -36,11 +36,22 @@ export interface PlumeThemeHomeBanner extends Pick<PlumeHomeConfigBase, 'type' |
hero: PlumeThemeHero
}
export interface PlumeThemeHomeHeroTintPlate {
r: { value: number, offset: number }
g: { value: number, offset: number }
b: { value: number, offset: number }
}
export interface PlumeThemeHomeHero extends PlumeHomeConfigBase {
type: 'hero'
hero: PlumeThemeHero
full?: boolean
background?: 'filter-blur' | (string & { zz_IGNORE?: never })
background?: 'tint-plate' | (string & { zz_IGNORE?: never })
tintPlate?:
| string | number
| { light?: string | number, dark?: string | number }
| PlumeThemeHomeHeroTintPlate
| { light?: PlumeThemeHomeHeroTintPlate, dark?: PlumeThemeHomeHeroTintPlate }
filter?: string
}

View File

@ -3,7 +3,7 @@ export type NavItem = NavItemWithLink | NavItemWithChildren
export interface NavItemWithLink {
text: string
link: string
icon?: string
icon?: string | { svg: string }
/**
* `activeMatch` is expected to be a regex string. We can't use actual
@ -14,13 +14,13 @@ export interface NavItemWithLink {
export interface NavItemChildren {
text?: string
icon?: string
icon?: string | { svg: string }
items: NavItemWithLink[]
}
export interface NavItemWithChildren {
text?: string
icon?: string
icon?: string | { svg: string }
items: (NavItemChildren | NavItemWithLink)[]
/**

View File

@ -30,5 +30,5 @@
"docs/.vuepress/**/*",
"scripts/**/*"
],
"exclude": ["node_modules", ".cache", "lib", "dist"]
"exclude": ["node_modules", ".cache", ".temp", "lib", "dist"]
}