// src/composables/clientData.ts import { inject } from "vue"; var clientDataSymbol = Symbol( __VUEPRESS_DEV__ ? "clientData" : "" ); var useClientData = () => { const clientData = inject(clientDataSymbol); if (!clientData) { throw new Error("useClientData() is called without provider."); } return clientData; }; // src/composables/clientDataUtils.ts var useLayouts = () => useClientData().layouts; var usePageComponent = () => useClientData().pageComponent; var usePageData = () => useClientData().pageData; var usePageFrontmatter = () => useClientData().pageFrontmatter; var usePageHead = () => useClientData().pageHead; var usePageLang = () => useClientData().pageLang; var usePageLayout = () => useClientData().pageLayout; var useRedirects = () => useClientData().redirects; var useRouteLocale = () => useClientData().routeLocale; var useRoutePath = () => useClientData().routePath; var useRoutes = () => useClientData().routes; var useSiteData = () => useClientData().siteData; var useSiteLocaleData = () => useClientData().siteLocaleData; var useData = useClientData; var useFrontmatter = usePageFrontmatter; var useHead = usePageHead; var useLang = usePageLang; var usePage = usePageData; var useSite = useSiteData; var useSiteLocale = useSiteLocaleData; // src/composables/onContentUpdated.ts import { onUnmounted } from "vue"; // src/internal/contentUpdatedCallbacks.ts var contentUpdatedCallbacks = /* @__PURE__ */ new Set(); // src/composables/onContentUpdated.ts var onContentUpdated = (fn) => { contentUpdatedCallbacks.add(fn); onUnmounted(() => { contentUpdatedCallbacks.delete(fn); }); }; // src/composables/updateHead.ts import { inject as inject2 } from "vue"; var updateHeadSymbol = Symbol( __VUEPRESS_DEV__ ? "updateHead" : "" ); var useUpdateHead = () => { const updateHead = inject2(updateHeadSymbol); if (!updateHead) { throw new Error("useUpdateHead() is called without provider."); } return updateHead; }; // src/router/resolveRoutePath.ts import { normalizeRoutePath } from "@vuepress/shared"; // src/internal/routes.ts import { redirects as redirectsRaw, routes as routesRaw } from "@internal/routes"; import { shallowRef } from "vue"; var redirects = shallowRef(redirectsRaw); var routes = shallowRef(routesRaw); if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot)) { __VUE_HMR_RUNTIME__.updateRedirects = (data) => { redirects.value = data; }; __VUE_HMR_RUNTIME__.updateRoutes = (data) => { routes.value = data; }; } // src/router/resolveRoutePath.ts var resolveRoutePath = (pathname, currentPath) => { const normalizedRoutePath = normalizeRoutePath(pathname, currentPath); if (routes.value[normalizedRoutePath]) return normalizedRoutePath; const encodedRoutePath = encodeURI(normalizedRoutePath); if (routes.value[encodedRoutePath]) { return encodedRoutePath; } const redirectedRoutePath = redirects.value[normalizedRoutePath] || redirects.value[encodedRoutePath]; if (redirectedRoutePath) { return redirectedRoutePath; } return normalizedRoutePath; }; // src/router/resolveRoute.ts import { splitPath } from "@vuepress/shared"; var resolveRoute = (path, currentPath) => { const { pathname, hashAndQueries } = splitPath(path); const routePath = resolveRoutePath(pathname, currentPath); const routeFullPath = routePath + hashAndQueries; if (!routes.value[routePath]) { return { ...routes.value["/404.html"], path: routeFullPath, notFound: true }; } return { ...routes.value[routePath], path: routeFullPath, notFound: false }; }; // src/router/resolveRouteFullPath.ts import { splitPath as splitPath2 } from "@vuepress/shared"; var resolveRouteFullPath = (path, currentPath) => { const { pathname, hashAndQueries } = splitPath2(path); return resolveRoutePath(pathname, currentPath) + hashAndQueries; }; // src/router/index.ts import { useRoute, useRouter } from "vue-router"; // src/components/RouteLink.ts import { computed, defineComponent, h } from "vue"; import { useRoute as useRoute2, useRouter as useRouter2 } from "vue-router"; var guardEvent = (event) => { if (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) return; if (event.defaultPrevented) return; if (event.button !== void 0 && event.button !== 0) return; if (event.currentTarget) { const target = event.currentTarget.getAttribute("target"); if (target?.match(/\b_blank\b/i)) return; } event.preventDefault(); return true; }; var RouteLink = defineComponent({ name: "RouteLink", props: { /** * The route path to link to */ to: { type: String, required: true }, /** * Whether the link is active to have an active class * * Notice that the active status is not automatically determined according to the current route. */ active: Boolean, /** * The class to add when the link is active */ activeClass: { type: String, default: "route-link-active" } }, slots: Object, setup(props, { slots }) { const router = useRouter2(); const route = useRoute2(); const path = computed( () => props.to.startsWith("#") || props.to.startsWith("?") ? props.to : `${__VUEPRESS_BASE__}${resolveRouteFullPath(props.to, route.path).substring(1)}` ); return () => h( "a", { class: ["route-link", { [props.activeClass]: props.active }], href: path.value, onClick: (event = {}) => { if (guardEvent(event)) { void router.push(props.to).catch(); } } }, slots.default() ); } }); // src/components/AutoLink.ts import { isLinkWithProtocol } from "@vuepress/shared"; import { computed as computed2, defineComponent as defineComponent2, h as h2, toRef } from "vue"; import { useRoute as useRoute3 } from "vue-router"; var AutoLink = defineComponent2({ name: "AutoLink", props: { config: { type: Object, required: true } }, slots: Object, setup(props, { slots }) { const config = toRef(props, "config"); const route = useRoute3(); const siteData = useSiteData(); const withProtocol = computed2(() => isLinkWithProtocol(config.value.link)); const linkTarget = computed2( () => config.value.target || (withProtocol.value ? "_blank" : void 0) ); const isBlankTarget = computed2(() => linkTarget.value === "_blank"); const isInternal = computed2( () => !withProtocol.value && !isBlankTarget.value ); const linkRel = computed2( () => config.value.rel || (isBlankTarget.value ? "noopener noreferrer" : null) ); const linkAriaLabel = computed2( () => config.value.ariaLabel ?? config.value.text ); const shouldBeActiveInSubpath = computed2(() => { if (config.value.exact) return false; const localePaths = Object.keys(siteData.value.locales); return localePaths.length ? ( // Check all the locales localePaths.every((key) => key !== config.value.link) ) : ( // Check root config.value.link !== "/" ); }); const isActive = computed2(() => { if (!isInternal.value) return false; if (config.value.activeMatch) { return (config.value.activeMatch instanceof RegExp ? config.value.activeMatch : new RegExp(config.value.activeMatch, "u")).test(route.path); } if (shouldBeActiveInSubpath.value) { return route.path.startsWith(config.value.link); } return route.path === config.value.link; }); return () => { const { before, after, default: defaultSlot } = slots; const content = defaultSlot?.(config.value) ?? [ before?.(config.value), config.value.text, after?.(config.value) ]; return isInternal.value ? h2( RouteLink, { "class": "auto-link", "to": config.value.link, "active": isActive.value, "aria-label": linkAriaLabel.value }, () => content ) : h2( "a", { "class": "auto-link external-link", "href": config.value.link, "aria-label": linkAriaLabel.value, "rel": linkRel.value, "target": linkTarget.value }, content ); }; } }); // src/components/ClientOnly.ts import { defineComponent as defineComponent3, onMounted, ref } from "vue"; var ClientOnly = defineComponent3({ name: "ClientOnly", setup(_, ctx) { const isMounted = ref(false); onMounted(() => { isMounted.value = true; }); return () => isMounted.value ? ctx.slots.default?.() : null; } }); // src/components/Content.ts import { computed as computed3, defineAsyncComponent, defineComponent as defineComponent4, h as h3, watch } from "vue"; var runContentUpdatedCallbacks = (reason) => { contentUpdatedCallbacks.forEach((fn) => fn(reason)); }; var Content = defineComponent4({ name: "Content", props: { path: { type: String, required: false, default: "" } }, setup(props) { const pageComponent = usePageComponent(); const ContentComponent = computed3(() => { if (!props.path) return pageComponent.value; const route = resolveRoute(props.path); return defineAsyncComponent( async () => route.loader().then(({ comp }) => comp) ); }); const frontmatter = usePageFrontmatter(); watch( frontmatter, () => { runContentUpdatedCallbacks("updated"); }, { deep: true, flush: "post" } ); return () => h3(ContentComponent.value, { onVnodeMounted: () => { runContentUpdatedCallbacks("mounted"); }, onVnodeUpdated: () => { runContentUpdatedCallbacks("updated"); }, onVnodeBeforeUnmount: () => { runContentUpdatedCallbacks("beforeUnmount"); } }); } }); // src/resolvers.ts import { dedupeHead, isString, resolveLocalePath } from "@vuepress/shared"; import { reactive } from "vue"; // src/constants.ts var LAYOUT_NAME_DEFAULT = "Layout"; var LANG_DEFAULT = "en-US"; // src/resolvers.ts var resolvers = reactive({ /** * Resolve layouts component map */ resolveLayouts: (clientConfigs) => clientConfigs.reduce( (prev, item) => ({ ...prev, ...item.layouts }), {} ), /** * Merge the head config in frontmatter and site locale * * Frontmatter should take priority over site locale */ resolvePageHead: (pageHeadTitle, pageFrontmatter, siteLocaleDate) => { const description = isString(pageFrontmatter.description) ? pageFrontmatter.description : siteLocaleDate.description; const head = [ ...Array.isArray(pageFrontmatter.head) ? pageFrontmatter.head : [], ...siteLocaleDate.head, ["title", {}, pageHeadTitle], ["meta", { name: "description", content: description }] ]; return dedupeHead(head); }, /** * Resolve the content of page head title * * It would be used as the content of the `