diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..35b1c34 --- /dev/null +++ b/404.html @@ -0,0 +1,21 @@ + + + + + + 404 | Nuxt I18n Micro + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/api/events.html b/api/events.html new file mode 100644 index 0000000..6f5a192 --- /dev/null +++ b/api/events.html @@ -0,0 +1,54 @@ + + + + + + 📢 Events | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

📢 Events

🔄 i18n:register

The i18n:register event in Nuxt I18n Micro enables dynamic addition of translations to your application's global i18n context, making the internationalization process seamless and flexible. This event allows you to integrate new translations as needed, enhancing your application's localization capabilities.

📝 Event Details

  • Purpose:

    • Allows dynamic incorporation of additional translations into the existing set for a specific locale.
  • Payload:

    • register:
      • A function provided by the event that takes two arguments:
        • translations (Translations):
          • An object containing key-value pairs representing translations, organized according to the Translations interface.
        • locale (string, optional):
          • The locale code (e.g., 'en', 'ru') for which the translations are registered. Defaults to the locale provided by the event if not specified.
  • Behavior:

    • When triggered, the register function merges the new translations into the global context for the specified locale, updating the available translations across the application.

💡 Example Usage

The following example demonstrates how to use the i18n:register event to dynamically add translations:

typescript
nuxt.hook('i18n:register', async (register: (translations: unknown, locale?: string) => void, locale: string) => {
+  register({
+    "greeting": "Hello",
+    "farewell": "Goodbye"
+  }, locale);
+});

🛠️ Explanation

  • Triggering the Event:

    • The event is hooked into the i18n:register lifecycle event provided by Nuxt I18n Micro.
  • Adding Translations:

    • The example registers English translations for "greeting" and "farewell".
    • The register function merges these translations into the existing set for the provided locale.

🔗 Key Benefits

  • Dynamic Updates:

    • Easily update or add translations without needing to redeploy your entire application.
  • Localization Flexibility:

    • Supports real-time localization adjustments based on user or application needs.

Using the i18n:register event, you can ensure that your application's localization strategy remains flexible and adaptable, enhancing the overall user experience.


🛠️ Modifying Translations with Plugins

To modify translations dynamically in your Nuxt application, using plugins is recommended. Plugins provide a structured way to handle localization updates, especially when working with modules or external translation files.

Registering the Plugin

If you're using a module, register the plugin where translation modifications will occur by adding it to your module’s configuration:

javascript
addPlugin({
+  src: resolve('./plugins/extend_locales'),
+})

This registers the plugin located at ./plugins/extend_locales, which will handle dynamic loading and registration of translations.

Implementing the Plugin

In the plugin, you can manage locale modifications. Here's an example implementation in a Nuxt plugin:

typescript
import { defineNuxtPlugin } from '#app'
+
+export default defineNuxtPlugin(async (nuxtApp) => {
+  // Function to load translations from JSON files and register them
+  const loadTranslations = async (lang: string) => {
+    try {
+      const translations = await import(`../locales/${lang}.json`)
+      return translations.default
+    } catch (error) {
+      console.error(`Error loading translations for language: ${lang}`, error)
+      return null
+    }
+  }
+
+  // Hook into the 'i18n:register' event to dynamically add translations
+  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+  // @ts-expect-error
+  nuxtApp.hook('i18n:register', async (register: (translations: unknown, locale?: string) => void, locale: string) => {
+    const translations = await loadTranslations(locale)
+    if (translations) {
+      register(translations, locale)
+    }
+  })
+})

📝 Detailed Explanation

  1. Loading Translations:
  • The loadTranslations function dynamically imports translation files based on the locale. The files are expected to be in the locales directory and named according to locale codes (e.g., en.json, de.json).
  • On successful loading, translations are returned; otherwise, an error is logged.
  1. Registering Translations:
  • The plugin hooks into the i18n:register event using nuxtApp.hook.
  • When the event is triggered, the register function is called with the loaded translations and the corresponding locale.
  • This merges the new translations into the global i18n context for the specified locale, updating the available translations throughout the application.

🔗 Benefits of Using Plugins for Translation Modifications

  • Separation of Concerns:

    • Encapsulate localization logic separately from the main application code, making management and maintenance easier.
  • Dynamic and Scalable:

    • By dynamically loading and registering translations, you can update content without requiring a full application redeployment, which is especially useful for applications with frequently updated or multilingual content.
  • Enhanced Localization Flexibility:

    • Plugins allow you to modify or extend translations as needed, providing a more adaptable and responsive localization strategy that meets user preferences or business requirements.

By adopting this approach, you can efficiently expand and modify your application's localization through a structured and maintainable process using plugins, keeping internationalization adaptive to changing needs and improving the overall user experience.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/api/methods.html b/api/methods.html new file mode 100644 index 0000000..7a75187 --- /dev/null +++ b/api/methods.html @@ -0,0 +1,149 @@ + + + + + + 🛠️ Methods | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🛠️ Methods

🌍 $getLocale

  • Type: () => string
  • Description: Returns the current locale code.
  • Example:
typescript
const locale = $getLocale()
+// Output: 'en' (assuming the current locale is English)

🌍 $getLocaleName

Version introduced: v1.28.0

  • Type: () => string | null
  • Description: Returns the current locale name from displayName config.
  • Example:
typescript
const locale = $getLocaleName()
+// Output: 'English'

🌍 $getLocales

  • Type: () => Array<{ code: string; iso?: string; dir?: string }>
  • Description: Returns an array of all available locales configured in the module.
  • Example:
typescript
const locales = $getLocales()
+// Output: [{ code: 'en', iso: 'en-US', dir: 'ltr' }, { code: 'fr', iso: 'fr-FR', dir: 'ltr' }]

🔍 $getRouteName

Version introduced: v1.28.0

  • Type: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric, locale?: string) => string
  • Description: Retrieves the base route name without any locale-specific prefixes or suffixes.
  • Parameters:
    • route: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric | undefined — Optional. The route object from which to extract the name.
    • locale: string | undefined — Optional. The locale code to consider when extracting the route name.
  • Example:
typescript
const routeName = $getRouteName(routeObject, 'fr')
+// Output: 'index' (assuming the base route name is 'index')

🔍 $t

  • Type: (key: string, params?: Record<string, any>, defaultValue?: string) => string | number | boolean | Translations | PluralTranslations | unknown | null

  • Description: Fetches a translation for the given key. Optionally interpolates parameters.

  • Parameters:

    • key: string — The translation key.
    • params: Record<string, any> | undefined — Optional. A record of key-value pairs to interpolate into the translation.
    • defaultValue: string | undefined — Optional. The default value to return if the translation is not found.
  • Example:

typescript
const welcomeMessage = $t('welcome', { username: 'Alice', unreadCount: 5 })
+// Output: "Welcome, Alice! You have 5 unread messages."

🔍 $ts

  • Type: (key: string, params?: Record<string, any>, defaultValue?: string) => string
  • Description: A variant of $t that always returns a string. Fetches a translation for the given key and optionally interpolates parameters.
  • Parameters:
    • key: string — The translation key.
    • params: Record<string, any> | undefined — Optional. A record of key-value pairs to interpolate into the translation.
    • defaultValue: string | undefined — Optional. The default value to return if the translation is not found.
  • Example:
typescript
const welcomeMessage = $ts('welcome', { username: 'Alice', unreadCount: 5 })
+// Output: "Welcome, Alice! You have 5 unread messages."

🔢 $tc

  • Type: (key: string, count: number, defaultValue?: string) => string
  • Description: Fetches a pluralized translation for the given key based on the count.
  • Parameters:
    • key: string — The translation key.
    • count: number — The count for pluralization.
    • defaultValue: string | undefined — Optional. The default value to return if the translation is not found.
  • Example:
typescript
const appleCountMessage = $tc('apples', 10)
+// Output: "10 apples" (assuming the plural rule for 'apples' is defined correctly)

🔢 $tn

  • Type: (value: number, options?: Intl.NumberFormatOptions) => string
  • Description: Formats a number according to the current locale using Intl.NumberFormat.
  • Parameters:
    • value: number — The number to format.
    • options: Intl.NumberFormatOptions | undefined — Optional. Intl.NumberFormatOptions to customize the formatting.
  • Example:
typescript
const formattedNumber = $tn(1234567.89, { style: 'currency', currency: 'USD' })
+// Output: "$1,234,567.89" in the 'en-US' locale

Use Cases:

  • Formatting numbers as currency, percentages, or decimals in the appropriate locale format.
  • Customizing the number format using Intl.NumberFormatOptions such as currency, minimum fraction digits, etc.

📅 $td

  • Type: (value: Date | number | string, options?: Intl.DateTimeFormatOptions) => string
  • Description: Formats a date according to the current locale using Intl.DateTimeFormat.
  • Parameters:
    • value: Date | number | string — The date to format, which can be a Date object, a timestamp, or a date string.
    • options: Intl.DateTimeFormatOptions | undefined — Optional. Intl.DateTimeFormatOptions to customize the formatting.
  • Example:
typescript
const formattedDate = $td(new Date(), { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })
+// Output: "Friday, September 1, 2023" in the 'en-US' locale

Use Cases:

  • Displaying dates in a format that aligns with the user's locale, including long or short date formats.
  • Customizing date output using options like weekday names, time formats, and timezone settings.

🔄 $switchLocaleRoute

  • Type: (locale: string) => RouteLocationRaw
  • Description: Return current route with the given locale
  • Parameters:
    • locale: string — Target locale.
  • Example:
typescript
// on /en/news
+const routeFr = $switchLocaleRoute('fr')
+// Output: A route object with the new locale applied, e.g., { name: 'localized-news', params: { locale: 'fr' } }

🔄 $switchLocalePath

  • Type: (locale: string) => string
  • Description: Return url of current route with the given locale
  • Parameters:
    • locale: string — Target locale.
  • Example:
typescript
// on /en/news
+const routeFr = $switchLocalePath('fr')
+window.location.href = routeFr
+// Output: url with new locale applied, e.g., '/fr/nouvelles'

🔄 $switchLocale

  • Type: (locale: string) => void
  • Description: Switches to the given locale and redirects the user to the appropriate localized route.
  • Parameters:
    • locale: string — The locale to switch to.
  • Example:
typescript
$switchLocale('fr')
+// Output: Redirects the user to the French version of the route

🔄 $switchRoute

Version introduced: v1.27.0

  • Type: (route: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric | string, toLocale?: string) => void
  • Description: Switches the route to a new specified destination and changes the locale if needed, redirecting the user to the appropriate localized route.
  • Parameters:
    • route: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric | string — The route to which you want to switch. It can be:
      • A RouteLocationNormalizedLoaded or RouteLocationResolvedGeneric object.
      • A string representing the route path.
  • toLocale (optional): string — The locale to switch to for the target route. If not provided, the current locale is used.

Info: This method facilitates seamless switching between routes, accommodating the current locale configuration. Depending on the input, it resolves the intended route and determines the appropriate locale for redirecting the user to a localized route.

Examples:

  • String Path:

    typescript
    // Switches to the given path with the current locale
    +switchRoute('/about')
  • String Path with Locale:

    typescript
    // Switches to the given path with French locale
    +switchRoute('/about', 'fr')
  • Named Route:

    typescript
    // Switches to a named route with the current locale
    +switchRoute({ name: 'page' })
  • Named Route with Locale:

    typescript
    // Switches to a named route and changes the locale to Spanish
    +switchRoute({ name: 'page' }, 'es')

🔄 $setI18nRouteParams

  • Type: (value: Record<LocaleCode, Record<string, string>> | null) => Record<LocaleCode, Record<string, string>> | null
  • Description: set localized versions of params for all switchLocale* methods and returns passed value. MUST be called inside useAsyncData
  • Parameters:
    • value: Record<LocaleCode, Record<string, string>> | null — params of current route for other locale
  • Example:
typescript
// in pages/news/[id].vue
+// for en/news/1-first-article
+const { $switchLocaleRoute, $setI18nRouteParams, $defineI18nRoute } = useI18n();
+// OR
+const { $switchLocaleRoute, $setI18nRouteParams, $defineI18nRoute } = useNuxtApp();
+$defineI18nRoute({
+  localeRoutes: {
+    en: '/news/:id()',
+    fr: '/nouvelles/:id()',
+    de: '/Nachricht/:id()',
+  },
+})
+const { data: news } = await useAsyncData(`news-${params.id}`, async () => {
+  let response = await $fetch("/api/getNews", {
+    query: {
+      id: params.id,
+    },
+  });
+  if (response?.localeSlugs) {
+    response.localeSlugs = {
+      en: {
+        id: '1-first-article'
+      }
+      fr: {
+        id: '1-premier-article'
+      }
+      de: {
+        id: '1-erster-Artikel'
+      }
+    }
+    $setI18nRouteParams(response?.localeSlugs);
+  }
+  return response;
+});
+$switchLocalePath('fr') // === 'fr/nouvelles/1-premier-article'
+$switchLocalePath('de') // === 'de/Nachricht/1-erster-Artikel'

🌐 $localeRoute

  • Type: (to: RouteLocationRaw, locale?: string) => RouteLocationResolved
  • Description: Generates a localized route object based on the target route.
  • Parameters:
    • to: RouteLocationRaw — The target route object.
    • locale: string | undefined — Optional. The locale for the generated route.
  • Example:
typescript
const localizedRoute = $localeRoute({ name: 'index' })
+// Output: A route object with the current locale applied, e.g., { name: 'index', params: { locale: 'fr' } }

🔄 $localePath

  • Type: (to: RouteLocationRaw, locale?: string) => string
  • Description: Return url based on the target route
  • Parameters:
    • to: RouteLocationRaw — The target route object.
    • locale: string | undefined — Optional. The locale for the generated route.
  • Example:
typescript
const localizedRoute = $localeRoute({ name: 'news' })
+// Output: url with new locale applied, e.g., '/en/nouvelles'

🗂️ $mergeTranslations

  • Type: (newTranslations: Record<string, string>) => void
  • Description: Merges new translations into the existing translation cache for the current route and locale.
  • Parameters:
    • newTranslations: Record<string, string> — The new translations to merge.
  • Example:
typescript
$mergeTranslations({
+  welcome: 'Bienvenue, {username}!'
+})
+// Output: Updates the translation cache with the new French translation

🚦 $defineI18nRoute

  • Type: (routeDefinition: { locales?: string[] | Record<string, Record<string, TranslationObject>>, localeRoutes?: Record<string, string> }) => void
  • Description: Defines route behavior based on the current locale. This method can be used to control access to specific routes based on available locales, provide translations for specific locales, or set custom routes for different locales.
  • Parameters:
    • locales: string[] | Record<string, Record<string, TranslationObject>> — This property determines which locales are available for the route.
    • localeRoutes: Record<string, string> | undefined — Optional. Custom routes for specific locales.
  • Example:
typescript
$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+  },
+  localeRoutes: {
+    ru: '/localesubpage',
+  },
+})

Use Cases:

  • Controlling Access: By specifying available locales, you can control which routes are accessible based on the current locale, ensuring that users only see content relevant to their language.

  • Providing Translations: The locales object allows for providing specific translations for each route, enhancing the user experience by delivering content in the user's preferred language.

  • Custom Routing: The localeRoutes property offers flexibility in defining different paths for specific locales, which can be particularly useful in cases where certain languages or regions require unique navigational flows or URLs.

This function offers a flexible way to manage routing and localization in your Nuxt application, making it easy to tailor the user experience based on the language and region settings of your audience.

Example 1: Controlling Access Based on Locales

typescript
import { useNuxtApp } from '#imports'
+
+const { $defineI18nRoute } = useNuxtApp()
+
+$defineI18nRoute({
+  locales: ['en', 'fr', 'de'] // Only these locales are allowed for this route
+})

Example 2: Providing Translations for Locales

typescript
import { useNuxtApp } from '#imports'
+
+const { $defineI18nRoute } = useNuxtApp()
+
+$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
+    de: { greeting: 'Hallo', farewell: { aaa: { bbb: "Auf Wiedersehen" } } },
+    ru: {} // Russian locale is allowed but no translations are provided
+  }
+})

📝 Explanation:

  • Locales Array: If you only want to specify which locales are allowed for a route, pass an array of locale codes. The user will only be able to access this route if the current locale is in this list.
  • Locales Object: If you want to provide specific translations for each locale, pass an object where each key is a locale code. The value should be an object with key-value pairs for translations. If you do not wish to provide translations for a locale but still want to allow access, pass an empty object ({}) for that locale.

💻 Example Usage in a Component

Here's an example of how to use these methods in a Nuxt component:

vue
<template>
+  <div>
+    <p>{{ $t('key2.key2.key2.key2.key2') }}</p>
+    <p>Current Locale: {{ $getLocale() }}</p>
+
+    <div>
+      {{ $t('welcome', { username: 'Alice', unreadCount: 5 }) }}
+    </div>
+    <div>
+      {{ $tc('apples', 10) }}
+    </div>
+
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale"
+        :disabled="locale === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ locale.code }}
+      </button>
+    </div>
+
+    <div>
+      <NuxtLink :to="$localeRoute({ name: 'index' })">
+        Go to Index
+      </NuxtLink>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useI18n } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t, $tc } = useI18n()
+</script>

🛠️ useNuxtApp

Example:

typescript
import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t } = useNuxtApp()

🧩 useI18n Composable

Example:

typescript
import { useI18n } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t } = useI18n()
+// or
+const i18n = useI18n()

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/assets/api_events.md.D1_p7qRJ.js b/assets/api_events.md.D1_p7qRJ.js new file mode 100644 index 0000000..bc29386 --- /dev/null +++ b/assets/api_events.md.D1_p7qRJ.js @@ -0,0 +1,31 @@ +import{_ as s,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"📢 Events","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"api/events.md","filePath":"api/events.md","lastUpdated":1727601432000}'),e={name:"api/events.md"};function l(h,i,p,r,o,k){return t(),a("div",null,i[0]||(i[0]=[n(`

📢 Events

🔄 i18n:register

The i18n:register event in Nuxt I18n Micro enables dynamic addition of translations to your application's global i18n context, making the internationalization process seamless and flexible. This event allows you to integrate new translations as needed, enhancing your application's localization capabilities.

📝 Event Details

💡 Example Usage

The following example demonstrates how to use the i18n:register event to dynamically add translations:

typescript
nuxt.hook('i18n:register', async (register: (translations: unknown, locale?: string) => void, locale: string) => {
+  register({
+    "greeting": "Hello",
+    "farewell": "Goodbye"
+  }, locale);
+});

🛠️ Explanation

🔗 Key Benefits

Using the i18n:register event, you can ensure that your application's localization strategy remains flexible and adaptable, enhancing the overall user experience.


🛠️ Modifying Translations with Plugins

To modify translations dynamically in your Nuxt application, using plugins is recommended. Plugins provide a structured way to handle localization updates, especially when working with modules or external translation files.

Registering the Plugin

If you're using a module, register the plugin where translation modifications will occur by adding it to your module’s configuration:

javascript
addPlugin({
+  src: resolve('./plugins/extend_locales'),
+})

This registers the plugin located at ./plugins/extend_locales, which will handle dynamic loading and registration of translations.

Implementing the Plugin

In the plugin, you can manage locale modifications. Here's an example implementation in a Nuxt plugin:

typescript
import { defineNuxtPlugin } from '#app'
+
+export default defineNuxtPlugin(async (nuxtApp) => {
+  // Function to load translations from JSON files and register them
+  const loadTranslations = async (lang: string) => {
+    try {
+      const translations = await import(\`../locales/\${lang}.json\`)
+      return translations.default
+    } catch (error) {
+      console.error(\`Error loading translations for language: \${lang}\`, error)
+      return null
+    }
+  }
+
+  // Hook into the 'i18n:register' event to dynamically add translations
+  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+  // @ts-expect-error
+  nuxtApp.hook('i18n:register', async (register: (translations: unknown, locale?: string) => void, locale: string) => {
+    const translations = await loadTranslations(locale)
+    if (translations) {
+      register(translations, locale)
+    }
+  })
+})

📝 Detailed Explanation

  1. Loading Translations:
  1. Registering Translations:

🔗 Benefits of Using Plugins for Translation Modifications

By adopting this approach, you can efficiently expand and modify your application's localization through a structured and maintainable process using plugins, keeping internationalization adaptive to changing needs and improving the overall user experience.

`,31)]))}const c=s(e,[["render",l]]);export{g as __pageData,c as default}; diff --git a/assets/api_events.md.D1_p7qRJ.lean.js b/assets/api_events.md.D1_p7qRJ.lean.js new file mode 100644 index 0000000..bc29386 --- /dev/null +++ b/assets/api_events.md.D1_p7qRJ.lean.js @@ -0,0 +1,31 @@ +import{_ as s,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"📢 Events","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"api/events.md","filePath":"api/events.md","lastUpdated":1727601432000}'),e={name:"api/events.md"};function l(h,i,p,r,o,k){return t(),a("div",null,i[0]||(i[0]=[n(`

📢 Events

🔄 i18n:register

The i18n:register event in Nuxt I18n Micro enables dynamic addition of translations to your application's global i18n context, making the internationalization process seamless and flexible. This event allows you to integrate new translations as needed, enhancing your application's localization capabilities.

📝 Event Details

💡 Example Usage

The following example demonstrates how to use the i18n:register event to dynamically add translations:

typescript
nuxt.hook('i18n:register', async (register: (translations: unknown, locale?: string) => void, locale: string) => {
+  register({
+    "greeting": "Hello",
+    "farewell": "Goodbye"
+  }, locale);
+});

🛠️ Explanation

🔗 Key Benefits

Using the i18n:register event, you can ensure that your application's localization strategy remains flexible and adaptable, enhancing the overall user experience.


🛠️ Modifying Translations with Plugins

To modify translations dynamically in your Nuxt application, using plugins is recommended. Plugins provide a structured way to handle localization updates, especially when working with modules or external translation files.

Registering the Plugin

If you're using a module, register the plugin where translation modifications will occur by adding it to your module’s configuration:

javascript
addPlugin({
+  src: resolve('./plugins/extend_locales'),
+})

This registers the plugin located at ./plugins/extend_locales, which will handle dynamic loading and registration of translations.

Implementing the Plugin

In the plugin, you can manage locale modifications. Here's an example implementation in a Nuxt plugin:

typescript
import { defineNuxtPlugin } from '#app'
+
+export default defineNuxtPlugin(async (nuxtApp) => {
+  // Function to load translations from JSON files and register them
+  const loadTranslations = async (lang: string) => {
+    try {
+      const translations = await import(\`../locales/\${lang}.json\`)
+      return translations.default
+    } catch (error) {
+      console.error(\`Error loading translations for language: \${lang}\`, error)
+      return null
+    }
+  }
+
+  // Hook into the 'i18n:register' event to dynamically add translations
+  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+  // @ts-expect-error
+  nuxtApp.hook('i18n:register', async (register: (translations: unknown, locale?: string) => void, locale: string) => {
+    const translations = await loadTranslations(locale)
+    if (translations) {
+      register(translations, locale)
+    }
+  })
+})

📝 Detailed Explanation

  1. Loading Translations:
  1. Registering Translations:

🔗 Benefits of Using Plugins for Translation Modifications

By adopting this approach, you can efficiently expand and modify your application's localization through a structured and maintainable process using plugins, keeping internationalization adaptive to changing needs and improving the overall user experience.

`,31)]))}const c=s(e,[["render",l]]);export{g as __pageData,c as default}; diff --git a/assets/api_methods.md.CeANTGTe.js b/assets/api_methods.md.CeANTGTe.js new file mode 100644 index 0000000..a67b873 --- /dev/null +++ b/assets/api_methods.md.CeANTGTe.js @@ -0,0 +1,126 @@ +import{_ as i,c as a,a2 as t,o as n}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🛠️ Methods","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"api/methods.md","filePath":"api/methods.md","lastUpdated":1729695167000}'),e={name:"api/methods.md"};function l(h,s,p,k,r,o){return n(),a("div",null,s[0]||(s[0]=[t(`

🛠️ Methods

🌍 $getLocale

typescript
const locale = $getLocale()
+// Output: 'en' (assuming the current locale is English)

🌍 $getLocaleName

Version introduced: v1.28.0

typescript
const locale = $getLocaleName()
+// Output: 'English'

🌍 $getLocales

typescript
const locales = $getLocales()
+// Output: [{ code: 'en', iso: 'en-US', dir: 'ltr' }, { code: 'fr', iso: 'fr-FR', dir: 'ltr' }]

🔍 $getRouteName

Version introduced: v1.28.0

typescript
const routeName = $getRouteName(routeObject, 'fr')
+// Output: 'index' (assuming the base route name is 'index')

🔍 $t

typescript
const welcomeMessage = $t('welcome', { username: 'Alice', unreadCount: 5 })
+// Output: "Welcome, Alice! You have 5 unread messages."

🔍 $ts

typescript
const welcomeMessage = $ts('welcome', { username: 'Alice', unreadCount: 5 })
+// Output: "Welcome, Alice! You have 5 unread messages."

🔢 $tc

typescript
const appleCountMessage = $tc('apples', 10)
+// Output: "10 apples" (assuming the plural rule for 'apples' is defined correctly)

🔢 $tn

typescript
const formattedNumber = $tn(1234567.89, { style: 'currency', currency: 'USD' })
+// Output: "$1,234,567.89" in the 'en-US' locale

Use Cases:

📅 $td

typescript
const formattedDate = $td(new Date(), { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })
+// Output: "Friday, September 1, 2023" in the 'en-US' locale

Use Cases:

🔄 $switchLocaleRoute

typescript
// on /en/news
+const routeFr = $switchLocaleRoute('fr')
+// Output: A route object with the new locale applied, e.g., { name: 'localized-news', params: { locale: 'fr' } }

🔄 $switchLocalePath

typescript
// on /en/news
+const routeFr = $switchLocalePath('fr')
+window.location.href = routeFr
+// Output: url with new locale applied, e.g., '/fr/nouvelles'

🔄 $switchLocale

typescript
$switchLocale('fr')
+// Output: Redirects the user to the French version of the route

🔄 $switchRoute

Version introduced: v1.27.0

Info: This method facilitates seamless switching between routes, accommodating the current locale configuration. Depending on the input, it resolves the intended route and determines the appropriate locale for redirecting the user to a localized route.

Examples:

🔄 $setI18nRouteParams

typescript
// in pages/news/[id].vue
+// for en/news/1-first-article
+const { $switchLocaleRoute, $setI18nRouteParams, $defineI18nRoute } = useI18n();
+// OR
+const { $switchLocaleRoute, $setI18nRouteParams, $defineI18nRoute } = useNuxtApp();
+$defineI18nRoute({
+  localeRoutes: {
+    en: '/news/:id()',
+    fr: '/nouvelles/:id()',
+    de: '/Nachricht/:id()',
+  },
+})
+const { data: news } = await useAsyncData(\`news-\${params.id}\`, async () => {
+  let response = await $fetch("/api/getNews", {
+    query: {
+      id: params.id,
+    },
+  });
+  if (response?.localeSlugs) {
+    response.localeSlugs = {
+      en: {
+        id: '1-first-article'
+      }
+      fr: {
+        id: '1-premier-article'
+      }
+      de: {
+        id: '1-erster-Artikel'
+      }
+    }
+    $setI18nRouteParams(response?.localeSlugs);
+  }
+  return response;
+});
+$switchLocalePath('fr') // === 'fr/nouvelles/1-premier-article'
+$switchLocalePath('de') // === 'de/Nachricht/1-erster-Artikel'

🌐 $localeRoute

typescript
const localizedRoute = $localeRoute({ name: 'index' })
+// Output: A route object with the current locale applied, e.g., { name: 'index', params: { locale: 'fr' } }

🔄 $localePath

typescript
const localizedRoute = $localeRoute({ name: 'news' })
+// Output: url with new locale applied, e.g., '/en/nouvelles'

🗂️ $mergeTranslations

typescript
$mergeTranslations({
+  welcome: 'Bienvenue, {username}!'
+})
+// Output: Updates the translation cache with the new French translation

🚦 $defineI18nRoute

typescript
$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+  },
+  localeRoutes: {
+    ru: '/localesubpage',
+  },
+})

Use Cases:

This function offers a flexible way to manage routing and localization in your Nuxt application, making it easy to tailor the user experience based on the language and region settings of your audience.

Example 1: Controlling Access Based on Locales

typescript
import { useNuxtApp } from '#imports'
+
+const { $defineI18nRoute } = useNuxtApp()
+
+$defineI18nRoute({
+  locales: ['en', 'fr', 'de'] // Only these locales are allowed for this route
+})

Example 2: Providing Translations for Locales

typescript
import { useNuxtApp } from '#imports'
+
+const { $defineI18nRoute } = useNuxtApp()
+
+$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
+    de: { greeting: 'Hallo', farewell: { aaa: { bbb: "Auf Wiedersehen" } } },
+    ru: {} // Russian locale is allowed but no translations are provided
+  }
+})

📝 Explanation:

💻 Example Usage in a Component

Here's an example of how to use these methods in a Nuxt component:

vue
<template>
+  <div>
+    <p>{{ $t('key2.key2.key2.key2.key2') }}</p>
+    <p>Current Locale: {{ $getLocale() }}</p>
+
+    <div>
+      {{ $t('welcome', { username: 'Alice', unreadCount: 5 }) }}
+    </div>
+    <div>
+      {{ $tc('apples', 10) }}
+    </div>
+
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale"
+        :disabled="locale === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ locale.code }}
+      </button>
+    </div>
+
+    <div>
+      <NuxtLink :to="$localeRoute({ name: 'index' })">
+        Go to Index
+      </NuxtLink>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useI18n } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t, $tc } = useI18n()
+</script>

🛠️ useNuxtApp

Example:

typescript
import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t } = useNuxtApp()

🧩 useI18n Composable

Example:

typescript
import { useI18n } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t } = useI18n()
+// or
+const i18n = useI18n()
`,82)]))}const c=i(e,[["render",l]]);export{g as __pageData,c as default}; diff --git a/assets/api_methods.md.CeANTGTe.lean.js b/assets/api_methods.md.CeANTGTe.lean.js new file mode 100644 index 0000000..a67b873 --- /dev/null +++ b/assets/api_methods.md.CeANTGTe.lean.js @@ -0,0 +1,126 @@ +import{_ as i,c as a,a2 as t,o as n}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🛠️ Methods","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"api/methods.md","filePath":"api/methods.md","lastUpdated":1729695167000}'),e={name:"api/methods.md"};function l(h,s,p,k,r,o){return n(),a("div",null,s[0]||(s[0]=[t(`

🛠️ Methods

🌍 $getLocale

typescript
const locale = $getLocale()
+// Output: 'en' (assuming the current locale is English)

🌍 $getLocaleName

Version introduced: v1.28.0

typescript
const locale = $getLocaleName()
+// Output: 'English'

🌍 $getLocales

typescript
const locales = $getLocales()
+// Output: [{ code: 'en', iso: 'en-US', dir: 'ltr' }, { code: 'fr', iso: 'fr-FR', dir: 'ltr' }]

🔍 $getRouteName

Version introduced: v1.28.0

typescript
const routeName = $getRouteName(routeObject, 'fr')
+// Output: 'index' (assuming the base route name is 'index')

🔍 $t

typescript
const welcomeMessage = $t('welcome', { username: 'Alice', unreadCount: 5 })
+// Output: "Welcome, Alice! You have 5 unread messages."

🔍 $ts

typescript
const welcomeMessage = $ts('welcome', { username: 'Alice', unreadCount: 5 })
+// Output: "Welcome, Alice! You have 5 unread messages."

🔢 $tc

typescript
const appleCountMessage = $tc('apples', 10)
+// Output: "10 apples" (assuming the plural rule for 'apples' is defined correctly)

🔢 $tn

typescript
const formattedNumber = $tn(1234567.89, { style: 'currency', currency: 'USD' })
+// Output: "$1,234,567.89" in the 'en-US' locale

Use Cases:

📅 $td

typescript
const formattedDate = $td(new Date(), { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })
+// Output: "Friday, September 1, 2023" in the 'en-US' locale

Use Cases:

🔄 $switchLocaleRoute

typescript
// on /en/news
+const routeFr = $switchLocaleRoute('fr')
+// Output: A route object with the new locale applied, e.g., { name: 'localized-news', params: { locale: 'fr' } }

🔄 $switchLocalePath

typescript
// on /en/news
+const routeFr = $switchLocalePath('fr')
+window.location.href = routeFr
+// Output: url with new locale applied, e.g., '/fr/nouvelles'

🔄 $switchLocale

typescript
$switchLocale('fr')
+// Output: Redirects the user to the French version of the route

🔄 $switchRoute

Version introduced: v1.27.0

Info: This method facilitates seamless switching between routes, accommodating the current locale configuration. Depending on the input, it resolves the intended route and determines the appropriate locale for redirecting the user to a localized route.

Examples:

🔄 $setI18nRouteParams

typescript
// in pages/news/[id].vue
+// for en/news/1-first-article
+const { $switchLocaleRoute, $setI18nRouteParams, $defineI18nRoute } = useI18n();
+// OR
+const { $switchLocaleRoute, $setI18nRouteParams, $defineI18nRoute } = useNuxtApp();
+$defineI18nRoute({
+  localeRoutes: {
+    en: '/news/:id()',
+    fr: '/nouvelles/:id()',
+    de: '/Nachricht/:id()',
+  },
+})
+const { data: news } = await useAsyncData(\`news-\${params.id}\`, async () => {
+  let response = await $fetch("/api/getNews", {
+    query: {
+      id: params.id,
+    },
+  });
+  if (response?.localeSlugs) {
+    response.localeSlugs = {
+      en: {
+        id: '1-first-article'
+      }
+      fr: {
+        id: '1-premier-article'
+      }
+      de: {
+        id: '1-erster-Artikel'
+      }
+    }
+    $setI18nRouteParams(response?.localeSlugs);
+  }
+  return response;
+});
+$switchLocalePath('fr') // === 'fr/nouvelles/1-premier-article'
+$switchLocalePath('de') // === 'de/Nachricht/1-erster-Artikel'

🌐 $localeRoute

typescript
const localizedRoute = $localeRoute({ name: 'index' })
+// Output: A route object with the current locale applied, e.g., { name: 'index', params: { locale: 'fr' } }

🔄 $localePath

typescript
const localizedRoute = $localeRoute({ name: 'news' })
+// Output: url with new locale applied, e.g., '/en/nouvelles'

🗂️ $mergeTranslations

typescript
$mergeTranslations({
+  welcome: 'Bienvenue, {username}!'
+})
+// Output: Updates the translation cache with the new French translation

🚦 $defineI18nRoute

typescript
$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+  },
+  localeRoutes: {
+    ru: '/localesubpage',
+  },
+})

Use Cases:

This function offers a flexible way to manage routing and localization in your Nuxt application, making it easy to tailor the user experience based on the language and region settings of your audience.

Example 1: Controlling Access Based on Locales

typescript
import { useNuxtApp } from '#imports'
+
+const { $defineI18nRoute } = useNuxtApp()
+
+$defineI18nRoute({
+  locales: ['en', 'fr', 'de'] // Only these locales are allowed for this route
+})

Example 2: Providing Translations for Locales

typescript
import { useNuxtApp } from '#imports'
+
+const { $defineI18nRoute } = useNuxtApp()
+
+$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
+    de: { greeting: 'Hallo', farewell: { aaa: { bbb: "Auf Wiedersehen" } } },
+    ru: {} // Russian locale is allowed but no translations are provided
+  }
+})

📝 Explanation:

💻 Example Usage in a Component

Here's an example of how to use these methods in a Nuxt component:

vue
<template>
+  <div>
+    <p>{{ $t('key2.key2.key2.key2.key2') }}</p>
+    <p>Current Locale: {{ $getLocale() }}</p>
+
+    <div>
+      {{ $t('welcome', { username: 'Alice', unreadCount: 5 }) }}
+    </div>
+    <div>
+      {{ $tc('apples', 10) }}
+    </div>
+
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale"
+        :disabled="locale === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ locale.code }}
+      </button>
+    </div>
+
+    <div>
+      <NuxtLink :to="$localeRoute({ name: 'index' })">
+        Go to Index
+      </NuxtLink>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useI18n } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t, $tc } = useI18n()
+</script>

🛠️ useNuxtApp

Example:

typescript
import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t } = useNuxtApp()

🧩 useI18n Composable

Example:

typescript
import { useI18n } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t } = useI18n()
+// or
+const i18n = useI18n()
`,82)]))}const c=i(e,[["render",l]]);export{g as __pageData,c as default}; diff --git a/assets/app.gI023V3V.js b/assets/app.gI023V3V.js new file mode 100644 index 0000000..e222076 --- /dev/null +++ b/assets/app.gI023V3V.js @@ -0,0 +1 @@ +import{R as i}from"./chunks/theme.DDdXCRuz.js";import{R as o,a3 as u,a4 as c,a5 as l,a6 as f,a7 as d,a8 as m,a9 as h,aa as g,ab as A,ac as v,d as P,u as R,v as w,s as y,ad as C,ae as b,af as E,ag as S}from"./chunks/framework.CBrKbnPu.js";function p(e){if(e.extends){const a=p(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=p(i),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),b(),E(),s.setup&&s.setup(),()=>S(s.Layout)}});async function D(){globalThis.__VITEPRESS__=!0;const e=j(),a=_();a.provide(c,e);const t=l(e.route);return a.provide(f,t),a.component("Content",d),a.component("ClientOnly",m),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:h}),{app:a,router:e,data:t}}function _(){return g(T)}function j(){let e=o,a;return A(t=>{let n=v(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&D().then(({app:e,router:a,data:t})=>{a.go().then(()=>{u(a.route,t.site),e.mount("#app")})});export{D as createApp}; diff --git a/assets/chunks/@localSearchIndexroot.tyM1vONZ.js b/assets/chunks/@localSearchIndexroot.tyM1vONZ.js new file mode 100644 index 0000000..d179b72 --- /dev/null +++ b/assets/chunks/@localSearchIndexroot.tyM1vONZ.js @@ -0,0 +1 @@ +const t='{"documentCount":392,"nextId":392,"documentIds":{"0":"/nuxt-i18n-micro/api/events#📢-events","1":"/nuxt-i18n-micro/api/events#🔄-i18n-register","2":"/nuxt-i18n-micro/api/events#📝-event-details","3":"/nuxt-i18n-micro/api/events#💡-example-usage","4":"/nuxt-i18n-micro/api/events#🛠️-explanation","5":"/nuxt-i18n-micro/api/events#🔗-key-benefits","6":"/nuxt-i18n-micro/api/events#🛠️-modifying-translations-with-plugins","7":"/nuxt-i18n-micro/api/events#registering-the-plugin","8":"/nuxt-i18n-micro/api/events#implementing-the-plugin","9":"/nuxt-i18n-micro/api/events#📝-detailed-explanation","10":"/nuxt-i18n-micro/api/events#🔗-benefits-of-using-plugins-for-translation-modifications","11":"/nuxt-i18n-micro/api/methods#🛠️-methods","12":"/nuxt-i18n-micro/api/methods#🌍-getlocale","13":"/nuxt-i18n-micro/api/methods#🌍-getlocalename","14":"/nuxt-i18n-micro/api/methods#🌍-getlocales","15":"/nuxt-i18n-micro/api/methods#🔍-getroutename","16":"/nuxt-i18n-micro/api/methods#🔍-t","17":"/nuxt-i18n-micro/api/methods#🔍-ts","18":"/nuxt-i18n-micro/api/methods#🔢-tc","19":"/nuxt-i18n-micro/api/methods#🔢-tn","20":"/nuxt-i18n-micro/api/methods#use-cases","21":"/nuxt-i18n-micro/api/methods#📅-td","22":"/nuxt-i18n-micro/api/methods#use-cases-1","23":"/nuxt-i18n-micro/api/methods#🔄-switchlocaleroute","24":"/nuxt-i18n-micro/api/methods#🔄-switchlocalepath","25":"/nuxt-i18n-micro/api/methods#🔄-switchlocale","26":"/nuxt-i18n-micro/api/methods#🔄-switchroute","27":"/nuxt-i18n-micro/api/methods#🔄-seti18nrouteparams","28":"/nuxt-i18n-micro/api/methods#🌐-localeroute","29":"/nuxt-i18n-micro/api/methods#🔄-localepath","30":"/nuxt-i18n-micro/api/methods#🗂️-mergetranslations","31":"/nuxt-i18n-micro/api/methods#🚦-definei18nroute","32":"/nuxt-i18n-micro/api/methods#use-cases-2","33":"/nuxt-i18n-micro/api/methods#example-1-controlling-access-based-on-locales","34":"/nuxt-i18n-micro/api/methods#example-2-providing-translations-for-locales","35":"/nuxt-i18n-micro/api/methods#📝-explanation","36":"/nuxt-i18n-micro/api/methods#💻-example-usage-in-a-component","37":"/nuxt-i18n-micro/api/methods#🛠️-usenuxtapp","38":"/nuxt-i18n-micro/api/methods#🧩-usei18n-composable","39":"/nuxt-i18n-micro/components/i18n-link#🌍-i18n-link-component","40":"/nuxt-i18n-micro/components/i18n-link#⚙️-props","41":"/nuxt-i18n-micro/components/i18n-link#to","42":"/nuxt-i18n-micro/components/i18n-link#activestyle","43":"/nuxt-i18n-micro/components/i18n-link#🛠️-example-usages","44":"/nuxt-i18n-micro/components/i18n-link#basic-usage","45":"/nuxt-i18n-micro/components/i18n-link#active-link-styling-with-inline-styles","46":"/nuxt-i18n-micro/components/i18n-link#external-links-handling","47":"/nuxt-i18n-micro/components/i18n-link#🎨-styles","48":"/nuxt-i18n-micro/components/i18n-link#default-active-styles","49":"/nuxt-i18n-micro/components/i18n-link#custom-active-styles","50":"/nuxt-i18n-micro/components/i18n-link#🚀-additional-features","51":"/nuxt-i18n-micro/components/i18n-link#slot-for-custom-content","52":"/nuxt-i18n-micro/components/i18n-link#accessibility-enhancements","53":"/nuxt-i18n-micro/components/i18n-switcher#🌍-i18n-switcher-component","54":"/nuxt-i18n-micro/components/i18n-switcher#⚙️-props","55":"/nuxt-i18n-micro/components/i18n-switcher#customlabels","56":"/nuxt-i18n-micro/components/i18n-switcher#customwrapperstyle","57":"/nuxt-i18n-micro/components/i18n-switcher#custombuttonstyle","58":"/nuxt-i18n-micro/components/i18n-switcher#customdropdownstyle","59":"/nuxt-i18n-micro/components/i18n-switcher#customitemstyle","60":"/nuxt-i18n-micro/components/i18n-switcher#customlinkstyle","61":"/nuxt-i18n-micro/components/i18n-switcher#customactivelinkstyle","62":"/nuxt-i18n-micro/components/i18n-switcher#customdisabledlinkstyle","63":"/nuxt-i18n-micro/components/i18n-switcher#customiconstyle","64":"/nuxt-i18n-micro/components/i18n-switcher#🛠️-example-usages","65":"/nuxt-i18n-micro/components/i18n-switcher#basic-usage","66":"/nuxt-i18n-micro/components/i18n-switcher#custom-labels-and-inline-styles","67":"/nuxt-i18n-micro/components/i18n-switcher#🎨-styles-overview","68":"/nuxt-i18n-micro/components/i18n-t#🌍-i18n-t-component","69":"/nuxt-i18n-micro/components/i18n-t#⚙️-props","70":"/nuxt-i18n-micro/components/i18n-t#keypath","71":"/nuxt-i18n-micro/components/i18n-t#plural","72":"/nuxt-i18n-micro/components/i18n-t#tag","73":"/nuxt-i18n-micro/components/i18n-t#params","74":"/nuxt-i18n-micro/components/i18n-t#defaultvalue","75":"/nuxt-i18n-micro/components/i18n-t#html","76":"/nuxt-i18n-micro/components/i18n-t#hideifempty","77":"/nuxt-i18n-micro/components/i18n-t#custompluralrule","78":"/nuxt-i18n-micro/components/i18n-t#🛠️-example-usages","79":"/nuxt-i18n-micro/components/i18n-t#basic-usage","80":"/nuxt-i18n-micro/components/i18n-t#using-slots-for-dynamic-content","81":"/nuxt-i18n-micro/components/i18n-t#pluralization","82":"/nuxt-i18n-micro/components/i18n-t#🚀-additional-features","83":"/nuxt-i18n-micro/components/i18n-t#default-slot","84":"/nuxt-i18n-micro/components/i18n-t#conditional-rendering","85":"/nuxt-i18n-micro/components/i18n-t#custom-pluralization-rule","86":"/nuxt-i18n-micro/components/i18n-t#advanced-example-with-slots","87":"/nuxt-i18n-micro/composables/useI18n#🛠️-usei18n-composable","88":"/nuxt-i18n-micro/composables/useI18n#⚙️-return-values","89":"/nuxt-i18n-micro/composables/useI18n#getlocale","90":"/nuxt-i18n-micro/composables/useI18n#🌍-getlocalename","91":"/nuxt-i18n-micro/composables/useI18n#getlocales","92":"/nuxt-i18n-micro/composables/useI18n#t","93":"/nuxt-i18n-micro/composables/useI18n#tc","94":"/nuxt-i18n-micro/composables/useI18n#has","95":"/nuxt-i18n-micro/composables/useI18n#mergetranslations","96":"/nuxt-i18n-micro/composables/useI18n#switchlocale","97":"/nuxt-i18n-micro/composables/useI18n#localeroute","98":"/nuxt-i18n-micro/composables/useI18n#loadpagetranslations","99":"/nuxt-i18n-micro/composables/useI18n#🛠️-example-usages","100":"/nuxt-i18n-micro/composables/useI18n#basic-locale-retrieval","101":"/nuxt-i18n-micro/composables/useI18n#translation-with-parameters","102":"/nuxt-i18n-micro/composables/useI18n#switching-locales","103":"/nuxt-i18n-micro/composables/useI18n#generating-a-localized-route","104":"/nuxt-i18n-micro/composables/useI18n#loading-page-specific-translations","105":"/nuxt-i18n-micro/composables/useLocaleHead#🌍-uselocalehead-composable","106":"/nuxt-i18n-micro/composables/useLocaleHead#⚙️-options","107":"/nuxt-i18n-micro/composables/useLocaleHead#adddirattribute","108":"/nuxt-i18n-micro/composables/useLocaleHead#identifierattribute","109":"/nuxt-i18n-micro/composables/useLocaleHead#addseoattributes","110":"/nuxt-i18n-micro/composables/useLocaleHead#baseurl","111":"/nuxt-i18n-micro/composables/useLocaleHead#🛠️-return-values","112":"/nuxt-i18n-micro/composables/useLocaleHead#htmlattrs","113":"/nuxt-i18n-micro/composables/useLocaleHead#meta","114":"/nuxt-i18n-micro/composables/useLocaleHead#link","115":"/nuxt-i18n-micro/composables/useLocaleHead#🛠️-example-usages","116":"/nuxt-i18n-micro/composables/useLocaleHead#basic-usage","117":"/nuxt-i18n-micro/composables/useLocaleHead#customize-identifier-attribute","118":"/nuxt-i18n-micro/composables/useLocaleHead#disable-seo-attributes","119":"/nuxt-i18n-micro/composables/useLocaleHead#specify-a-base-url","120":"/nuxt-i18n-micro/composables/useLocaleHead#🚀-additional-features","121":"/nuxt-i18n-micro/composables/useLocaleHead#seo-meta-and-link-tags","122":"/nuxt-i18n-micro/composables/useLocaleHead#dynamic-locale-and-direction","123":"/nuxt-i18n-micro/composables/useLocaleHead#handling-localized-routes","124":"/nuxt-i18n-micro/composables/useLocaleHead#🛠️-example-usage","125":"/nuxt-i18n-micro/composables/useLocaleHead#explanation-of-the-code","126":"/nuxt-i18n-micro/composables/useLocaleHead#📝-notes","127":"/nuxt-i18n-micro/examples#📚-nuxt-i18n-micro-examples-and-usage","128":"/nuxt-i18n-micro/examples#🛠️-basic-setup","129":"/nuxt-i18n-micro/examples#🌍-locale-switching","130":"/nuxt-i18n-micro/examples#switching-locales-programmatically","131":"/nuxt-i18n-micro/examples#example-json-for-locale-switching","132":"/nuxt-i18n-micro/examples#using-i18n-switcher-component","133":"/nuxt-i18n-micro/examples#🌐-using-i18n-link-for-localized-navigation","134":"/nuxt-i18n-micro/examples#example-json-for-navigation-links","135":"/nuxt-i18n-micro/examples#example-with-active-link-styling","136":"/nuxt-i18n-micro/examples#example-json-for-active-link-styling","137":"/nuxt-i18n-micro/examples#📝-rendering-dynamic-keys-from-translation-files","138":"/nuxt-i18n-micro/examples#example-rendering-dynamic-keys","139":"/nuxt-i18n-micro/examples#example-translation-file-en-json","140":"/nuxt-i18n-micro/examples#example-rendering-dynamic-keys-from-an-object","141":"/nuxt-i18n-micro/examples#example-translation-file-en-json-1","142":"/nuxt-i18n-micro/examples#🌟-using-i18n-t-for-translations-with-slots-and-interpolation","143":"/nuxt-i18n-micro/examples#example-json-for-i18n-t","144":"/nuxt-i18n-micro/examples#with-interpolation","145":"/nuxt-i18n-micro/examples#example-json-for-interpolation","146":"/nuxt-i18n-micro/examples#📝-comprehensive-example-with-nested-sections","147":"/nuxt-i18n-micro/examples#example-json-for-nested-sections","148":"/nuxt-i18n-micro/examples#🌟-using-tc-for-pluralization","149":"/nuxt-i18n-micro/examples#example-using-tc-for-pluralization","150":"/nuxt-i18n-micro/examples#example-json-for-pluralization","151":"/nuxt-i18n-micro/examples#explanation","152":"/nuxt-i18n-micro/examples#additional-example-with-more-complex-pluralization","153":"/nuxt-i18n-micro/examples#🌐-using-tn-for-number-formatting","154":"/nuxt-i18n-micro/examples#example-using-tn-for-number-formatting","155":"/nuxt-i18n-micro/examples#example-json-for-number-formatting-no-json-needed-for-number-formatting-directly","156":"/nuxt-i18n-micro/examples#🗓️-using-td-for-date-and-time-formatting","157":"/nuxt-i18n-micro/examples#example-using-td-for-date-and-time-formatting","158":"/nuxt-i18n-micro/guide/cli#🌐-nuxt-i18n-micro-cli-guide","159":"/nuxt-i18n-micro/guide/cli#📖-introduction","160":"/nuxt-i18n-micro/guide/cli#🔧-installation-and-setup","161":"/nuxt-i18n-micro/guide/cli#📦-installing-nuxt-i18n-micro-cli","162":"/nuxt-i18n-micro/guide/cli#🛠-initializing-in-your-project","163":"/nuxt-i18n-micro/guide/cli#📄-common-arguments","164":"/nuxt-i18n-micro/guide/cli#📋-commands","165":"/nuxt-i18n-micro/guide/cli#📊-stats-command","166":"/nuxt-i18n-micro/guide/cli#🌍-translate-command","167":"/nuxt-i18n-micro/guide/cli#🌐-supported-translation-services","168":"/nuxt-i18n-micro/guide/cli#⚙️-service-configuration","169":"/nuxt-i18n-micro/guide/cli#🛠️-extract-command","170":"/nuxt-i18n-micro/guide/cli#🔄-sync-command","171":"/nuxt-i18n-micro/guide/cli#✅-validate-command","172":"/nuxt-i18n-micro/guide/cli#🧹-clean-command","173":"/nuxt-i18n-micro/guide/cli#📤-import-command","174":"/nuxt-i18n-micro/guide/cli#📥-export-command","175":"/nuxt-i18n-micro/guide/cli#🗂️-export-csv-command","176":"/nuxt-i18n-micro/guide/cli#📑-import-csv-command","177":"/nuxt-i18n-micro/guide/cli#🧾-diff-command","178":"/nuxt-i18n-micro/guide/cli#🔍-check-duplicates-command","179":"/nuxt-i18n-micro/guide/cli#🔄-replace-values-command","180":"/nuxt-i18n-micro/guide/cli#🛠-examples","181":"/nuxt-i18n-micro/guide/cli#⚙️-configuration-guide","182":"/nuxt-i18n-micro/guide/cli#🔑-nuxt-config-js-example","183":"/nuxt-i18n-micro/guide/cli#📝-best-practices","184":"/nuxt-i18n-micro/guide/cli#🔑-consistent-key-naming","185":"/nuxt-i18n-micro/guide/cli#🧹-regular-maintenance","186":"/nuxt-i18n-micro/guide/cli#🛠-automate-translation-workflow","187":"/nuxt-i18n-micro/guide/cli#🛡️-secure-api-keys","188":"/nuxt-i18n-micro/guide/cli#📞-support-and-contributions","189":"/nuxt-i18n-micro/guide/contribution#🤝-contribution-guide","190":"/nuxt-i18n-micro/guide/contribution#📖-introduction","191":"/nuxt-i18n-micro/guide/contribution#🚀-getting-started","192":"/nuxt-i18n-micro/guide/contribution#_1-📚-familiarize-yourself-with-the-project","193":"/nuxt-i18n-micro/guide/contribution#_2-🍴-fork-the-repository","194":"/nuxt-i18n-micro/guide/contribution#_3-📥-clone-your-fork","195":"/nuxt-i18n-micro/guide/contribution#_4-🌱-create-a-branch","196":"/nuxt-i18n-micro/guide/contribution#🛠️-local-development-setup","197":"/nuxt-i18n-micro/guide/contribution#🛠-prerequisites","198":"/nuxt-i18n-micro/guide/contribution#🚀-getting-started-1","199":"/nuxt-i18n-micro/guide/contribution#_1-📥-clone-the-repository","200":"/nuxt-i18n-micro/guide/contribution#_2-📦-install-dependencies","201":"/nuxt-i18n-micro/guide/contribution#_3-🖥️-run-the-development-server","202":"/nuxt-i18n-micro/guide/contribution#_4-🏗️-building-the-module","203":"/nuxt-i18n-micro/guide/contribution#_5-🧹-linting-the-code","204":"/nuxt-i18n-micro/guide/contribution#_6-✅-running-tests","205":"/nuxt-i18n-micro/guide/contribution#_7-🔍-type-checking","206":"/nuxt-i18n-micro/guide/contribution#_8-📚-building-and-previewing-the-documentation","207":"/nuxt-i18n-micro/guide/contribution#_9-🎮-running-the-playground","208":"/nuxt-i18n-micro/guide/contribution#🔧-summary-of-common-scripts","209":"/nuxt-i18n-micro/guide/contribution#🚧-making-changes","210":"/nuxt-i18n-micro/guide/contribution#_1-💻-code","211":"/nuxt-i18n-micro/guide/contribution#_2-🧹-run-linting","212":"/nuxt-i18n-micro/guide/contribution#_3-🧪-test-your-changes","213":"/nuxt-i18n-micro/guide/contribution#_4-📝-commit-your-changes","214":"/nuxt-i18n-micro/guide/contribution#✅-commit-message-format","215":"/nuxt-i18n-micro/guide/contribution#📋-examples","216":"/nuxt-i18n-micro/guide/contribution#🛠️-commit-types","217":"/nuxt-i18n-micro/guide/contribution#_5-🚀-push-to-github","218":"/nuxt-i18n-micro/guide/contribution#_6-🔄-create-a-pull-request","219":"/nuxt-i18n-micro/guide/contribution#_7-🕵️‍♂️-await-feedback","220":"/nuxt-i18n-micro/guide/contribution#💡-contribution-tips","221":"/nuxt-i18n-micro/guide/crowdin#🌐-crowdin-integration-guide","222":"/nuxt-i18n-micro/guide/crowdin#📖-introduction","223":"/nuxt-i18n-micro/guide/crowdin#🔧-installation-and-setup","224":"/nuxt-i18n-micro/guide/crowdin#📦-installing-crowdin-cli","225":"/nuxt-i18n-micro/guide/crowdin#🛠-initializing-crowdin-in-your-project","226":"/nuxt-i18n-micro/guide/crowdin#🗂️-configuration-guide","227":"/nuxt-i18n-micro/guide/crowdin#📄-crowdin-configuration-file-crowdin-yml","228":"/nuxt-i18n-micro/guide/crowdin#📂-key-configuration-parameters","229":"/nuxt-i18n-micro/guide/crowdin#📂-files-configuration","230":"/nuxt-i18n-micro/guide/crowdin#⬆️-uploading-source-files-to-crowdin","231":"/nuxt-i18n-micro/guide/crowdin#⬇️-downloading-translations-from-crowdin","232":"/nuxt-i18n-micro/guide/crowdin#⚙️-best-practices","233":"/nuxt-i18n-micro/guide/crowdin#🔑-consistent-key-naming","234":"/nuxt-i18n-micro/guide/crowdin#🧹-regular-maintenance","235":"/nuxt-i18n-micro/guide/crowdin#🛠-automate-uploads-and-downloads","236":"/nuxt-i18n-micro/guide/custom-locale-routes#🔗-custom-localized-routes-with-localeroutes-in-nuxt-i18n-micro","237":"/nuxt-i18n-micro/guide/custom-locale-routes#📖-introduction-to-localeroutes","238":"/nuxt-i18n-micro/guide/custom-locale-routes#🚀-primary-use-case-of-localeroutes","239":"/nuxt-i18n-micro/guide/custom-locale-routes#📄-example-defining-localeroutes-in-definei18nroute","240":"/nuxt-i18n-micro/guide/custom-locale-routes#🔄-how-localeroutes-work","241":"/nuxt-i18n-micro/guide/custom-locale-routes#🌱-use-cases-for-localeroutes","242":"/nuxt-i18n-micro/guide/custom-locale-routes#📄-example-using-localeroutes-in-a-page","243":"/nuxt-i18n-micro/guide/custom-locale-routes#🛠️-using-localeroutes-in-different-contexts","244":"/nuxt-i18n-micro/guide/custom-locale-routes#📝-best-practices-for-using-localeroutes","245":"/nuxt-i18n-micro/guide/faq#faq-common-issues-solutions","246":"/nuxt-i18n-micro/guide/faq#❓-what-if-a-route-doesn-t-load","247":"/nuxt-i18n-micro/guide/faq#❓-why-is-the-assets-locales-folder-added-to-the-server-folder","248":"/nuxt-i18n-micro/guide/faq#❓-is-nuxt-i18n-micro-inspired-by-vue-i18n-what-about-features-like-modifiers","249":"/nuxt-i18n-micro/guide/faq#❓-can-i-use-nuxtlink-or-i18nlink-directly-in-translation-strings","250":"/nuxt-i18n-micro/guide/folder-structure#📂-folder-structure-guide","251":"/nuxt-i18n-micro/guide/folder-structure#📖-introduction","252":"/nuxt-i18n-micro/guide/folder-structure#🗂️-recommended-folder-structure","253":"/nuxt-i18n-micro/guide/folder-structure#🔧-basic-structure","254":"/nuxt-i18n-micro/guide/folder-structure#📄-explanation-of-structure","255":"/nuxt-i18n-micro/guide/folder-structure#_1-🌍-global-translation-files","256":"/nuxt-i18n-micro/guide/folder-structure#_2-📄-page-specific-translation-files","257":"/nuxt-i18n-micro/guide/folder-structure#📂-handling-dynamic-routes-and-nested-paths","258":"/nuxt-i18n-micro/guide/folder-structure#dynamic-route-translation-folder-structure","259":"/nuxt-i18n-micro/guide/folder-structure#🛠-customizing-the-directory-structure","260":"/nuxt-i18n-micro/guide/folder-structure#⚙️-how-translations-are-loaded","261":"/nuxt-i18n-micro/guide/folder-structure#🌍-dynamic-locale-routes","262":"/nuxt-i18n-micro/guide/folder-structure#💾-caching-and-pre-rendering","263":"/nuxt-i18n-micro/guide/folder-structure#📝-best-practices","264":"/nuxt-i18n-micro/guide/folder-structure#📂-use-page-specific-files-wisely","265":"/nuxt-i18n-micro/guide/folder-structure#🔑-keep-translation-keys-consistent","266":"/nuxt-i18n-micro/guide/folder-structure#🗂️-organize-translations-by-context","267":"/nuxt-i18n-micro/guide/folder-structure#🧹-regularly-clean-up-unused-translations","268":"/nuxt-i18n-micro/guide/getting-started#🌐-getting-started-with-nuxt-i18n-micro","269":"/nuxt-i18n-micro/guide/getting-started#📖-overview","270":"/nuxt-i18n-micro/guide/getting-started#🤔-why-choose-nuxt-i18n-micro","271":"/nuxt-i18n-micro/guide/getting-started#🛠-installation","272":"/nuxt-i18n-micro/guide/getting-started#⚙️-basic-setup","273":"/nuxt-i18n-micro/guide/getting-started#📂-folder-structure","274":"/nuxt-i18n-micro/guide/getting-started#⚙️-module-configuration-options","275":"/nuxt-i18n-micro/guide/getting-started#🌍-locales","276":"/nuxt-i18n-micro/guide/getting-started#🌐-defaultlocale","277":"/nuxt-i18n-micro/guide/getting-started#🗂-translationdir","278":"/nuxt-i18n-micro/guide/getting-started#🔍-meta","279":"/nuxt-i18n-micro/guide/getting-started#🐛-debug","280":"/nuxt-i18n-micro/guide/getting-started#🐛-types","281":"/nuxt-i18n-micro/guide/getting-started#🔗-metabaseurl","282":"/nuxt-i18n-micro/guide/getting-started#🌍-autodetectlanguage","283":"/nuxt-i18n-micro/guide/getting-started#🔍-autodetectpath","284":"/nuxt-i18n-micro/guide/getting-started#🔢-plural","285":"/nuxt-i18n-micro/guide/getting-started#🚦-includedefaultlocaleroute","286":"/nuxt-i18n-micro/guide/getting-started#🚦-customregexmatcher","287":"/nuxt-i18n-micro/guide/getting-started#🔗-routeslocalelinks","288":"/nuxt-i18n-micro/guide/getting-started#🧩-define","289":"/nuxt-i18n-micro/guide/getting-started#🔄-disablepagelocales","290":"/nuxt-i18n-micro/guide/getting-started#📂-folder-structure-with-disablepagelocales-true","291":"/nuxt-i18n-micro/guide/getting-started#👀-disablewatcher","292":"/nuxt-i18n-micro/guide/getting-started#🔗-apibaseurl","293":"/nuxt-i18n-micro/guide/getting-started#🍪-localecookie","294":"/nuxt-i18n-micro/guide/getting-started#🌐-fallbacklocale","295":"/nuxt-i18n-micro/guide/getting-started#🌐-globallocaleroutes","296":"/nuxt-i18n-micro/guide/getting-started#usage","297":"/nuxt-i18n-micro/guide/getting-started#🔄-caching-mechanism","298":"/nuxt-i18n-micro/guide/layers#🗂️-layers-in-nuxt-i18n-micro","299":"/nuxt-i18n-micro/guide/layers#📖-introduction-to-layers","300":"/nuxt-i18n-micro/guide/layers#🛠️-primary-configuration-layer","301":"/nuxt-i18n-micro/guide/layers#📄-example-defining-the-primary-configuration-layer","302":"/nuxt-i18n-micro/guide/layers#🌱-child-layers","303":"/nuxt-i18n-micro/guide/layers#📄-example-extending-the-primary-layer-in-a-child-layer","304":"/nuxt-i18n-micro/guide/layers#🌐-using-layers-in-a-modular-application","305":"/nuxt-i18n-micro/guide/layers#📄-example-layered-configuration-in-a-modular-application","306":"/nuxt-i18n-micro/guide/layers#primary-layer-global-configuration","307":"/nuxt-i18n-micro/guide/layers#child-layer-for-admin-panel","308":"/nuxt-i18n-micro/guide/layers#child-layer-for-customer-support-portal","309":"/nuxt-i18n-micro/guide/layers#📝-best-practices-for-using-layers","310":"/nuxt-i18n-micro/guide/migration#🔄-migration-from-nuxt-i18n-to-nuxt-i18n-micro","311":"/nuxt-i18n-micro/guide/migration#📖-introduction","312":"/nuxt-i18n-micro/guide/migration#🚀-why-migrate","313":"/nuxt-i18n-micro/guide/migration#🔍-key-differences","314":"/nuxt-i18n-micro/guide/migration#🛠️-step-by-step-migration","315":"/nuxt-i18n-micro/guide/migration#_1-🛠️-install-nuxt-i18n-micro","316":"/nuxt-i18n-micro/guide/migration#_2-🔄-update-configuration","317":"/nuxt-i18n-micro/guide/migration#_3-🗂️-reorganize-translation-files","318":"/nuxt-i18n-micro/guide/migration#_4-🔗-replace-nuxt-link-with-nuxtlink","319":"/nuxt-i18n-micro/guide/migration#_5-🛠️-handle-seo-configurations","320":"/nuxt-i18n-micro/guide/migration#_6-🧪-test-your-application","321":"/nuxt-i18n-micro/guide/migration#🛡️-common-issues-and-troubleshooting","322":"/nuxt-i18n-micro/guide/migration#❌-translation-files-not-loading","323":"/nuxt-i18n-micro/guide/migration#⚠️-route-not-found-errors","324":"/nuxt-i18n-micro/guide/migration#🏷️-missing-seo-tags","325":"/nuxt-i18n-micro/guide/multi-domain-locales#🌍-setting-up-multi-domain-locales-with-nuxt-i18n-micro-using-layers","326":"/nuxt-i18n-micro/guide/multi-domain-locales#📝-introduction","327":"/nuxt-i18n-micro/guide/multi-domain-locales#🎯-objective","328":"/nuxt-i18n-micro/guide/multi-domain-locales#🛠-steps-to-implement-multi-domain-locales","329":"/nuxt-i18n-micro/guide/multi-domain-locales#_1-create-the-base-layer","330":"/nuxt-i18n-micro/guide/multi-domain-locales#base-layer-configuration","331":"/nuxt-i18n-micro/guide/multi-domain-locales#_2-create-domain-specific-child-layers","332":"/nuxt-i18n-micro/guide/multi-domain-locales#example-configuration-for-the-french-domain","333":"/nuxt-i18n-micro/guide/multi-domain-locales#example-configuration-for-the-german-domain","334":"/nuxt-i18n-micro/guide/multi-domain-locales#_3-deploy-the-application-for-each-domain","335":"/nuxt-i18n-micro/guide/multi-domain-locales#_4-set-up-multiple-projects-for-different-locales","336":"/nuxt-i18n-micro/guide/multi-domain-locales#_5-configure-routing-based-on-domain","337":"/nuxt-i18n-micro/guide/multi-domain-locales#_6-deploy-and-verify","338":"/nuxt-i18n-micro/guide/multi-domain-locales#📝-best-practices","339":"/nuxt-i18n-micro/guide/multi-domain-locales#🎉-conclusion","340":"/nuxt-i18n-micro/guide/per-component-translations#📖-per-component-translations-in-nuxt-i18n-micro","341":"/nuxt-i18n-micro/guide/per-component-translations#overview","342":"/nuxt-i18n-micro/guide/per-component-translations#definei18nroute-function","343":"/nuxt-i18n-micro/guide/per-component-translations#method-signature","344":"/nuxt-i18n-micro/guide/per-component-translations#parameters","345":"/nuxt-i18n-micro/guide/per-component-translations#example-usage","346":"/nuxt-i18n-micro/guide/per-component-translations#use-cases","347":"/nuxt-i18n-micro/guide/per-component-translations#best-practices","348":"/nuxt-i18n-micro/guide/per-component-translations#example-vue-page-with-per-component-translations","349":"/nuxt-i18n-micro/guide/per-component-translations#explanation","350":"/nuxt-i18n-micro/guide/per-component-translations#summary","351":"/nuxt-i18n-micro/guide/performance-results#performance-test-results","352":"/nuxt-i18n-micro/guide/performance-results#project-information","353":"/nuxt-i18n-micro/guide/performance-results#description","354":"/nuxt-i18n-micro/guide/performance-results#important-note","355":"/nuxt-i18n-micro/guide/performance-results#build-performance-for-test-fixtures-i18n-micro","356":"/nuxt-i18n-micro/guide/performance-results#build-performance-for-test-fixtures-i18n","357":"/nuxt-i18n-micro/guide/performance-results#⏱️-build-time-and-resource-consumption","358":"/nuxt-i18n-micro/guide/performance-results#performance-comparison","359":"/nuxt-i18n-micro/guide/performance-results#stress-test-with-artillery-for-test-fixtures-i18n","360":"/nuxt-i18n-micro/guide/performance-results#stress-test-with-artillery-for-test-fixtures-i18n-micro","361":"/nuxt-i18n-micro/guide/performance-results#comparison-between-i18n-and-i18n-micro","362":"/nuxt-i18n-micro/guide/performance-results#📊-detailed-performance-analysis","363":"/nuxt-i18n-micro/guide/performance-results#🔍-test-logic-explanation","364":"/nuxt-i18n-micro/guide/performance-results#🛠-why-this-approach","365":"/nuxt-i18n-micro/guide/performance#🚀-performance-guide","366":"/nuxt-i18n-micro/guide/performance#📖-introduction","367":"/nuxt-i18n-micro/guide/performance#🤔-why-focus-on-performance","368":"/nuxt-i18n-micro/guide/performance#📊-performance-comparison","369":"/nuxt-i18n-micro/guide/performance#⏱️-build-time-and-resource-consumption","370":"/nuxt-i18n-micro/guide/performance#🌐-server-performance-under-load","371":"/nuxt-i18n-micro/guide/performance#🔍-interpretation-of-results","372":"/nuxt-i18n-micro/guide/performance#⚙️-key-optimizations","373":"/nuxt-i18n-micro/guide/performance#🛠️-minimalist-design","374":"/nuxt-i18n-micro/guide/performance#🚦-efficient-routing","375":"/nuxt-i18n-micro/guide/performance#📂-streamlined-translation-loading","376":"/nuxt-i18n-micro/guide/performance#💾-caching-and-pre-rendering","377":"/nuxt-i18n-micro/guide/performance#📝-tips-for-maximizing-performance","378":"/nuxt-i18n-micro/guide/seo#🌐-seo-guide-for-nuxt-i18n-micro","379":"/nuxt-i18n-micro/guide/seo#📖-introduction","380":"/nuxt-i18n-micro/guide/seo#⚙️-automatic-seo-handling","381":"/nuxt-i18n-micro/guide/seo#🔑-key-seo-features","382":"/nuxt-i18n-micro/guide/seo#🛠️-configuration","383":"/nuxt-i18n-micro/guide/seo#🎯-benefits","384":"/nuxt-i18n-micro/#✨-introduction","385":"/nuxt-i18n-micro/#📝-why-nuxt-i18n-micro","386":"/nuxt-i18n-micro/#🏁-performance-comparison","387":"/nuxt-i18n-micro/#⏱️-build-time-and-resource-consumption","388":"/nuxt-i18n-micro/#🌐-server-performance-10k-requests","389":"/nuxt-i18n-micro/#🔑-key-features","390":"/nuxt-i18n-micro/#⚙️-quick-setup","391":"/nuxt-i18n-micro/#🗂-folder-structure"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[2,1,1],"1":[3,2,37],"2":[3,5,65],"3":[3,5,27],"4":[2,5,34],"5":[3,5,44],"6":[5,2,31],"7":[3,7,40],"8":[3,7,75],"9":[3,7,67],"10":[8,7,87],"11":[2,1,1],"12":[2,2,19],"13":[2,2,26],"14":[2,2,31],"15":[2,2,49],"16":[2,2,61],"17":[2,2,61],"18":[2,2,45],"19":[2,2,44],"20":[3,4,23],"21":[2,2,55],"22":[3,4,30],"23":[2,2,35],"24":[2,2,35],"25":[2,2,29],"26":[2,2,91],"27":[2,2,78],"28":[2,2,41],"29":[2,2,38],"30":[2,2,36],"31":[2,2,60],"32":[3,4,91],"33":[7,4,19],"34":[6,4,34],"35":[3,4,56],"36":[6,2,65],"37":[2,2,13],"38":[3,2,15],"39":[6,1,40],"40":[2,6,1],"41":[1,8,38],"42":[1,8,52],"43":[3,6,1],"44":[2,9,20],"45":[6,9,32],"46":[3,9,38],"47":[2,6,22],"48":[3,8,27],"49":[3,8,25],"50":[3,6,1],"51":[4,9,28],"52":[2,9,29],"53":[6,1,36],"54":[2,6,1],"55":[1,8,37],"56":[1,8,32],"57":[1,8,32],"58":[1,8,37],"59":[1,8,30],"60":[1,8,35],"61":[1,8,34],"62":[1,8,33],"63":[1,8,35],"64":[3,6,1],"65":[2,9,16],"66":[5,9,67],"67":[3,6,66],"68":[6,1,38],"69":[2,6,1],"70":[1,8,25],"71":[1,8,23],"72":[1,8,27],"73":[1,8,33],"74":[1,8,30],"75":[1,8,26],"76":[1,8,30],"77":[1,8,58],"78":[3,6,1],"79":[2,9,20],"80":[5,9,52],"81":[1,9,20],"82":[3,6,1],"83":[2,9,34],"84":[2,9,23],"85":[3,9,31],"86":[4,9,23],"87":[3,1,50],"88":[3,3,16],"89":[1,6,22],"90":[2,3,26],"91":[1,5,31],"92":[1,5,56],"93":[1,5,41],"94":[1,5,28],"95":[1,5,25],"96":[1,5,19],"97":[1,5,26],"98":[1,5,29],"99":[3,3,1],"100":[3,5,12],"101":[3,5,20],"102":[2,5,13],"103":[4,5,18],"104":[4,5,17],"105":[3,1,38],"106":[2,3,12],"107":[1,5,30],"108":[1,5,33],"109":[1,5,31],"110":[1,5,30],"111":[3,3,28],"112":[1,6,31],"113":[1,6,34],"114":[1,6,37],"115":[3,3,1],"116":[2,6,12],"117":[3,6,17],"118":[3,6,17],"119":[4,6,19],"120":[3,3,1],"121":[5,6,29],"122":[4,6,27],"123":[3,6,46],"124":[3,3,34],"125":[4,6,78],"126":[2,6,72],"127":[7,1,35],"128":[3,7,41],"129":[3,7,1],"130":[3,10,45],"131":[5,10,8],"132":[6,10,29],"133":[9,7,36],"134":[5,16,7],"135":[5,16,14],"136":[6,16,16],"137":[7,7,33],"138":[4,14,56],"139":[6,14,15],"140":[7,14,52],"141":[6,14,20],"142":[12,7,34],"143":[8,18,7],"144":[2,18,15],"145":[4,18,10],"146":[6,7,78],"147":[5,13,61],"148":[5,7,37],"149":[5,12,51],"150":[4,12,25],"151":[1,12,26],"152":[6,12,48],"153":[6,7,36],"154":[6,13,43],"155":[11,13,1],"156":[8,7,31],"157":[8,14,50],"158":[6,1,1],"159":[2,6,53],"160":[4,6,1],"161":[6,10,21],"162":[5,10,28],"163":[3,10,24],"164":[2,6,1],"165":[3,8,50],"166":[3,8,87],"167":[4,11,52],"168":[3,11,43],"169":[3,8,26],"170":[3,8,19],"171":[3,8,21],"172":[3,8,14],"173":[3,8,28],"174":[3,8,23],"175":[4,8,52],"176":[4,8,43],"177":[3,8,40],"178":[4,8,81],"179":[4,8,174],"180":[2,6,35],"181":[3,6,21],"182":[5,8,41],"183":[3,6,1],"184":[4,9,12],"185":[3,9,15],"186":[4,9,24],"187":[4,9,28],"188":[4,6,52],"189":[3,1,1],"190":[2,3,44],"191":[3,3,1],"192":[7,6,33],"193":[5,6,23],"194":[5,6,27],"195":[5,6,26],"196":[4,1,1],"197":[2,4,20],"198":[3,4,1],"199":[5,7,21],"200":[4,7,15],"201":[6,7,37],"202":[5,7,27],"203":[5,7,28],"204":[4,7,22],"205":[4,7,18],"206":[7,7,26],"207":[5,7,36],"208":[5,4,45],"209":[3,1,1],"210":[3,3,30],"211":[4,3,27],"212":[5,3,35],"213":[5,3,20],"214":[4,7,14],"215":[3,7,23],"216":[4,7,36],"217":[5,3,13],"218":[6,3,35],"219":[4,3,28],"220":[3,3,50],"221":[4,1,1],"222":[2,4,38],"223":[4,4,23],"224":[4,8,13],"225":[6,8,28],"226":[3,4,1],"227":[7,6,49],"228":[4,6,54],"229":[3,6,40],"230":[6,4,30],"231":[5,4,31],"232":[3,4,1],"233":[4,7,14],"234":[3,7,15],"235":[5,7,43],"236":[10,1,1],"237":[4,10,46],"238":[6,10,45],"239":[6,15,33],"240":[4,15,31],"241":[5,10,1],"242":[7,14,69],"243":[6,14,42],"244":[6,10,69],"245":[5,1,1],"246":[9,5,59],"247":[11,5,91],"248":[15,5,93],"249":[12,5,72],"250":[4,1,1],"251":[2,4,47],"252":[4,4,31],"253":[3,6,25],"254":[4,6,1],"255":[5,9,54],"256":[6,9,71],"257":[7,6,33],"258":[5,12,57],"259":[5,6,50],"260":[5,4,1],"261":[4,9,56],"262":[5,9,57],"263":[3,4,1],"264":[6,7,30],"265":[5,7,25],"266":[5,7,37],"267":[6,7,28],"268":[7,1,1],"269":[2,7,36],"270":[7,7,45],"271":[2,7,16],"272":[3,7,34],"273":[3,10,35],"274":[4,7,18],"275":[2,11,58],"276":[2,11,17],"277":[2,11,18],"278":[2,11,23],"279":[2,11,22],"280":[2,11,24],"281":[2,11,25],"282":[2,11,28],"283":[2,11,26],"284":[2,11,54],"285":[2,11,23],"286":[2,11,48],"287":[2,11,24],"288":[2,11,35],"289":[2,11,25],"290":[6,11,32],"291":[2,11,17],"292":[2,11,57],"293":[2,11,16],"294":[2,11,40],"295":[2,11,79],"296":[2,11,52],"297":[3,1,58],"298":[6,1,1],"299":[4,6,47],"300":[4,6,34],"301":[7,10,64],"302":[3,6,43],"303":[9,8,78],"304":[7,8,28],"305":[8,8,34],"306":[5,15,23],"307":[6,15,37],"308":[7,15,73],"309":[6,6,70],"310":[9,1,1],"311":[2,9,39],"312":[4,9,52],"313":[3,9,83],"314":[4,9,1],"315":[6,12,14],"316":[4,12,41],"317":[5,12,32],"318":[10,12,35],"319":[5,12,27],"320":[5,12,34],"321":[5,9,1],"322":[5,14,23],"323":[5,14,21],"324":[4,14,26],"325":[12,1,1],"326":[2,12,64],"327":[2,12,38],"328":[7,12,1],"329":[5,16,27],"330":[3,21,30],"331":[6,16,26],"332":[6,20,54],"333":[6,20,53],"334":[7,16,17],"335":[8,16,45],"336":[6,16,35],"337":[4,16,27],"338":[3,12,33],"339":[2,12,63],"340":[8,1,1],"341":[1,8,44],"342":[2,8,29],"343":[2,10,11],"344":[1,10,55],"345":[2,10,25],"346":[2,8,92],"347":[2,8,64],"348":[7,8,77],"349":[1,8,68],"350":[1,8,48],"351":[3,1,1],"352":[2,3,11],"353":[2,5,55],"354":[3,5,70],"355":[7,3,24],"356":[6,3,25],"357":[6,8,23],"358":[2,3,29],"359":[8,3,38],"360":[9,3,37],"361":[5,3,38],"362":[4,3,1],"363":[4,6,118],"364":[5,6,84],"365":[3,1,1],"366":[2,3,39],"367":[6,3,57],"368":[3,3,38],"369":[6,5,40],"370":[5,5,50],"371":[4,5,81],"372":[3,3,1],"373":[3,6,30],"374":[3,6,41],"375":[4,6,34],"376":[5,6,54],"377":[5,3,81],"378":[7,1,1],"379":[2,7,56],"380":[4,7,1],"381":[4,10,103],"382":[2,10,43],"383":[2,10,63],"384":[2,1,57],"385":[6,1,76],"386":[3,6,27],"387":[6,8,41],"388":[6,8,52],"389":[3,1,116],"390":[3,1,50],"391":[3,1,22]},"averageFieldLength":[3.8265306122448983,7.071428571428569,34.178571428571416],"storedFields":{"0":{"title":"📢 Events","titles":[]},"1":{"title":"🔄 i18n:register","titles":["📢 Events"]},"2":{"title":"📝 Event Details","titles":["📢 Events","🔄 i18n:register"]},"3":{"title":"💡 Example Usage","titles":["📢 Events","🔄 i18n:register"]},"4":{"title":"🛠️ Explanation","titles":["📢 Events","🔄 i18n:register"]},"5":{"title":"🔗 Key Benefits","titles":["📢 Events","🔄 i18n:register"]},"6":{"title":"🛠️ Modifying Translations with Plugins","titles":["📢 Events"]},"7":{"title":"Registering the Plugin","titles":["📢 Events","🛠️ Modifying Translations with Plugins"]},"8":{"title":"Implementing the Plugin","titles":["📢 Events","🛠️ Modifying Translations with Plugins"]},"9":{"title":"📝 Detailed Explanation","titles":["📢 Events","🛠️ Modifying Translations with Plugins"]},"10":{"title":"🔗 Benefits of Using Plugins for Translation Modifications","titles":["📢 Events","🛠️ Modifying Translations with Plugins"]},"11":{"title":"🛠️ Methods","titles":[]},"12":{"title":"🌍 $getLocale","titles":["🛠️ Methods"]},"13":{"title":"🌍 $getLocaleName","titles":["🛠️ Methods"]},"14":{"title":"🌍 $getLocales","titles":["🛠️ Methods"]},"15":{"title":"🔍 $getRouteName","titles":["🛠️ Methods"]},"16":{"title":"🔍 $t","titles":["🛠️ Methods"]},"17":{"title":"🔍 $ts","titles":["🛠️ Methods"]},"18":{"title":"🔢 $tc","titles":["🛠️ Methods"]},"19":{"title":"🔢 $tn","titles":["🛠️ Methods"]},"20":{"title":"Use Cases:","titles":["🛠️ Methods","🔢 $tn"]},"21":{"title":"📅 $td","titles":["🛠️ Methods"]},"22":{"title":"Use Cases:","titles":["🛠️ Methods","📅 $td"]},"23":{"title":"🔄 $switchLocaleRoute","titles":["🛠️ Methods"]},"24":{"title":"🔄 $switchLocalePath","titles":["🛠️ Methods"]},"25":{"title":"🔄 $switchLocale","titles":["🛠️ Methods"]},"26":{"title":"🔄 $switchRoute","titles":["🛠️ Methods"]},"27":{"title":"🔄 $setI18nRouteParams","titles":["🛠️ Methods"]},"28":{"title":"🌐 $localeRoute","titles":["🛠️ Methods"]},"29":{"title":"🔄 $localePath","titles":["🛠️ Methods"]},"30":{"title":"🗂️ $mergeTranslations","titles":["🛠️ Methods"]},"31":{"title":"🚦 $defineI18nRoute","titles":["🛠️ Methods"]},"32":{"title":"Use Cases:","titles":["🛠️ Methods","🚦 $defineI18nRoute"]},"33":{"title":"Example 1: Controlling Access Based on Locales","titles":["🛠️ Methods","🚦 $defineI18nRoute"]},"34":{"title":"Example 2: Providing Translations for Locales","titles":["🛠️ Methods","🚦 $defineI18nRoute"]},"35":{"title":"📝 Explanation:","titles":["🛠️ Methods","🚦 $defineI18nRoute"]},"36":{"title":"💻 Example Usage in a Component","titles":["🛠️ Methods"]},"37":{"title":"🛠️ useNuxtApp","titles":["🛠️ Methods"]},"38":{"title":"🧩 useI18n Composable","titles":["🛠️ Methods"]},"39":{"title":"🌍 <i18n-link> Component","titles":[]},"40":{"title":"⚙️ Props","titles":["🌍 <i18n-link> Component"]},"41":{"title":"to","titles":["🌍 <i18n-link> Component","⚙️ Props"]},"42":{"title":"activeStyle","titles":["🌍 <i18n-link> Component","⚙️ Props"]},"43":{"title":"🛠️ Example Usages","titles":["🌍 <i18n-link> Component"]},"44":{"title":"Basic Usage","titles":["🌍 <i18n-link> Component","🛠️ Example Usages"]},"45":{"title":"Active Link Styling with Inline Styles","titles":["🌍 <i18n-link> Component","🛠️ Example Usages"]},"46":{"title":"External Links Handling","titles":["🌍 <i18n-link> Component","🛠️ Example Usages"]},"47":{"title":"🎨 Styles","titles":["🌍 <i18n-link> Component"]},"48":{"title":"Default Active Styles","titles":["🌍 <i18n-link> Component","🎨 Styles"]},"49":{"title":"Custom Active Styles","titles":["🌍 <i18n-link> Component","🎨 Styles"]},"50":{"title":"🚀 Additional Features","titles":["🌍 <i18n-link> Component"]},"51":{"title":"Slot for Custom Content","titles":["🌍 <i18n-link> Component","🚀 Additional Features"]},"52":{"title":"Accessibility Enhancements","titles":["🌍 <i18n-link> Component","🚀 Additional Features"]},"53":{"title":"🌍 <i18n-switcher> Component","titles":[]},"54":{"title":"⚙️ Props","titles":["🌍 <i18n-switcher> Component"]},"55":{"title":"customLabels","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"56":{"title":"customWrapperStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"57":{"title":"customButtonStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"58":{"title":"customDropdownStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"59":{"title":"customItemStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"60":{"title":"customLinkStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"61":{"title":"customActiveLinkStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"62":{"title":"customDisabledLinkStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"63":{"title":"customIconStyle","titles":["🌍 <i18n-switcher> Component","⚙️ Props"]},"64":{"title":"🛠️ Example Usages","titles":["🌍 <i18n-switcher> Component"]},"65":{"title":"Basic Usage","titles":["🌍 <i18n-switcher> Component","🛠️ Example Usages"]},"66":{"title":"Custom Labels and Inline Styles","titles":["🌍 <i18n-switcher> Component","🛠️ Example Usages"]},"67":{"title":"🎨 Styles Overview","titles":["🌍 <i18n-switcher> Component"]},"68":{"title":"🌍 <i18n-t> Component","titles":[]},"69":{"title":"⚙️ Props","titles":["🌍 <i18n-t> Component"]},"70":{"title":"keypath","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"71":{"title":"plural","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"72":{"title":"tag","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"73":{"title":"params","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"74":{"title":"defaultValue","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"75":{"title":"html","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"76":{"title":"hideIfEmpty","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"77":{"title":"customPluralRule","titles":["🌍 <i18n-t> Component","⚙️ Props"]},"78":{"title":"🛠️ Example Usages","titles":["🌍 <i18n-t> Component"]},"79":{"title":"Basic Usage","titles":["🌍 <i18n-t> Component","🛠️ Example Usages"]},"80":{"title":"Using Slots for Dynamic Content","titles":["🌍 <i18n-t> Component","🛠️ Example Usages"]},"81":{"title":"Pluralization","titles":["🌍 <i18n-t> Component","🛠️ Example Usages"]},"82":{"title":"🚀 Additional Features","titles":["🌍 <i18n-t> Component"]},"83":{"title":"Default Slot","titles":["🌍 <i18n-t> Component","🚀 Additional Features"]},"84":{"title":"Conditional Rendering","titles":["🌍 <i18n-t> Component","🚀 Additional Features"]},"85":{"title":"Custom Pluralization Rule","titles":["🌍 <i18n-t> Component","🚀 Additional Features"]},"86":{"title":"Advanced Example with Slots","titles":["🌍 <i18n-t> Component","🚀 Additional Features"]},"87":{"title":"🛠️ useI18n Composable","titles":[]},"88":{"title":"⚙️ Return Values","titles":["🛠️ useI18n Composable"]},"89":{"title":"$getLocale","titles":["🛠️ useI18n Composable","⚙️ Return Values"]},"90":{"title":"🌍 $getLocaleName","titles":["🛠️ useI18n Composable"]},"91":{"title":"$getLocales","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"92":{"title":"$t","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"93":{"title":"$tc","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"94":{"title":"$has","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"95":{"title":"$mergeTranslations","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"96":{"title":"$switchLocale","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"97":{"title":"$localeRoute","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"98":{"title":"$loadPageTranslations","titles":["🛠️ useI18n Composable","🌍 $getLocaleName"]},"99":{"title":"🛠️ Example Usages","titles":["🛠️ useI18n Composable"]},"100":{"title":"Basic Locale Retrieval","titles":["🛠️ useI18n Composable","🛠️ Example Usages"]},"101":{"title":"Translation with Parameters","titles":["🛠️ useI18n Composable","🛠️ Example Usages"]},"102":{"title":"Switching Locales","titles":["🛠️ useI18n Composable","🛠️ Example Usages"]},"103":{"title":"Generating a Localized Route","titles":["🛠️ useI18n Composable","🛠️ Example Usages"]},"104":{"title":"Loading Page-Specific Translations","titles":["🛠️ useI18n Composable","🛠️ Example Usages"]},"105":{"title":"🌍 useLocaleHead Composable","titles":[]},"106":{"title":"⚙️ Options","titles":["🌍 useLocaleHead Composable"]},"107":{"title":"addDirAttribute","titles":["🌍 useLocaleHead Composable","⚙️ Options"]},"108":{"title":"identifierAttribute","titles":["🌍 useLocaleHead Composable","⚙️ Options"]},"109":{"title":"addSeoAttributes","titles":["🌍 useLocaleHead Composable","⚙️ Options"]},"110":{"title":"baseUrl","titles":["🌍 useLocaleHead Composable","⚙️ Options"]},"111":{"title":"🛠️ Return Values","titles":["🌍 useLocaleHead Composable"]},"112":{"title":"htmlAttrs","titles":["🌍 useLocaleHead Composable","🛠️ Return Values"]},"113":{"title":"meta","titles":["🌍 useLocaleHead Composable","🛠️ Return Values"]},"114":{"title":"link","titles":["🌍 useLocaleHead Composable","🛠️ Return Values"]},"115":{"title":"🛠️ Example Usages","titles":["🌍 useLocaleHead Composable"]},"116":{"title":"Basic Usage","titles":["🌍 useLocaleHead Composable","🛠️ Example Usages"]},"117":{"title":"Customize Identifier Attribute","titles":["🌍 useLocaleHead Composable","🛠️ Example Usages"]},"118":{"title":"Disable SEO Attributes","titles":["🌍 useLocaleHead Composable","🛠️ Example Usages"]},"119":{"title":"Specify a Base URL","titles":["🌍 useLocaleHead Composable","🛠️ Example Usages"]},"120":{"title":"🚀 Additional Features","titles":["🌍 useLocaleHead Composable"]},"121":{"title":"SEO Meta and Link Tags","titles":["🌍 useLocaleHead Composable","🚀 Additional Features"]},"122":{"title":"Dynamic Locale and Direction","titles":["🌍 useLocaleHead Composable","🚀 Additional Features"]},"123":{"title":"Handling Localized Routes","titles":["🌍 useLocaleHead Composable","🚀 Additional Features"]},"124":{"title":"🛠️ Example Usage","titles":["🌍 useLocaleHead Composable"]},"125":{"title":"Explanation of the Code","titles":["🌍 useLocaleHead Composable","🛠️ Example Usage"]},"126":{"title":"📝 Notes","titles":["🌍 useLocaleHead Composable","🛠️ Example Usage"]},"127":{"title":"📚 Nuxt I18n Micro Examples and Usage","titles":[]},"128":{"title":"🛠️ Basic Setup","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"129":{"title":"🌍 Locale Switching","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"130":{"title":"Switching Locales Programmatically","titles":["📚 Nuxt I18n Micro Examples and Usage","🌍 Locale Switching"]},"131":{"title":"Example JSON for Locale Switching","titles":["📚 Nuxt I18n Micro Examples and Usage","🌍 Locale Switching"]},"132":{"title":"Using <i18n-switcher> Component","titles":["📚 Nuxt I18n Micro Examples and Usage","🌍 Locale Switching"]},"133":{"title":"🌐 Using <i18n-link> for Localized Navigation","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"134":{"title":"Example JSON for Navigation Links","titles":["📚 Nuxt I18n Micro Examples and Usage","🌐 Using <i18n-link> for Localized Navigation"]},"135":{"title":"Example with Active Link Styling","titles":["📚 Nuxt I18n Micro Examples and Usage","🌐 Using <i18n-link> for Localized Navigation"]},"136":{"title":"Example JSON for Active Link Styling","titles":["📚 Nuxt I18n Micro Examples and Usage","🌐 Using <i18n-link> for Localized Navigation"]},"137":{"title":"📝 Rendering Dynamic Keys from Translation Files","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"138":{"title":"Example: Rendering Dynamic Keys","titles":["📚 Nuxt I18n Micro Examples and Usage","📝 Rendering Dynamic Keys from Translation Files"]},"139":{"title":"Example Translation File (en.json)","titles":["📚 Nuxt I18n Micro Examples and Usage","📝 Rendering Dynamic Keys from Translation Files"]},"140":{"title":"Example: Rendering Dynamic Keys from an Object","titles":["📚 Nuxt I18n Micro Examples and Usage","📝 Rendering Dynamic Keys from Translation Files"]},"141":{"title":"Example Translation File (en.json)","titles":["📚 Nuxt I18n Micro Examples and Usage","📝 Rendering Dynamic Keys from Translation Files"]},"142":{"title":"🌟 Using <i18n-t> for Translations with Slots and Interpolation","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"143":{"title":"Example JSON for <i18n-t>","titles":["📚 Nuxt I18n Micro Examples and Usage","🌟 Using <i18n-t> for Translations with Slots and Interpolation"]},"144":{"title":"With Interpolation","titles":["📚 Nuxt I18n Micro Examples and Usage","🌟 Using <i18n-t> for Translations with Slots and Interpolation"]},"145":{"title":"Example JSON for Interpolation","titles":["📚 Nuxt I18n Micro Examples and Usage","🌟 Using <i18n-t> for Translations with Slots and Interpolation"]},"146":{"title":"📝 Comprehensive Example with Nested Sections","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"147":{"title":"Example JSON for Nested Sections","titles":["📚 Nuxt I18n Micro Examples and Usage","📝 Comprehensive Example with Nested Sections"]},"148":{"title":"🌟 Using $tc for Pluralization","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"149":{"title":"Example: Using $tc for Pluralization","titles":["📚 Nuxt I18n Micro Examples and Usage","🌟 Using $tc for Pluralization"]},"150":{"title":"Example JSON for Pluralization","titles":["📚 Nuxt I18n Micro Examples and Usage","🌟 Using $tc for Pluralization"]},"151":{"title":"Explanation","titles":["📚 Nuxt I18n Micro Examples and Usage","🌟 Using $tc for Pluralization"]},"152":{"title":"Additional Example with More Complex Pluralization","titles":["📚 Nuxt I18n Micro Examples and Usage","🌟 Using $tc for Pluralization"]},"153":{"title":"🌐 Using $tn for Number Formatting","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"154":{"title":"Example: Using $tn for Number Formatting","titles":["📚 Nuxt I18n Micro Examples and Usage","🌐 Using $tn for Number Formatting"]},"155":{"title":"Example JSON for Number Formatting (No JSON needed for number formatting directly)","titles":["📚 Nuxt I18n Micro Examples and Usage","🌐 Using $tn for Number Formatting"]},"156":{"title":"🗓️ Using $td for Date and Time Formatting","titles":["📚 Nuxt I18n Micro Examples and Usage"]},"157":{"title":"Example: Using $td for Date and Time Formatting","titles":["📚 Nuxt I18n Micro Examples and Usage","🗓️ Using $td for Date and Time Formatting"]},"158":{"title":"🌐 nuxt-i18n-micro-cli Guide","titles":[]},"159":{"title":"📖 Introduction","titles":["🌐 nuxt-i18n-micro-cli Guide"]},"160":{"title":"🔧 Installation and Setup","titles":["🌐 nuxt-i18n-micro-cli Guide"]},"161":{"title":"📦 Installing nuxt-i18n-micro-cli","titles":["🌐 nuxt-i18n-micro-cli Guide","🔧 Installation and Setup"]},"162":{"title":"🛠 Initializing in Your Project","titles":["🌐 nuxt-i18n-micro-cli Guide","🔧 Installation and Setup"]},"163":{"title":"📄 Common Arguments","titles":["🌐 nuxt-i18n-micro-cli Guide","🔧 Installation and Setup"]},"164":{"title":"📋 Commands","titles":["🌐 nuxt-i18n-micro-cli Guide"]},"165":{"title":"📊 stats Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"166":{"title":"🌍 translate Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"167":{"title":"🌐 Supported Translation Services","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands","🌍 translate Command"]},"168":{"title":"⚙️ Service Configuration","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands","🌍 translate Command"]},"169":{"title":"🛠️ extract Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"170":{"title":"🔄 sync Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"171":{"title":"✅ validate Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"172":{"title":"🧹 clean Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"173":{"title":"📤 import Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"174":{"title":"📥 export Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"175":{"title":"🗂️ export-csv Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"176":{"title":"📑 import-csv Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"177":{"title":"🧾 diff Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"178":{"title":"🔍 check-duplicates Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"179":{"title":"🔄 replace-values Command","titles":["🌐 nuxt-i18n-micro-cli Guide","📋 Commands"]},"180":{"title":"🛠 Examples","titles":["🌐 nuxt-i18n-micro-cli Guide"]},"181":{"title":"⚙️ Configuration Guide","titles":["🌐 nuxt-i18n-micro-cli Guide"]},"182":{"title":"🔑 nuxt.config.js Example","titles":["🌐 nuxt-i18n-micro-cli Guide","⚙️ Configuration Guide"]},"183":{"title":"📝 Best Practices","titles":["🌐 nuxt-i18n-micro-cli Guide"]},"184":{"title":"🔑 Consistent Key Naming","titles":["🌐 nuxt-i18n-micro-cli Guide","📝 Best Practices"]},"185":{"title":"🧹 Regular Maintenance","titles":["🌐 nuxt-i18n-micro-cli Guide","📝 Best Practices"]},"186":{"title":"🛠 Automate Translation Workflow","titles":["🌐 nuxt-i18n-micro-cli Guide","📝 Best Practices"]},"187":{"title":"🛡️ Secure API Keys","titles":["🌐 nuxt-i18n-micro-cli Guide","📝 Best Practices"]},"188":{"title":"📞 Support and Contributions","titles":["🌐 nuxt-i18n-micro-cli Guide"]},"189":{"title":"🤝 Contribution Guide","titles":[]},"190":{"title":"📖 Introduction","titles":["🤝 Contribution Guide"]},"191":{"title":"🚀 Getting Started","titles":["🤝 Contribution Guide"]},"192":{"title":"1. 📚 Familiarize Yourself with the Project","titles":["🤝 Contribution Guide","🚀 Getting Started"]},"193":{"title":"2. 🍴 Fork the Repository","titles":["🤝 Contribution Guide","🚀 Getting Started"]},"194":{"title":"3. 📥 Clone Your Fork","titles":["🤝 Contribution Guide","🚀 Getting Started"]},"195":{"title":"4. 🌱 Create a Branch","titles":["🤝 Contribution Guide","🚀 Getting Started"]},"196":{"title":"🛠️ Local Development Setup","titles":[]},"197":{"title":"🛠 Prerequisites","titles":["🛠️ Local Development Setup"]},"198":{"title":"🚀 Getting Started","titles":["🛠️ Local Development Setup"]},"199":{"title":"1. 📥 Clone the Repository","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"200":{"title":"2. 📦 Install Dependencies","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"201":{"title":"3. 🖥️ Run the Development Server","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"202":{"title":"4. 🏗️ Building the Module","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"203":{"title":"5. 🧹 Linting the Code","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"204":{"title":"6. ✅ Running Tests","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"205":{"title":"7. 🔍 Type Checking","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"206":{"title":"8. 📚 Building and Previewing the Documentation","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"207":{"title":"9. 🎮 Running the Playground","titles":["🛠️ Local Development Setup","🚀 Getting Started"]},"208":{"title":"🔧 Summary of Common Scripts","titles":["🛠️ Local Development Setup"]},"209":{"title":"🚧 Making Changes","titles":[]},"210":{"title":"1. 💻 Code","titles":["🚧 Making Changes"]},"211":{"title":"2. 🧹 Run Linting","titles":["🚧 Making Changes"]},"212":{"title":"3. 🧪 Test Your Changes","titles":["🚧 Making Changes"]},"213":{"title":"4. 📝 Commit Your Changes","titles":["🚧 Making Changes"]},"214":{"title":"✅ Commit Message Format","titles":["🚧 Making Changes","4. 📝 Commit Your Changes"]},"215":{"title":"📋 Examples:","titles":["🚧 Making Changes","4. 📝 Commit Your Changes"]},"216":{"title":"🛠️ Commit Types:","titles":["🚧 Making Changes","4. 📝 Commit Your Changes"]},"217":{"title":"5. 🚀 Push to GitHub","titles":["🚧 Making Changes"]},"218":{"title":"6. 🔄 Create a Pull Request","titles":["🚧 Making Changes"]},"219":{"title":"7. 🕵️‍♂️ Await Feedback","titles":["🚧 Making Changes"]},"220":{"title":"💡 Contribution Tips","titles":["🚧 Making Changes"]},"221":{"title":"🌐 Crowdin Integration Guide","titles":[]},"222":{"title":"📖 Introduction","titles":["🌐 Crowdin Integration Guide"]},"223":{"title":"🔧 Installation and Setup","titles":["🌐 Crowdin Integration Guide"]},"224":{"title":"📦 Installing Crowdin CLI","titles":["🌐 Crowdin Integration Guide","🔧 Installation and Setup"]},"225":{"title":"🛠 Initializing Crowdin in Your Project","titles":["🌐 Crowdin Integration Guide","🔧 Installation and Setup"]},"226":{"title":"🗂️ Configuration Guide","titles":["🌐 Crowdin Integration Guide"]},"227":{"title":"📄 Crowdin Configuration File (crowdin.yml)","titles":["🌐 Crowdin Integration Guide","🗂️ Configuration Guide"]},"228":{"title":"📂 Key Configuration Parameters","titles":["🌐 Crowdin Integration Guide","🗂️ Configuration Guide"]},"229":{"title":"📂 Files Configuration","titles":["🌐 Crowdin Integration Guide","🗂️ Configuration Guide"]},"230":{"title":"⬆️ Uploading Source Files to Crowdin","titles":["🌐 Crowdin Integration Guide"]},"231":{"title":"⬇️ Downloading Translations from Crowdin","titles":["🌐 Crowdin Integration Guide"]},"232":{"title":"⚙️ Best Practices","titles":["🌐 Crowdin Integration Guide"]},"233":{"title":"🔑 Consistent Key Naming","titles":["🌐 Crowdin Integration Guide","⚙️ Best Practices"]},"234":{"title":"🧹 Regular Maintenance","titles":["🌐 Crowdin Integration Guide","⚙️ Best Practices"]},"235":{"title":"🛠 Automate Uploads and Downloads","titles":["🌐 Crowdin Integration Guide","⚙️ Best Practices"]},"236":{"title":"🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro","titles":[]},"237":{"title":"📖 Introduction to localeRoutes","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro"]},"238":{"title":"🚀 Primary Use Case of localeRoutes","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro"]},"239":{"title":"📄 Example: Defining localeRoutes in $defineI18nRoute","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro","🚀 Primary Use Case of localeRoutes"]},"240":{"title":"🔄 How localeRoutes Work","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro","🚀 Primary Use Case of localeRoutes"]},"241":{"title":"🌱 Use Cases for localeRoutes","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro"]},"242":{"title":"📄 Example: Using localeRoutes in a Page","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro","🌱 Use Cases for localeRoutes"]},"243":{"title":"🛠️ Using localeRoutes in Different Contexts","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro","🌱 Use Cases for localeRoutes"]},"244":{"title":"📝 Best Practices for Using localeRoutes","titles":["🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro"]},"245":{"title":"FAQ: Common Issues & Solutions","titles":[]},"246":{"title":"❓ What if a route doesn\'t load?","titles":["FAQ: Common Issues & Solutions"]},"247":{"title":"❓ Why is the assets/_locales/ folder added to the server folder?","titles":["FAQ: Common Issues & Solutions"]},"248":{"title":"❓ Is Nuxt I18n Micro inspired by vue-i18n? What about features like modifiers?","titles":["FAQ: Common Issues & Solutions"]},"249":{"title":"❓ Can I use NuxtLink or i18nLink directly in translation strings?","titles":["FAQ: Common Issues & Solutions"]},"250":{"title":"📂 Folder Structure Guide","titles":[]},"251":{"title":"📖 Introduction","titles":["📂 Folder Structure Guide"]},"252":{"title":"🗂️ Recommended Folder Structure","titles":["📂 Folder Structure Guide"]},"253":{"title":"🔧 Basic Structure","titles":["📂 Folder Structure Guide","🗂️ Recommended Folder Structure"]},"254":{"title":"📄 Explanation of Structure","titles":["📂 Folder Structure Guide","🗂️ Recommended Folder Structure"]},"255":{"title":"1. 🌍 Global Translation Files","titles":["📂 Folder Structure Guide","🗂️ Recommended Folder Structure","📄 Explanation of Structure"]},"256":{"title":"2. 📄 Page-Specific Translation Files","titles":["📂 Folder Structure Guide","🗂️ Recommended Folder Structure","📄 Explanation of Structure"]},"257":{"title":"📂 Handling Dynamic Routes and Nested Paths","titles":["📂 Folder Structure Guide","🗂️ Recommended Folder Structure"]},"258":{"title":"Dynamic Route Translation Folder Structure","titles":["📂 Folder Structure Guide","🗂️ Recommended Folder Structure","📂 Handling Dynamic Routes and Nested Paths"]},"259":{"title":"🛠 Customizing the Directory Structure","titles":["📂 Folder Structure Guide","🗂️ Recommended Folder Structure"]},"260":{"title":"⚙️ How Translations are Loaded","titles":["📂 Folder Structure Guide"]},"261":{"title":"🌍 Dynamic Locale Routes","titles":["📂 Folder Structure Guide","⚙️ How Translations are Loaded"]},"262":{"title":"💾 Caching and Pre-rendering","titles":["📂 Folder Structure Guide","⚙️ How Translations are Loaded"]},"263":{"title":"📝 Best Practices","titles":["📂 Folder Structure Guide"]},"264":{"title":"📂 Use Page-Specific Files Wisely","titles":["📂 Folder Structure Guide","📝 Best Practices"]},"265":{"title":"🔑 Keep Translation Keys Consistent","titles":["📂 Folder Structure Guide","📝 Best Practices"]},"266":{"title":"🗂️ Organize Translations by Context","titles":["📂 Folder Structure Guide","📝 Best Practices"]},"267":{"title":"🧹 Regularly Clean Up Unused Translations","titles":["📂 Folder Structure Guide","📝 Best Practices"]},"268":{"title":"🌐 Getting Started with Nuxt I18n Micro","titles":[]},"269":{"title":"📖 Overview","titles":["🌐 Getting Started with Nuxt I18n Micro"]},"270":{"title":"🤔 Why Choose Nuxt I18n Micro?","titles":["🌐 Getting Started with Nuxt I18n Micro"]},"271":{"title":"🛠 Installation","titles":["🌐 Getting Started with Nuxt I18n Micro"]},"272":{"title":"⚙️ Basic Setup","titles":["🌐 Getting Started with Nuxt I18n Micro"]},"273":{"title":"📂 Folder Structure","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Basic Setup"]},"274":{"title":"⚙️ Module Configuration Options","titles":["🌐 Getting Started with Nuxt I18n Micro"]},"275":{"title":"🌍 locales","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"276":{"title":"🌐 defaultLocale","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"277":{"title":"🗂 translationDir","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"278":{"title":"🔍 meta","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"279":{"title":"🐛 debug","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"280":{"title":"🐛 types","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"281":{"title":"🔗 metaBaseUrl","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"282":{"title":"🌍 autoDetectLanguage","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"283":{"title":"🔍 autoDetectPath","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"284":{"title":"🔢 plural","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"285":{"title":"🚦 includeDefaultLocaleRoute","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"286":{"title":"🚦 customRegexMatcher","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"287":{"title":"🔗 routesLocaleLinks","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"288":{"title":"🧩 define","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"289":{"title":"🔄 disablePageLocales","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"290":{"title":"📂 Folder Structure with disablePageLocales: true","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"291":{"title":"👀 disableWatcher","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"292":{"title":"🔗 apiBaseUrl","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"293":{"title":"🍪 localeCookie","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"294":{"title":"🌐 fallbackLocale","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"295":{"title":"🌐 globalLocaleRoutes","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"296":{"title":"Usage:","titles":["🌐 Getting Started with Nuxt I18n Micro","⚙️ Module Configuration Options"]},"297":{"title":"🔄 Caching Mechanism","titles":[]},"298":{"title":"🗂️ Layers in Nuxt I18n Micro","titles":[]},"299":{"title":"📖 Introduction to Layers","titles":["🗂️ Layers in Nuxt I18n Micro"]},"300":{"title":"🛠️ Primary Configuration Layer","titles":["🗂️ Layers in Nuxt I18n Micro"]},"301":{"title":"📄 Example: Defining the Primary Configuration Layer","titles":["🗂️ Layers in Nuxt I18n Micro","🛠️ Primary Configuration Layer"]},"302":{"title":"🌱 Child Layers","titles":["🗂️ Layers in Nuxt I18n Micro"]},"303":{"title":"📄 Example: Extending the Primary Layer in a Child Layer","titles":["🗂️ Layers in Nuxt I18n Micro","🌱 Child Layers"]},"304":{"title":"🌐 Using Layers in a Modular Application","titles":["🗂️ Layers in Nuxt I18n Micro","🌱 Child Layers"]},"305":{"title":"📄 Example: Layered Configuration in a Modular Application","titles":["🗂️ Layers in Nuxt I18n Micro","🌱 Child Layers"]},"306":{"title":"Primary Layer (Global Configuration):","titles":["🗂️ Layers in Nuxt I18n Micro","🌱 Child Layers","📄 Example: Layered Configuration in a Modular Application"]},"307":{"title":"Child Layer for Admin Panel:","titles":["🗂️ Layers in Nuxt I18n Micro","🌱 Child Layers","📄 Example: Layered Configuration in a Modular Application"]},"308":{"title":"Child Layer for Customer Support Portal:","titles":["🗂️ Layers in Nuxt I18n Micro","🌱 Child Layers","📄 Example: Layered Configuration in a Modular Application"]},"309":{"title":"📝 Best Practices for Using Layers","titles":["🗂️ Layers in Nuxt I18n Micro"]},"310":{"title":"🔄 Migration from nuxt-i18n to Nuxt I18n Micro","titles":[]},"311":{"title":"📖 Introduction","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro"]},"312":{"title":"🚀 Why Migrate?","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro"]},"313":{"title":"🔍 Key Differences","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro"]},"314":{"title":"🛠️ Step-by-Step Migration","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro"]},"315":{"title":"1. 🛠️ Install Nuxt I18n Micro","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛠️ Step-by-Step Migration"]},"316":{"title":"2. 🔄 Update Configuration","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛠️ Step-by-Step Migration"]},"317":{"title":"3. 🗂️ Reorganize Translation Files","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛠️ Step-by-Step Migration"]},"318":{"title":"4. 🔗 Replace <nuxt-link> with <NuxtLink>","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛠️ Step-by-Step Migration"]},"319":{"title":"5. 🛠️ Handle SEO Configurations","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛠️ Step-by-Step Migration"]},"320":{"title":"6. 🧪 Test Your Application","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛠️ Step-by-Step Migration"]},"321":{"title":"🛡️ Common Issues and Troubleshooting","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro"]},"322":{"title":"❌ Translation Files Not Loading","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛡️ Common Issues and Troubleshooting"]},"323":{"title":"⚠️ Route Not Found Errors","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛡️ Common Issues and Troubleshooting"]},"324":{"title":"🏷️ Missing SEO Tags","titles":["🔄 Migration from nuxt-i18n to Nuxt I18n Micro","🛡️ Common Issues and Troubleshooting"]},"325":{"title":"🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","titles":[]},"326":{"title":"📝 Introduction","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers"]},"327":{"title":"🎯 Objective","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers"]},"328":{"title":"🛠 Steps to Implement Multi-Domain Locales","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers"]},"329":{"title":"1. Create the Base Layer","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales"]},"330":{"title":"Base Layer Configuration","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales","1. Create the Base Layer"]},"331":{"title":"2. Create Domain-Specific Child Layers","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales"]},"332":{"title":"Example: Configuration for the French Domain","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales","2. Create Domain-Specific Child Layers"]},"333":{"title":"Example: Configuration for the German Domain","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales","2. Create Domain-Specific Child Layers"]},"334":{"title":"3. Deploy the Application for Each Domain","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales"]},"335":{"title":"4. Set Up Multiple Projects for Different Locales","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales"]},"336":{"title":"5. Configure Routing Based on Domain","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales"]},"337":{"title":"6. Deploy and Verify","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","🛠 Steps to Implement Multi-Domain Locales"]},"338":{"title":"📝 Best Practices","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers"]},"339":{"title":"🎉 Conclusion","titles":["🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers"]},"340":{"title":"📖 Per-Component Translations in Nuxt I18n Micro","titles":[]},"341":{"title":"Overview","titles":["📖 Per-Component Translations in Nuxt I18n Micro"]},"342":{"title":"$defineI18nRoute Function","titles":["📖 Per-Component Translations in Nuxt I18n Micro"]},"343":{"title":"Method Signature","titles":["📖 Per-Component Translations in Nuxt I18n Micro","$defineI18nRoute Function"]},"344":{"title":"Parameters","titles":["📖 Per-Component Translations in Nuxt I18n Micro","$defineI18nRoute Function"]},"345":{"title":"Example Usage","titles":["📖 Per-Component Translations in Nuxt I18n Micro","$defineI18nRoute Function"]},"346":{"title":"Use Cases","titles":["📖 Per-Component Translations in Nuxt I18n Micro"]},"347":{"title":"Best Practices","titles":["📖 Per-Component Translations in Nuxt I18n Micro"]},"348":{"title":"Example: Vue Page with Per-Component Translations","titles":["📖 Per-Component Translations in Nuxt I18n Micro"]},"349":{"title":"Explanation","titles":["📖 Per-Component Translations in Nuxt I18n Micro"]},"350":{"title":"Summary","titles":["📖 Per-Component Translations in Nuxt I18n Micro"]},"351":{"title":"Performance Test Results","titles":[]},"352":{"title":"Project Information","titles":["Performance Test Results"]},"353":{"title":"Description:","titles":["Performance Test Results","Project Information"]},"354":{"title":"Important Note:","titles":["Performance Test Results","Project Information"]},"355":{"title":"Build Performance for ./test/fixtures/i18n-micro","titles":["Performance Test Results"]},"356":{"title":"Build Performance for ./test/fixtures/i18n","titles":["Performance Test Results"]},"357":{"title":"⏱️ Build Time and Resource Consumption","titles":["Performance Test Results","Build Performance for ./test/fixtures/i18n"]},"358":{"title":"Performance Comparison","titles":["Performance Test Results"]},"359":{"title":"Stress Test with Artillery for ./test/fixtures/i18n","titles":["Performance Test Results"]},"360":{"title":"Stress Test with Artillery for ./test/fixtures/i18n-micro","titles":["Performance Test Results"]},"361":{"title":"Comparison between i18n and i18n-micro","titles":["Performance Test Results"]},"362":{"title":"📊 Detailed Performance Analysis","titles":["Performance Test Results"]},"363":{"title":"🔍 Test Logic Explanation","titles":["Performance Test Results","📊 Detailed Performance Analysis"]},"364":{"title":"🛠 Why This Approach?","titles":["Performance Test Results","📊 Detailed Performance Analysis"]},"365":{"title":"🚀 Performance Guide","titles":[]},"366":{"title":"📖 Introduction","titles":["🚀 Performance Guide"]},"367":{"title":"🤔 Why Focus on Performance?","titles":["🚀 Performance Guide"]},"368":{"title":"📊 Performance Comparison","titles":["🚀 Performance Guide"]},"369":{"title":"⏱️ Build Time and Resource Consumption","titles":["🚀 Performance Guide","📊 Performance Comparison"]},"370":{"title":"🌐 Server Performance Under Load","titles":["🚀 Performance Guide","📊 Performance Comparison"]},"371":{"title":"🔍 Interpretation of Results","titles":["🚀 Performance Guide","📊 Performance Comparison"]},"372":{"title":"⚙️ Key Optimizations","titles":["🚀 Performance Guide"]},"373":{"title":"🛠️ Minimalist Design","titles":["🚀 Performance Guide","⚙️ Key Optimizations"]},"374":{"title":"🚦 Efficient Routing","titles":["🚀 Performance Guide","⚙️ Key Optimizations"]},"375":{"title":"📂 Streamlined Translation Loading","titles":["🚀 Performance Guide","⚙️ Key Optimizations"]},"376":{"title":"💾 Caching and Pre-rendering","titles":["🚀 Performance Guide","⚙️ Key Optimizations"]},"377":{"title":"📝 Tips for Maximizing Performance","titles":["🚀 Performance Guide"]},"378":{"title":"🌐 SEO Guide for Nuxt I18n Micro","titles":[]},"379":{"title":"📖 Introduction","titles":["🌐 SEO Guide for Nuxt I18n Micro"]},"380":{"title":"⚙️ Automatic SEO Handling","titles":["🌐 SEO Guide for Nuxt I18n Micro"]},"381":{"title":"🔑 Key SEO Features","titles":["🌐 SEO Guide for Nuxt I18n Micro","⚙️ Automatic SEO Handling"]},"382":{"title":"🛠️ Configuration","titles":["🌐 SEO Guide for Nuxt I18n Micro","⚙️ Automatic SEO Handling"]},"383":{"title":"🎯 Benefits","titles":["🌐 SEO Guide for Nuxt I18n Micro","⚙️ Automatic SEO Handling"]},"384":{"title":"✨ Introduction","titles":[]},"385":{"title":"📝 Why Nuxt I18n Micro?","titles":[]},"386":{"title":"🏁 Performance Comparison","titles":["📝 Why Nuxt I18n Micro?"]},"387":{"title":"⏱️ Build Time and Resource Consumption","titles":["📝 Why Nuxt I18n Micro?","🏁 Performance Comparison"]},"388":{"title":"🌐 Server Performance (10k Requests)","titles":["📝 Why Nuxt I18n Micro?","🏁 Performance Comparison"]},"389":{"title":"🔑 Key Features","titles":[]},"390":{"title":"⚙️ Quick Setup","titles":[]},"391":{"title":"🗂 Folder Structure","titles":[]}},"dirtCount":0,"index":[["✨",{"0":{"384":1}}],["known",{"2":{"385":1}}],["kb",{"2":{"369":1,"387":1}}],["kept",{"2":{"187":1}}],["keeps",{"2":{"264":1,"349":1}}],["keep",{"0":{"265":1},"2":{"179":1,"185":1,"220":1,"234":1,"244":1,"267":1,"309":2,"338":2,"347":2,"377":1}}],["keeping",{"2":{"10":1,"179":1}}],["key3",{"2":{"139":2}}],["key1",{"2":{"139":2}}],["keys",{"0":{"137":1,"138":1,"140":1,"187":1,"265":1},"1":{"138":1,"139":1,"140":1,"141":1},"2":{"127":1,"137":1,"138":1,"140":1,"159":1,"165":2,"166":2,"168":1,"169":1,"170":1,"171":1,"172":1,"175":1,"177":1,"178":2,"180":3,"184":1,"185":1,"187":2,"233":1,"234":1,"265":1,"267":1}}],["keypath=",{"2":{"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"79":1,"80":2,"81":1,"83":1,"84":1,"85":1,"86":1,"142":1,"144":1,"248":2,"249":2}}],["keypath",{"0":{"70":1}}],["key=",{"2":{"36":1,"130":1,"138":1,"140":1,"146":1}}],["key2",{"2":{"36":5,"139":2}}],["key",{"0":{"5":1,"184":1,"228":1,"233":1,"313":1,"372":1,"381":1,"389":1},"1":{"373":1,"374":1,"375":1,"376":1},"2":{"2":1,"16":5,"17":5,"18":4,"35":2,"70":1,"74":1,"77":2,"85":1,"88":1,"92":3,"93":3,"94":2,"138":6,"139":3,"140":4,"149":1,"166":3,"168":2,"178":1,"179":2,"180":2,"187":1,"258":3,"266":2,"270":1,"284":5,"295":1,"313":1,"344":2,"363":1,"385":1}}],["⏱️",{"0":{"357":1,"369":1,"387":1}}],["⚠️",{"0":{"323":1}}],["❌",{"0":{"322":1}}],["⚡",{"2":{"312":1,"389":1}}],["z",{"2":{"286":2}}],["zero",{"2":{"151":1,"152":1}}],["©",{"2":{"255":1}}],["└──",{"2":{"253":3,"258":3,"273":3,"290":1,"317":3,"391":3}}],["│",{"2":{"253":14,"258":9,"273":14,"317":14,"391":14}}],["├──",{"2":{"253":9,"258":9,"273":9,"290":2,"317":9,"391":9}}],["❓",{"0":{"246":1,"247":1,"248":1,"249":1}}],["⬇️",{"0":{"231":1}}],["⬆️",{"0":{"230":1}}],["94",{"2":{"369":1,"387":1}}],["92",{"2":{"369":1,"387":1}}],["96",{"2":{"369":1,"387":1}}],["9610",{"2":{"356":1,"357":1,"358":1}}],["93",{"2":{"369":1,"387":1}}],["91",{"2":{"360":1}}],["90",{"2":{"359":1}}],["97",{"2":{"359":1}}],["95",{"2":{"359":1}}],["9",{"0":{"207":1}}],["655",{"2":{"369":1,"387":1}}],["68",{"2":{"360":1}}],["69",{"2":{"359":1}}],["611",{"2":{"370":1,"388":1}}],["61",{"2":{"359":1,"370":1,"388":1}}],["63",{"2":{"356":1}}],["67",{"2":{"355":1}}],["60",{"2":{"355":2,"357":1,"358":1,"361":1,"363":2}}],["6",{"0":{"204":1,"218":1,"320":1,"337":1},"2":{"355":1,"357":1,"358":1,"363":2}}],["x26",{"2":{"200":6,"284":4}}],["x3c",{"2":{"36":22,"41":4,"42":2,"44":2,"45":2,"46":2,"49":2,"51":4,"52":2,"55":2,"56":2,"57":2,"58":2,"59":2,"60":2,"61":2,"62":2,"63":2,"65":3,"66":3,"70":1,"71":1,"72":1,"73":1,"74":2,"75":1,"76":2,"77":2,"79":1,"80":7,"81":1,"83":4,"84":2,"85":2,"86":6,"124":6,"130":12,"132":5,"133":10,"135":6,"138":12,"140":10,"142":10,"144":4,"146":64,"149":16,"154":14,"157":14,"194":1,"214":3,"242":16,"248":9,"249":9,"284":1,"318":7,"343":3,"348":10}}],["🧠",{"2":{"371":1}}],["🤔",{"0":{"270":1,"367":1}}],["🧼",{"2":{"220":1}}],["🧪",{"0":{"212":1,"320":1}}],["🤝",{"0":{"189":1},"1":{"190":1,"191":1,"192":1,"193":1,"194":1,"195":1}}],["🧾",{"0":{"177":1}}],["🧹",{"0":{"172":1,"185":1,"203":1,"211":1,"234":1,"267":1}}],["🧩",{"0":{"38":1,"288":1}}],["✅",{"0":{"171":1,"204":1,"214":1}}],["74",{"2":{"361":1}}],["72",{"2":{"359":1}}],["73",{"2":{"356":1,"358":1,"370":1,"388":1}}],["703",{"2":{"370":1,"388":1}}],["70",{"2":{"356":1,"360":1}}],["77",{"2":{"355":1,"357":1,"358":1}}],["7",{"0":{"205":1,"219":1},"2":{"154":1,"369":1,"387":1}}],["+1",{"2":{"147":1}}],["323",{"2":{"370":1,"388":1}}],["379",{"2":{"370":1,"388":1}}],["391",{"2":{"369":1,"387":1}}],["31s",{"2":{"369":1,"387":1}}],["31",{"2":{"369":1,"387":1}}],["311",{"2":{"360":1}}],["364",{"2":{"360":1}}],["3642",{"2":{"356":1}}],["344",{"2":{"360":1}}],["38",{"2":{"359":1}}],["384",{"2":{"356":1,"357":1,"358":1}}],["304",{"2":{"361":1}}],["3000",{"2":{"201":1,"207":1}}],["30",{"2":{"157":1,"361":1}}],["3",{"0":{"194":1,"201":1,"212":1,"317":1,"334":1},"2":{"93":3,"152":1,"166":1,"168":1,"179":1,"369":1,"387":1}}],["333",{"2":{"60":1,"66":1}}],["82",{"2":{"361":1}}],["8305",{"2":{"369":1,"387":1}}],["83",{"2":{"360":1}}],["8527",{"2":{"358":1}}],["81",{"2":{"358":1}}],["801",{"2":{"359":1}}],["80",{"2":{"356":1,"358":1,"360":1}}],["88",{"2":{"356":1,"357":1,"358":1}}],["84",{"2":{"355":1,"356":1}}],["8",{"0":{"206":1}}],["8px",{"2":{"58":1,"60":1,"66":2}}],["89",{"2":{"19":2,"154":2}}],["44",{"2":{"369":1,"387":1}}],["473",{"2":{"369":1,"387":1}}],["457",{"2":{"361":1}}],["4567",{"2":{"147":1}}],["48",{"2":{"360":1}}],["439",{"2":{"359":1}}],["490",{"2":{"370":1,"388":1}}],["49",{"2":{"359":1,"370":1,"388":1}}],["40",{"2":{"356":1,"357":1,"358":1,"359":1,"361":1}}],["4",{"0":{"195":1,"202":1,"213":1,"318":1,"335":1},"1":{"214":1,"215":1,"216":1},"2":{"361":1,"369":1,"373":1,"387":1,"389":1}}],["4px",{"2":{"57":1,"66":1}}],["42b983",{"2":{"49":1}}],["⚙️",{"0":{"40":1,"54":1,"69":1,"88":1,"106":1,"168":1,"181":1,"232":1,"260":1,"272":1,"274":1,"372":1,"380":1,"390":1},"1":{"41":1,"42":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"89":1,"107":1,"108":1,"109":1,"110":1,"182":1,"233":1,"234":1,"235":1,"261":1,"262":1,"273":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"373":1,"374":1,"375":1,"376":1,"381":1,"382":1,"383":1},"2":{"270":1,"309":1}}],[">visit",{"2":{"46":1}}],[">home",{"2":{"41":1,"318":3}}],[">about",{"2":{"41":1,"42":1,"44":1,"45":1,"49":1,"135":1}}],[">",{"2":{"36":2,"51":1,"52":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"65":1,"66":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"79":1,"80":3,"81":1,"83":2,"84":1,"85":1,"86":2,"130":1,"132":1,"133":2,"138":2,"140":1,"142":2,"144":1,"146":5,"149":4,"154":4,"157":4,"242":4,"248":3,"249":3,"284":3,"318":1,"348":1}}],["свидания",{"2":{"31":1,"345":1,"348":1}}],["до",{"2":{"31":1,"345":1,"348":1}}],["привет",{"2":{"31":1,"345":1,"348":1}}],["🏁",{"0":{"386":1},"1":{"387":1,"388":1},"2":{"376":1,"377":1}}],["🎉",{"0":{"339":1}}],["🎯",{"0":{"327":1,"383":1}}],["🏷️",{"0":{"324":1}}],["🍪",{"0":{"293":1}}],["🎮",{"0":{"207":1}}],["🏗️",{"0":{"202":1}}],["🌱",{"0":{"195":1,"241":1,"302":1},"1":{"242":1,"243":1,"303":1,"304":1,"305":1,"306":1,"307":1,"308":1}}],["🍴",{"0":{"193":1}}],["🌟",{"0":{"142":1,"148":1},"1":{"143":1,"144":1,"145":1,"149":1,"150":1,"151":1,"152":1}}],["🎨",{"0":{"47":1,"67":1},"1":{"48":1,"49":1}}],["🌐",{"0":{"28":1,"133":1,"153":1,"158":1,"167":1,"221":1,"268":1,"276":1,"294":1,"295":1,"304":1,"370":1,"378":1,"388":1},"1":{"134":1,"135":1,"136":1,"154":1,"155":1,"159":1,"160":1,"161":1,"162":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1,"228":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"235":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"379":1,"380":1,"381":1,"382":1,"383":1},"2":{"313":1,"381":1,"389":1}}],["🌍",{"0":{"12":1,"13":1,"14":1,"39":1,"53":1,"68":1,"90":1,"105":1,"129":1,"166":1,"255":1,"261":1,"275":1,"282":1,"325":1},"1":{"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"86":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"130":1,"131":1,"132":1,"167":1,"168":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1},"2":{"381":1}}],["quick",{"0":{"390":1}}],["quickly",{"2":{"376":1}}],["quality",{"2":{"208":1}}],["query",{"2":{"27":1}}],["quot",{"2":{"4":4,"46":2,"121":4,"125":4,"151":6,"152":4,"179":16,"193":2,"218":2,"283":2,"381":6}}],["yml",{"0":{"227":1},"2":{"227":2}}],["yandexcloud",{"2":{"167":1}}],["yandex",{"2":{"166":1,"167":3}}],["yet",{"2":{"389":1}}],["yes",{"2":{"41":1,"42":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"249":1}}],["year",{"2":{"21":1,"157":1}}],["you",{"2":{"1":1,"5":1,"7":1,"8":1,"10":3,"16":1,"17":1,"26":1,"32":1,"35":3,"42":1,"45":1,"47":1,"48":1,"51":1,"55":1,"56":1,"57":1,"60":1,"67":1,"68":1,"77":1,"105":1,"126":1,"127":1,"137":1,"141":1,"145":1,"150":1,"152":1,"159":1,"162":1,"165":1,"166":2,"168":1,"179":3,"181":1,"188":2,"190":2,"197":2,"199":1,"201":1,"203":1,"206":1,"207":2,"210":1,"212":1,"220":2,"223":1,"225":1,"230":1,"231":1,"235":1,"237":1,"238":1,"239":1,"244":1,"249":1,"251":1,"253":1,"256":1,"259":3,"262":1,"280":2,"286":2,"288":1,"289":1,"292":2,"295":4,"299":2,"300":1,"301":1,"302":1,"303":3,"304":2,"305":1,"309":1,"311":1,"313":1,"318":1,"326":1,"327":1,"331":1,"335":2,"339":2,"346":1,"377":2,"383":2,"390":1}}],["yourself",{"0":{"192":1},"2":{"192":1}}],["your",{"0":{"162":1,"194":1,"212":1,"213":1,"225":1,"320":1},"1":{"214":1,"215":1,"216":1},"2":{"1":2,"5":2,"6":1,"7":1,"10":1,"32":2,"53":2,"67":1,"70":1,"77":1,"87":1,"105":1,"110":1,"111":1,"122":1,"123":3,"126":2,"127":1,"137":1,"140":1,"147":1,"150":1,"152":1,"159":2,"161":1,"162":2,"165":2,"166":1,"168":1,"169":1,"178":1,"179":1,"180":2,"181":1,"182":1,"185":1,"186":1,"187":1,"188":2,"190":2,"193":1,"194":4,"195":2,"197":1,"199":1,"201":1,"203":1,"206":1,"207":1,"210":1,"211":2,"212":1,"217":3,"218":3,"219":3,"220":2,"222":2,"223":2,"225":2,"227":3,"228":2,"229":1,"230":3,"231":2,"234":1,"235":4,"237":1,"239":1,"249":1,"251":1,"255":1,"256":1,"259":1,"265":2,"266":1,"267":2,"270":1,"271":1,"272":1,"274":1,"275":1,"288":1,"299":3,"300":1,"301":1,"302":2,"303":1,"309":4,"311":1,"315":1,"316":1,"317":1,"319":1,"320":1,"322":3,"323":1,"324":1,"326":1,"329":1,"336":1,"339":1,"350":2,"367":1,"371":3,"374":1,"377":3,"379":3,"381":1,"382":1,"383":1,"390":3}}],["25",{"2":{"370":1,"388":1}}],["24",{"2":{"361":1}}],["2483",{"2":{"360":1}}],["220",{"2":{"369":1,"387":1}}],["22",{"2":{"360":1}}],["2994",{"2":{"359":1}}],["29",{"2":{"355":1,"357":1,"358":1}}],["20",{"2":{"370":1,"388":1}}],["2024",{"2":{"255":1}}],["2023",{"2":{"21":1,"157":1}}],["20px",{"2":{"63":1,"66":1}}],["2px",{"2":{"58":1,"66":1}}],["2",{"0":{"34":1,"193":1,"200":1,"211":1,"256":1,"316":1,"331":1},"1":{"332":1,"333":1},"2":{"152":1,"157":3,"179":1,"284":3,"389":1}}],["27",{"2":{"26":1,"358":1}}],["234",{"2":{"19":1,"154":1}}],["288",{"2":{"360":1}}],["281",{"2":{"359":1}}],["28",{"2":{"13":1,"15":1,"90":1,"355":1}}],["18",{"2":{"370":1,"388":1}}],["185",{"2":{"355":1,"357":1,"358":1}}],["1m",{"2":{"369":1,"387":1}}],["130",{"2":{"360":1}}],["198",{"2":{"358":1}}],["196",{"2":{"356":1}}],["14",{"2":{"361":1}}],["144",{"2":{"356":1}}],["146",{"2":{"355":1}}],["172",{"2":{"355":1}}],["155",{"2":{"359":1}}],["15",{"2":{"157":1}}],["123",{"2":{"147":2}}],["1234567",{"2":{"19":1,"154":1}}],["16px",{"2":{"60":1,"66":1}}],["1px",{"2":{"58":1,"66":1}}],["1",{"0":{"33":1,"192":1,"199":1,"210":1,"255":1,"315":1,"329":1},"1":{"330":1},"2":{"21":1,"27":6,"58":1,"66":1,"77":1,"85":1,"149":1,"151":1,"154":1,"157":1,"179":1,"284":4,"359":1,"361":2,"369":2,"373":1,"387":2,"389":1}}],["10k",{"0":{"388":1}}],["10mb",{"2":{"368":1,"386":1}}],["1082",{"2":{"355":1,"357":1,"358":1}}],["1000",{"2":{"166":1,"168":1}}],["10px",{"2":{"56":1,"66":1}}],["10",{"2":{"18":2,"36":1,"149":2,"151":2,"157":1,"359":1,"370":1}}],["599",{"2":{"370":1,"388":1}}],["592",{"2":{"359":1}}],["5s",{"2":{"369":1,"387":1}}],["54",{"2":{"369":1,"370":1,"387":1,"388":1}}],["50",{"2":{"361":1}}],["58",{"2":{"360":1}}],["511",{"2":{"355":1,"361":1}}],["56",{"2":{"154":1,"361":1}}],["567",{"2":{"19":1,"154":2}}],["555",{"2":{"147":1}}],["5px",{"2":{"59":2,"66":2}}],["5",{"0":{"203":1,"217":1,"319":1,"336":1},"2":{"16":2,"17":2,"36":1,"144":1,"166":1,"168":1,"373":1,"389":1}}],["|",{"2":{"13":1,"15":4,"16":8,"17":2,"18":1,"19":1,"21":5,"26":4,"27":3,"28":1,"29":1,"31":3,"41":1,"71":1,"73":2,"90":1,"92":9,"150":2,"152":5,"242":1,"284":3,"286":1,"294":1,"295":1,"343":1}}],["0h",{"2":{"387":2}}],["0m",{"2":{"369":1,"387":1}}],["08",{"2":{"360":1}}],["05",{"2":{"360":1,"370":1,"388":1}}],["000",{"2":{"370":1}}],["00",{"2":{"359":5,"360":5,"361":6,"370":1,"388":1}}],["007bff",{"2":{"57":1,"58":1,"63":1,"66":3}}],["03",{"2":{"356":1,"357":1,"358":1}}],["02",{"2":{"356":1,"357":1,"358":1}}],["04",{"2":{"355":1}}],["0",{"2":{"13":1,"15":1,"26":1,"58":5,"59":1,"66":6,"90":1,"149":1,"151":1,"154":1,"284":2,"359":2,"360":3,"361":3}}],["$2",{"2":{"179":1}}],["$loadpagetranslations",{"0":{"98":1},"2":{"98":2,"104":2}}],["$localepath",{"0":{"29":1}}],["$localeroute",{"0":{"28":1,"97":1},"2":{"28":1,"29":1,"36":2,"37":1,"38":1,"97":2,"103":2,"242":3,"318":1}}],["$has",{"0":{"94":1},"2":{"94":2,"138":3}}],["$mergetranslations",{"0":{"30":1,"95":1},"2":{"95":2}}],["$fetch",{"2":{"27":1,"247":1}}],["$definei18nroute",{"0":{"31":1,"239":1,"342":1},"1":{"32":1,"33":1,"34":1,"35":1,"343":1,"344":1,"345":1},"2":{"27":3,"33":2,"34":2,"239":1,"242":3,"341":1,"342":1,"346":4,"348":4,"349":1,"350":1}}],["$seti18nrouteparams",{"0":{"27":1},"2":{"27":3}}],["$switchroute",{"0":{"26":1}}],["$switchlocale",{"0":{"25":1,"96":1},"2":{"36":2,"37":1,"38":1,"96":2,"102":2,"130":2,"133":1,"146":2,"242":1}}],["$switchlocalepath",{"0":{"24":1},"2":{"24":1,"27":2}}],["$switchlocaleroute",{"0":{"23":1},"2":{"23":1,"27":2}}],["$1",{"2":{"19":1,"154":1,"179":3}}],["$td",{"0":{"21":1,"156":1,"157":1},"1":{"22":1,"157":1},"2":{"21":1,"156":1,"157":3}}],["$tn",{"0":{"19":1,"153":1,"154":1},"1":{"20":1,"154":1,"155":1},"2":{"19":1,"153":1,"154":3}}],["$tc",{"0":{"18":1,"93":1,"148":1,"149":1},"1":{"149":1,"150":1,"151":1,"152":1},"2":{"18":1,"36":2,"93":2,"148":1,"149":5,"151":3,"152":2}}],["$ts",{"0":{"17":1},"2":{"17":1}}],["$t",{"0":{"16":1,"92":1},"2":{"16":1,"17":1,"36":3,"37":1,"38":1,"92":2,"101":2,"130":2,"133":3,"138":4,"140":2,"146":18,"242":2,"348":1}}],["$getroutename",{"0":{"15":1},"2":{"15":1}}],["$getlocales",{"0":{"14":1,"91":1},"2":{"14":1,"36":2,"37":1,"38":1,"91":2,"130":2,"133":1,"146":2,"242":1}}],["$getlocalename",{"0":{"13":1,"90":1},"1":{"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1},"2":{"13":1,"90":1}}],["$getlocale",{"0":{"12":1,"89":1},"2":{"12":1,"36":3,"37":1,"38":1,"89":2,"100":2,"130":3,"133":1,"146":2,"242":1}}],["$",{"2":{"8":2,"27":1,"77":1,"87":1}}],["`alternate`",{"2":{"301":1}}],["`$",{"2":{"77":1,"85":1}}],["`news",{"2":{"27":1}}],["`error",{"2":{"8":1}}],["`",{"2":{"8":2,"27":1,"77":1}}],["===",{"2":{"27":2,"36":1,"77":1,"85":1,"130":1,"146":1,"284":2}}],["=",{"2":{"8":3,"12":2,"13":2,"14":2,"15":2,"16":2,"17":2,"18":2,"19":2,"21":2,"23":2,"24":3,"25":1,"26":1,"27":6,"28":2,"29":2,"30":1,"31":1,"33":1,"34":1,"36":1,"37":1,"38":2,"77":2,"89":3,"90":2,"91":3,"92":3,"93":3,"94":3,"95":2,"96":2,"97":3,"98":2,"100":2,"101":2,"102":1,"103":2,"104":1,"107":1,"108":1,"109":1,"110":1,"112":1,"113":1,"114":1,"116":1,"117":1,"118":1,"119":1,"124":1,"130":1,"133":1,"138":1,"140":1,"146":1,"149":1,"154":1,"157":1,"242":1,"284":4,"346":2,"348":1}}],["=>",{"2":{"3":2,"8":4,"27":1,"36":1,"77":1,"85":1,"130":1,"146":1,"284":2}}],["just",{"2":{"389":1}}],["javascriptdefinepagemeta",{"2":{"246":1}}],["javascriptaddplugin",{"2":{"7":1}}],["jane",{"2":{"101":1}}],["john",{"2":{"92":2}}],["jsexport",{"2":{"182":1}}],["js",{"0":{"182":1},"2":{"127":1,"159":1,"162":2,"165":1,"181":2,"188":1,"197":1,"316":1}}],["jsconst",{"2":{"89":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"100":1,"101":1,"102":1,"103":1,"104":1,"107":1,"108":1,"109":1,"110":1,"112":1,"113":1,"114":1,"116":1,"117":1,"118":1,"119":1}}],["json`",{"2":{"8":1}}],["json",{"0":{"131":1,"134":1,"136":1,"139":1,"141":1,"143":1,"145":1,"147":1,"150":1,"155":2},"2":{"8":1,"9":2,"131":1,"134":1,"136":1,"139":1,"141":1,"143":1,"145":1,"147":1,"150":2,"152":1,"163":1,"173":1,"175":1,"176":1,"227":4,"249":1,"253":9,"255":4,"256":6,"258":9,"261":2,"273":9,"290":3,"313":1,"317":10,"322":1,"375":1,"389":1,"391":9}}],["would",{"2":{"258":3}}],["workloads",{"2":{"371":1}}],["workaround",{"2":{"247":1}}],["work",{"0":{"240":1},"2":{"192":1,"195":1,"201":1,"212":1,"247":1}}],["workflow",{"0":{"186":1},"2":{"186":1}}],["works",{"2":{"178":1,"179":1,"320":1}}],["working",{"2":{"6":1,"163":1,"175":1,"220":1}}],["worldwide",{"2":{"379":1}}],["world",{"2":{"95":1,"354":1,"363":1}}],["writing",{"2":{"210":1}}],["wrap",{"2":{"72":1}}],["wrapper",{"2":{"39":1,"56":1,"67":1}}],["w+",{"2":{"179":1}}],["warm",{"2":{"363":1}}],["was",{"2":{"248":2,"367":1,"384":1,"385":1}}],["watson",{"2":{"167":1}}],["walkthrough",{"2":{"222":1}}],["walk",{"2":{"159":1,"251":1}}],["want",{"2":{"26":1,"35":3,"137":1,"207":1,"292":1,"295":1,"302":1,"303":1}}],["way",{"2":{"6":1,"32":1,"87":1,"153":1,"350":1}}],["were",{"2":{"179":2,"319":1,"386":1}}],["website",{"2":{"256":1,"305":1}}],["web",{"2":{"147":1}}],["we",{"2":{"140":2,"147":1,"149":1,"190":1,"213":1,"220":1,"256":1,"368":1,"370":1,"386":1}}],["well",{"2":{"123":1}}],["welcome",{"2":{"16":2,"17":2,"30":1,"36":1,"83":1,"101":2,"141":1,"143":1,"144":1,"145":1,"147":1,"190":1,"256":1}}],["welcomemessage",{"2":{"16":1,"17":1,"86":1,"101":1}}],["weight",{"2":{"48":1}}],["weekday",{"2":{"21":1,"22":1,"157":1}}],["wisely",{"0":{"264":1}}],["wish",{"2":{"35":1}}],["wide",{"2":{"147":1,"256":1}}],["wiedersehen",{"2":{"34":1,"345":1,"346":1,"348":1}}],["window",{"2":{"24":1}}],["will",{"2":{"7":2,"35":1,"45":1,"46":1,"49":1,"55":1,"76":1,"159":1,"161":1,"166":2,"175":1,"179":2,"201":1,"204":1,"206":1,"219":2,"225":1,"228":1,"229":2,"251":1,"259":1,"261":2,"283":1,"290":2,"292":2,"295":2,"296":2,"309":1,"329":1,"336":1,"364":1}}],["within",{"2":{"79":1,"87":1,"124":1,"137":1,"140":1,"146":1,"177":1,"178":4,"223":1,"228":1,"252":1,"258":1,"266":1,"341":1,"347":1,"348":1,"350":1}}],["with",{"0":{"6":1,"45":1,"86":1,"101":1,"135":1,"142":1,"144":1,"146":1,"152":1,"192":1,"236":1,"268":1,"290":1,"318":1,"325":1,"348":1,"359":1,"360":1},"1":{"7":1,"8":1,"9":1,"10":1,"143":1,"144":1,"145":1,"147":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1},"2":{"6":1,"9":1,"10":1,"22":1,"23":2,"24":2,"26":5,"28":1,"29":1,"30":1,"35":1,"45":1,"46":1,"53":1,"65":1,"66":1,"67":1,"68":1,"87":1,"92":1,"93":1,"101":2,"111":1,"116":1,"123":1,"124":1,"128":1,"132":1,"138":1,"142":1,"151":1,"154":1,"157":2,"162":1,"175":1,"178":1,"179":7,"192":1,"194":1,"215":2,"222":1,"223":1,"240":2,"242":1,"243":1,"244":1,"248":1,"249":2,"258":1,"264":1,"270":1,"279":1,"280":1,"295":1,"305":1,"311":1,"312":1,"313":1,"316":1,"318":2,"334":1,"348":1,"363":1,"364":1,"366":1,"367":1,"368":1,"375":1,"384":1,"385":3,"386":1,"389":1,"390":1}}],["without",{"2":{"5":1,"10":1,"15":1,"42":1,"87":1,"118":1,"240":1,"246":1,"262":1,"285":1,"296":1,"379":1}}],["why",{"0":{"247":1,"270":1,"312":1,"364":1,"367":1,"385":1},"1":{"386":1,"387":1,"388":1}}],["what",{"0":{"246":1,"248":1},"2":{"179":1}}],["while",{"2":{"179":1,"248":2,"249":1,"295":1,"327":1}}],["which",{"2":{"2":1,"7":1,"10":1,"15":1,"21":1,"26":1,"31":1,"32":2,"35":1,"55":1,"80":1,"83":1,"111":1,"179":1,"249":1,"256":1,"264":1,"283":1,"313":2,"344":1,"346":1,"353":1,"371":1,"381":2,"389":1}}],["who",{"2":{"175":1}}],["whether",{"2":{"190":1}}],["where",{"2":{"7":1,"32":1,"35":1,"175":1,"178":1,"179":1,"182":1,"227":1,"228":1,"229":2,"238":1,"244":1,"247":2,"259":1,"277":1,"300":1,"301":1,"302":1,"327":1,"344":3,"354":1}}],["when",{"2":{"2":1,"6":1,"9":1,"15":1,"42":1,"45":1,"49":1,"63":1,"108":1,"121":1,"151":3,"168":1,"179":2,"187":1,"213":1,"228":1,"237":1,"246":2,"247":4,"249":1,"252":1,"256":1,"258":1,"261":1,"265":1,"290":1,"292":1,"294":1,"297":1,"309":1,"347":1,"381":1}}],["ll",{"2":{"127":1,"188":1,"223":1,"235":1,"335":1}}],["less",{"2":{"369":1,"370":1,"387":1,"388":1}}],["length",{"2":{"284":4}}],["left",{"2":{"275":2}}],["leaks",{"2":{"371":1,"385":2}}],["leaving",{"2":{"295":1}}],["lean",{"2":{"264":1,"267":1}}],["leading",{"2":{"247":1,"371":1,"373":1,"383":1,"385":1}}],["lead",{"2":{"247":1,"367":1}}],["learn",{"2":{"52":1,"256":1}}],["leverages",{"2":{"327":1}}],["leverage",{"2":{"264":1,"377":1}}],["leveraging",{"2":{"166":1,"304":1,"326":1,"339":1}}],["level",{"2":{"163":1,"258":1,"349":1,"350":1}}],["letters",{"2":{"227":2,"229":1}}],["let",{"2":{"27":1}}],["layering",{"2":{"327":1}}],["layered",{"0":{"305":1},"1":{"306":1,"307":1,"308":1}}],["layer",{"0":{"300":1,"301":1,"303":2,"306":1,"307":1,"308":1,"329":1,"330":1},"1":{"301":1,"330":1},"2":{"300":2,"301":1,"303":7,"309":3,"329":1,"331":1,"332":1,"333":1,"334":2}}],["layers",{"0":{"298":1,"299":1,"302":1,"304":1,"309":1,"325":1,"331":1},"1":{"299":1,"300":1,"301":1,"302":1,"303":2,"304":2,"305":2,"306":2,"307":2,"308":2,"309":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":2,"333":2,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1},"2":{"299":2,"302":2,"304":1,"309":3,"326":1,"327":1,"337":1,"338":1,"339":1}}],["layout",{"2":{"53":1}}],["larger",{"2":{"304":1,"371":1}}],["large",{"2":{"264":1,"269":1,"270":1,"311":1,"312":1,"354":1,"363":1,"364":2,"367":2,"384":1,"385":4,"389":1}}],["landing",{"2":{"243":2}}],["lang=",{"2":{"348":1}}],["languages",{"2":{"32":1,"109":1,"222":1,"249":2,"275":1,"346":1}}],["language",{"2":{"8":1,"32":3,"114":1,"121":1,"125":2,"178":1,"229":1,"282":2,"300":1,"301":1,"303":1,"308":1,"332":1,"333":1,"346":2,"349":2,"350":1,"381":3,"383":2}}],["lang",{"2":{"8":3,"105":1,"112":2,"122":1,"125":1,"126":1,"275":1,"381":1}}],["latest",{"2":{"231":1}}],["later",{"2":{"197":2}}],["lazy",{"2":{"98":1,"104":1}}],["labels=",{"2":{"132":1}}],["labels",{"0":{"66":1},"2":{"55":1,"66":1,"132":1,"266":1}}],["label=",{"2":{"52":1}}],["label",{"2":{"52":1}}],["ltr",{"2":{"14":2,"107":1,"112":1,"128":3,"272":2,"275":3,"294":3,"301":2,"303":5,"306":2,"307":3,"308":3,"316":2,"330":3,"332":4,"333":4,"381":1,"382":2,"390":2}}],["lt",{"0":{"39":1,"53":1,"68":1,"132":1,"133":1,"142":1,"143":1,"318":2},"1":{"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"86":1,"134":1,"135":1,"136":1,"143":1,"144":1,"145":1},"2":{"14":1,"16":2,"17":2,"27":6,"30":2,"31":6,"39":2,"42":1,"53":1,"55":1,"56":1,"58":1,"59":1,"60":1,"67":1,"68":1,"73":1,"79":1,"80":2,"92":2,"98":1,"111":1,"112":2,"113":2,"114":2,"125":5,"127":3,"132":1,"133":1,"142":1,"194":1,"248":2,"249":1,"287":1,"295":3,"318":2,"381":3}}],["limit",{"2":{"377":1}}],["limiting",{"2":{"289":1}}],["lightweight",{"2":{"269":1,"384":1}}],["library",{"2":{"248":1}}],["libretranslate",{"2":{"167":2}}],["lilt",{"2":{"167":2}}],["li>",{"2":{"146":14}}],["li",{"2":{"59":1}}],["linguistic",{"2":{"237":1}}],["lingvatranslate",{"2":{"167":1}}],["lingva",{"2":{"167":1}}],["lint",{"2":{"203":2,"208":2,"211":1}}],["linter",{"2":{"203":1,"208":2,"211":1}}],["linting",{"0":{"203":1,"211":1},"2":{"211":1}}],["link>",{"2":{"41":2,"42":1,"44":1,"45":1,"46":1,"49":1,"51":1,"52":1,"80":2,"133":2,"135":1,"248":2,"249":2,"318":2}}],["links",{"0":{"46":1,"134":1},"2":{"39":1,"46":1,"67":2,"121":1,"125":2,"126":1,"242":1,"278":1,"287":1,"381":1}}],["link",{"0":{"39":1,"45":1,"114":1,"121":1,"133":1,"135":1,"136":1,"318":1},"1":{"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"134":1,"135":1,"136":1},"2":{"39":3,"41":3,"42":3,"44":2,"45":3,"46":2,"49":2,"51":2,"52":1,"62":1,"80":4,"105":1,"108":1,"109":1,"111":1,"114":3,"118":1,"125":2,"127":1,"133":3,"135":1,"218":1,"248":3,"249":6,"318":3,"381":3}}],["line",{"2":{"8":1,"159":1}}],["list",{"2":{"35":1,"58":1,"67":2}}],["likely",{"2":{"364":1}}],["like",{"0":{"248":1},"2":{"22":1,"166":1,"229":1,"247":2,"248":1,"255":1,"258":3,"281":1,"296":1,"301":1,"305":1,"366":1,"384":1}}],["lifecycle",{"2":{"4":1}}],["lower",{"2":{"312":1,"353":1,"364":1,"369":1,"371":1,"387":1}}],["lowers",{"2":{"297":1,"371":1}}],["lot",{"2":{"286":1}}],["lokaleseite",{"2":{"239":1}}],["look",{"2":{"192":1,"259":1,"366":1}}],["long",{"2":{"21":2,"22":1,"157":2}}],["logs",{"2":{"179":2}}],["logging",{"2":{"179":1,"279":2}}],["logged",{"2":{"9":1,"179":1}}],["loglevel",{"2":{"163":1}}],["log",{"2":{"89":1,"91":1,"92":1,"93":1,"94":1,"112":1,"113":1,"114":1,"163":1}}],["logic",{"0":{"363":1},"2":{"10":1,"77":1,"244":1,"248":1,"338":1,"373":1}}],["loads",{"2":{"98":1,"261":1,"377":1}}],["loaded",{"0":{"260":1},"1":{"261":1,"262":1},"2":{"9":1,"252":1,"256":1,"261":1,"262":1,"337":1,"375":1}}],["loadtranslations",{"2":{"8":2,"9":1}}],["load",{"0":{"246":1,"370":1},"2":{"8":1,"104":1,"256":1,"261":4,"264":1,"269":1,"270":1,"292":1,"312":1,"326":1,"335":1,"339":1,"363":3,"364":1,"371":2,"376":1,"377":1,"384":1,"385":1,"389":1}}],["loading",{"0":{"104":1,"322":1,"375":1},"2":{"7":1,"8":1,"9":2,"10":1,"98":1,"320":1,"377":1,"389":1}}],["locations",{"2":{"178":1}}],["location",{"2":{"24":1,"229":1,"322":1,"352":1}}],["located",{"2":{"7":1,"290":2}}],["locally",{"2":{"206":2,"208":1}}],["localhost",{"2":{"201":1,"207":1}}],["local",{"0":{"196":1},"1":{"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1},"2":{"194":1,"199":1,"247":1}}],["localize",{"2":{"243":1,"295":1}}],["localizes",{"2":{"39":1}}],["localizedroute",{"2":{"28":1,"29":1}}],["localized",{"0":{"103":1,"123":1,"133":1,"236":1},"1":{"134":1,"135":1,"136":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1},"2":{"23":1,"25":1,"26":2,"27":1,"28":1,"44":1,"92":1,"97":1,"103":1,"105":2,"126":1,"238":1,"243":1,"295":3,"296":2,"341":1,"347":1,"349":1,"350":1}}],["localization",{"2":{"1":1,"5":3,"6":1,"10":4,"32":1,"68":1,"70":1,"87":1,"159":1,"222":1,"247":4,"249":1,"295":4,"296":1,"299":1,"300":1,"302":1,"326":1,"339":1,"350":1}}],["localecookie",{"0":{"293":1}}],["localecode",{"2":{"27":3}}],["localeroutes",{"0":{"236":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1},"1":{"237":1,"238":1,"239":2,"240":2,"241":1,"242":2,"243":2,"244":1},"2":{"27":1,"31":3,"32":1,"237":1,"238":1,"239":2,"240":2,"242":2,"244":2,"343":1,"344":1,"345":1,"346":1,"348":1,"349":1}}],["localesubpage",{"2":{"31":1,"239":1,"242":1,"345":1}}],["localeslugs",{"2":{"27":3}}],["locales",{"0":{"33":1,"34":1,"102":1,"130":1,"247":1,"275":1,"325":1,"328":1,"335":1},"1":{"326":1,"327":1,"328":1,"329":2,"330":2,"331":2,"332":2,"333":2,"334":2,"335":2,"336":2,"337":2,"338":1,"339":1},"2":{"7":2,"8":1,"9":1,"14":2,"31":8,"32":3,"33":2,"34":1,"35":3,"53":1,"58":1,"60":1,"91":3,"113":1,"127":1,"128":2,"130":1,"159":1,"163":1,"170":2,"177":2,"179":3,"182":4,"188":1,"227":1,"228":1,"237":2,"238":1,"239":1,"240":2,"242":1,"244":2,"247":1,"253":1,"255":3,"256":4,"258":3,"259":1,"261":2,"262":1,"266":1,"272":2,"273":1,"275":1,"277":1,"278":1,"286":2,"290":3,"292":5,"294":1,"300":1,"301":2,"302":1,"303":4,"305":1,"306":2,"307":1,"308":1,"313":1,"316":3,"317":2,"320":1,"323":1,"326":1,"327":1,"330":2,"331":1,"332":1,"333":1,"339":1,"342":3,"343":1,"344":4,"345":1,"346":9,"347":3,"348":2,"349":3,"374":1,"376":1,"377":1,"381":1,"382":2,"389":1,"390":2,"391":1}}],["locale",{"0":{"100":1,"122":1,"129":1,"131":1,"261":1},"1":{"130":1,"131":1,"132":1},"2":{"2":5,"3":3,"4":1,"8":5,"9":4,"12":3,"13":2,"15":4,"19":2,"20":1,"21":2,"22":1,"23":6,"24":5,"25":4,"26":11,"27":1,"28":5,"29":4,"30":1,"31":1,"32":1,"34":1,"35":6,"36":6,"39":1,"44":1,"55":2,"56":1,"59":1,"61":1,"62":1,"65":1,"66":1,"67":1,"77":2,"85":1,"87":1,"89":3,"90":2,"91":1,"94":1,"95":1,"96":3,"97":2,"98":2,"100":2,"102":1,"103":1,"104":1,"107":1,"109":1,"113":2,"116":1,"121":3,"122":1,"123":1,"125":2,"126":1,"130":6,"132":1,"133":1,"146":5,"148":1,"153":1,"154":2,"156":2,"157":2,"165":1,"171":1,"177":2,"178":4,"179":1,"195":1,"215":2,"238":1,"239":2,"240":1,"242":2,"243":2,"247":1,"255":1,"256":1,"261":3,"275":4,"276":2,"282":1,"283":2,"284":3,"285":3,"286":1,"287":1,"291":2,"293":2,"294":3,"295":2,"296":2,"301":1,"302":1,"303":2,"308":2,"313":1,"317":1,"323":1,"324":1,"326":1,"329":1,"332":2,"333":2,"335":3,"336":1,"337":2,"339":1,"342":1,"344":4,"345":1,"346":1,"347":1,"348":3,"349":1,"374":1,"377":1,"381":3,"389":1}}],["h4>",{"2":{"146":2}}],["h3>",{"2":{"146":4}}],["h2>",{"2":{"146":2}}],["h1>",{"2":{"146":2,"348":2}}],["h1",{"2":{"142":1}}],["high",{"2":{"269":1,"270":1,"311":1,"363":1,"364":1,"367":1,"385":2,"389":1}}],["highlight",{"2":{"61":1}}],["highlighting",{"2":{"42":1}}],["highly",{"2":{"53":1,"350":1,"384":1}}],["hierarchy",{"2":{"227":1,"228":1}}],["history",{"2":{"179":1}}],["hi",{"2":{"179":6}}],["hideifempty=",{"2":{"76":1,"84":1}}],["hideifempty",{"0":{"76":1},"2":{"84":1}}],["http",{"2":{"201":1,"207":1}}],["https",{"2":{"46":2,"110":1,"114":1,"119":1,"194":1,"199":1,"227":1,"281":1}}],["htmlattrs",{"0":{"112":1},"2":{"111":1,"112":2,"125":1}}],["html",{"0":{"75":1},"2":{"68":1,"72":1,"75":2,"105":2,"107":1,"112":1,"122":1,"125":3,"142":1,"275":1,"381":1}}],["href=",{"2":{"146":4}}],["hreflang=",{"2":{"381":1}}],["hreflang",{"2":{"109":1,"126":1,"313":1,"381":1}}],["href",{"2":{"24":1,"114":1,"126":1}}],["hardware",{"2":{"368":1,"386":1}}],["happen",{"2":{"246":1,"283":1}}],["has",{"2":{"162":1,"228":1,"270":1,"308":1,"324":1}}],["handling",{"0":{"46":1,"123":1,"257":1,"380":1},"1":{"258":1,"381":1,"382":1,"383":1},"2":{"284":1,"312":1,"341":1,"364":1}}],["handled",{"2":{"353":1}}],["handles",{"2":{"133":1,"148":1,"149":1,"251":1,"363":1,"379":1,"383":1}}],["handle",{"0":{"319":1},"2":{"6":1,"7":1,"85":1,"87":1,"127":1,"140":1,"150":1,"152":1,"348":1,"353":1,"363":1,"371":1}}],["hallo",{"2":{"34":1,"345":1,"346":1,"348":1}}],["have",{"2":{"16":1,"17":1,"45":1,"145":1,"170":1,"181":1,"188":1,"197":1,"238":1,"240":1,"249":1,"286":1,"294":1,"296":1,"302":1,"303":1,"304":1,"305":1}}],["heavy",{"2":{"385":1}}],["headers",{"2":{"255":1}}],["header",{"2":{"125":1,"146":4,"147":4}}],["head",{"2":{"107":1,"108":2,"109":1,"110":1,"111":1,"116":2,"117":1,"118":2,"119":1,"124":2,"125":1,"367":1}}],["helpful",{"2":{"249":1}}],["help",{"2":{"190":1,"279":1,"309":1,"311":1}}],["helping",{"2":{"178":1}}],["helps",{"2":{"105":1,"165":1,"178":1,"244":1,"265":1,"350":1,"381":1}}],["hello123",{"2":{"179":1}}],["hello",{"2":{"3":1,"31":1,"34":1,"92":3,"94":1,"95":2,"145":1,"179":7,"345":1,"346":1,"348":1}}],["here",{"2":{"8":1,"36":1,"67":1,"125":1,"128":1,"146":1,"150":1,"239":1,"242":1,"253":1,"270":1,"301":1,"303":1,"316":1,"347":1,"377":1}}],["hour",{"2":{"157":1}}],["home",{"2":{"98":1,"133":1,"134":2,"146":1,"147":2,"255":2,"283":1}}],["hooks",{"2":{"9":1}}],["hooked",{"2":{"4":1}}],["hook",{"2":{"3":1,"8":2,"9":1}}],["however",{"2":{"247":1,"248":1,"354":1}}],["how",{"0":{"240":1,"260":1},"1":{"261":1,"262":1},"2":{"3":1,"36":1,"86":1,"124":1,"126":1,"127":2,"130":1,"137":1,"150":1,"165":1,"178":1,"179":2,"227":1,"239":1,"251":1,"301":1,"303":1,"348":1,"353":2,"363":2,"364":1,"366":1,"379":1}}],["v7",{"2":{"197":1}}],["verify",{"0":{"337":1},"2":{"324":1}}],["verbose",{"2":{"163":1}}],["versatile",{"2":{"39":1,"342":1}}],["versions",{"2":{"27":1,"114":1,"121":1,"125":2,"238":1,"381":1,"383":1}}],["version",{"2":{"13":1,"15":1,"25":1,"26":1,"90":1,"187":1,"381":1,"383":1}}],["visibility",{"2":{"379":1}}],["visible",{"2":{"379":1}}],["vision",{"2":{"256":1}}],["visits",{"2":{"256":1,"261":1}}],["visiting",{"2":{"141":1,"261":2}}],["view",{"2":{"201":1,"206":1,"364":1}}],["via",{"2":{"67":1,"68":1,"83":1,"286":2}}],["v",{"2":{"36":1,"130":1,"138":2,"140":1,"146":1}}],["vuei18n",{"2":{"182":1,"316":1}}],["vue",{"0":{"248":1,"348":1},"2":{"27":1,"36":1,"41":1,"42":1,"44":1,"45":1,"46":1,"49":1,"51":1,"52":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"65":1,"66":1,"68":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"79":1,"80":2,"81":1,"83":2,"84":1,"85":1,"86":1,"124":2,"130":1,"132":1,"133":1,"135":1,"138":1,"140":1,"142":1,"144":1,"146":1,"149":1,"154":1,"157":1,"242":2,"246":1,"248":2,"249":1,"286":1,"318":2,"347":1,"348":2}}],["valid",{"2":{"324":1}}],["validation",{"2":{"186":1}}],["validating",{"2":{"180":1}}],["validates",{"2":{"171":1}}],["validate",{"0":{"171":1},"2":{"171":2,"180":1}}],["values",{"0":{"88":1,"111":1,"179":1},"1":{"89":1,"112":1,"113":1,"114":1},"2":{"73":1,"137":1,"140":1,"175":1,"177":1,"178":5,"179":6,"256":1}}],["value",{"2":{"2":1,"16":2,"17":2,"18":1,"19":2,"21":2,"27":3,"35":2,"74":1,"77":1,"81":1,"85":1,"92":1,"93":1,"101":1,"138":1,"139":3,"140":2,"151":1,"166":1,"178":1,"179":3,"295":1,"344":2}}],["varying",{"2":{"326":1}}],["vary",{"2":{"148":1}}],["variables",{"2":{"187":1}}],["variant",{"2":{"17":1}}],["various",{"2":{"127":1,"147":1,"299":1,"339":1,"363":1}}],["variety",{"2":{"87":1}}],["v16",{"2":{"197":1}}],["v1",{"2":{"13":1,"15":1,"26":1,"90":1}}],["void",{"2":{"3":1,"8":1,"25":1,"26":1,"30":1,"31":1,"95":1,"96":1,"98":1}}],["uploads",{"0":{"235":1},"2":{"230":1}}],["upload",{"2":{"228":1,"230":2,"235":1}}],["uploading",{"0":{"230":1},"2":{"222":1}}],["upper",{"2":{"193":1}}],["up",{"0":{"267":1,"325":1,"335":1},"1":{"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1},"2":{"152":1,"162":1,"222":1,"230":1,"234":1,"235":1,"267":1,"300":1,"323":1,"363":1,"374":1,"377":1,"384":1}}],["updated",{"2":{"10":1,"231":1,"319":1}}],["update",{"0":{"316":1},"2":{"5":1,"10":1,"215":1,"220":1,"349":1}}],["updates",{"2":{"5":1,"6":1,"30":1,"176":1,"216":1}}],["updating",{"2":{"2":1,"9":1,"176":1,"216":2}}],["utilities",{"2":{"159":1}}],["utility",{"2":{"105":1}}],["utilize",{"2":{"86":1,"347":1}}],["ui",{"2":{"67":1}}],["ul>",{"2":{"146":4}}],["ul",{"2":{"58":1}}],["urls",{"2":{"32":1,"110":1,"114":1,"119":1,"123":1,"238":1,"243":2,"281":1,"363":1,"381":1}}],["url",{"0":{"119":1},"2":{"24":2,"29":2,"109":1,"110":1,"119":1,"121":2,"125":1,"126":2,"227":1,"228":2,"237":1,"238":1,"244":1,"281":2,"292":4,"296":1,"346":1,"381":1}}],["unpredictable",{"2":{"385":1}}],["unlike",{"2":{"313":1,"374":1,"389":1}}],["unlocalized",{"2":{"295":2,"296":2}}],["unless",{"2":{"244":1}}],["unaffected",{"2":{"295":1}}],["unnecessary",{"2":{"248":1,"309":1,"377":1}}],["unused",{"0":{"267":1},"2":{"172":1,"180":1,"185":1,"234":1,"267":1}}],["unbabel",{"2":{"167":2}}],["under",{"0":{"370":1},"2":{"266":2,"290":1,"353":1,"363":2,"364":1,"385":1,"386":1}}],["underlying",{"2":{"248":1}}],["understanding",{"2":{"383":1}}],["understand",{"2":{"165":1,"192":1,"244":1,"309":1,"313":1,"381":1,"389":1}}],["undefined",{"2":{"15":2,"16":2,"17":2,"18":1,"19":1,"21":1,"28":1,"29":1,"31":1,"294":2}}],["unique",{"2":{"32":1,"178":1,"273":1,"275":1,"341":1,"344":1,"346":1,"349":1}}],["unread",{"2":{"16":1,"17":1,"145":1}}],["unreadcount",{"2":{"16":1,"17":1,"36":1,"144":1,"145":1}}],["unknown",{"2":{"3":1,"8":1,"16":1,"92":2,"284":2}}],["usa",{"2":{"147":1}}],["usages",{"0":{"43":1,"64":1,"78":1,"99":1,"115":1},"1":{"44":1,"45":1,"46":1,"65":1,"66":1,"79":1,"80":1,"81":1,"100":1,"101":1,"102":1,"103":1,"104":1,"116":1,"117":1,"118":1,"119":1}}],["usage",{"0":{"3":1,"36":1,"44":1,"65":1,"79":1,"116":1,"124":1,"127":1,"296":1,"345":1},"1":{"125":1,"126":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1},"2":{"165":1,"166":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"269":1,"312":1,"353":2,"354":1,"355":6,"356":6,"357":4,"358":1,"359":6,"360":6,"361":3,"363":3,"364":2,"367":1,"369":4,"370":3,"371":2,"387":4,"388":3,"389":1}}],["usually",{"2":{"61":1}}],["usd",{"2":{"19":1,"154":1}}],["us",{"2":{"14":1,"19":1,"21":1,"41":1,"42":1,"44":1,"45":1,"49":1,"51":1,"52":2,"91":1,"112":1,"113":1,"128":1,"134":1,"135":1,"147":2,"154":2,"157":2,"182":1,"255":1,"256":1,"272":1,"275":2,"286":1,"287":1,"294":1,"316":2,"330":1,"332":1,"333":1,"382":1,"390":1}}],["using",{"0":{"10":1,"80":1,"132":1,"133":1,"142":1,"148":1,"149":1,"153":1,"154":1,"156":1,"157":1,"242":1,"243":1,"244":1,"304":1,"309":1,"325":1},"1":{"134":1,"135":1,"136":1,"143":1,"144":1,"145":1,"149":1,"150":1,"151":1,"152":1,"154":1,"155":1,"157":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1},"2":{"5":1,"6":1,"7":1,"9":1,"10":1,"19":1,"20":1,"21":1,"22":1,"47":1,"51":1,"67":1,"84":1,"126":1,"130":1,"137":1,"138":1,"149":1,"153":1,"156":1,"159":3,"161":1,"166":1,"168":1,"179":5,"180":1,"187":2,"188":1,"200":1,"201":1,"203":1,"208":1,"224":1,"230":1,"231":1,"239":1,"246":1,"247":1,"257":1,"270":1,"289":1,"292":1,"318":1,"341":1,"346":1,"347":1,"349":1,"366":1,"373":1}}],["usehead",{"2":{"124":1}}],["uselocalehead",{"0":{"105":1},"1":{"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1},"2":{"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"116":1,"117":1,"118":1,"119":1,"124":2,"125":1,"126":2}}],["uses",{"2":{"47":1,"146":1,"261":1,"313":1,"374":1}}],["usenuxtapp",{"0":{"37":1},"2":{"27":1,"33":2,"34":2,"37":2,"130":2,"133":2,"138":2,"140":2,"146":2,"149":2,"154":2,"157":2,"242":2,"346":4,"348":2}}],["usei18n",{"0":{"38":1,"87":1},"1":{"88":1,"89":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"103":1,"104":1},"2":{"27":1,"36":2,"38":3,"87":1,"88":1,"89":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"100":1,"101":1,"102":1,"103":1,"104":1}}],["useasyncdata",{"2":{"27":2}}],["used",{"2":{"26":1,"31":1,"60":1,"108":1,"110":1,"111":1,"125":1,"126":1,"136":1,"151":3,"165":1,"176":1,"179":2,"182":1,"228":1,"229":1,"256":1,"275":1,"293":1,"294":1,"302":1,"309":1,"349":1,"354":2,"361":3}}],["useful",{"2":{"10":1,"32":1,"42":1,"77":1,"108":1,"142":1,"148":1,"153":1,"156":1,"175":1,"176":1,"237":1,"255":1,"302":1,"344":1,"381":1}}],["useregex",{"2":{"179":3}}],["users",{"2":{"32":1,"62":1,"122":1,"123":1,"188":1,"336":1,"346":1,"363":1,"379":1,"383":1}}],["username>",{"2":{"194":1}}],["username",{"2":{"16":1,"17":1,"30":1,"36":1,"73":1,"144":1,"145":1,"194":2}}],["user",{"2":{"5":2,"10":2,"22":1,"25":2,"26":2,"32":3,"35":1,"45":1,"53":1,"73":1,"153":1,"156":1,"238":1,"243":1,"244":1,"256":1,"261":1,"276":1,"282":1,"293":2,"301":1,"308":1,"336":1,"346":2,"349":2,"350":1,"371":1,"379":1,"381":1,"383":1}}],["use",{"0":{"20":1,"22":1,"32":1,"238":1,"241":1,"249":1,"264":1,"346":1},"1":{"239":1,"240":1,"242":1,"243":1},"2":{"3":1,"36":1,"51":1,"74":1,"80":1,"85":1,"117":1,"124":1,"127":2,"166":1,"179":2,"185":1,"195":1,"202":1,"204":1,"206":1,"213":1,"238":1,"240":1,"242":1,"243":1,"244":1,"249":1,"265":1,"288":1,"289":1,"290":1,"292":2,"294":1,"301":1,"309":1,"333":1,"346":1,"347":1,"348":1,"377":2,"390":1}}],["bloating",{"2":{"264":1}}],["b",{"2":{"195":1}}],["brings",{"2":{"368":1}}],["brief",{"2":{"67":1,"141":1}}],["break",{"2":{"212":1}}],["branch",{"0":{"195":1},"2":{"195":2,"218":1,"219":1}}],["br>",{"2":{"146":2}}],["browser",{"2":{"48":1,"201":1,"206":1,"282":1}}],["bundle",{"2":{"270":1,"312":1,"367":1,"371":2,"377":1,"384":1,"385":2}}],["built",{"2":{"208":1,"248":1,"313":1,"367":1,"373":1,"384":1}}],["build",{"0":{"355":1,"356":1,"357":1,"369":1,"387":1},"1":{"357":1},"2":{"202":1,"206":3,"207":1,"208":5,"216":1,"247":4,"262":1,"269":1,"270":1,"312":1,"353":1,"355":1,"356":1,"357":2,"363":3,"364":3,"367":1,"371":2,"376":1,"384":1,"385":2,"389":2}}],["building",{"0":{"202":1,"206":1},"2":{"202":1}}],["bugs",{"2":{"385":1}}],["bugfix",{"2":{"195":1}}],["bug",{"2":{"190":1,"212":1,"216":2}}],["bulk",{"2":{"176":1,"179":1}}],["buttons",{"2":{"130":1,"266":1}}],["button>",{"2":{"36":1,"130":1,"146":1}}],["button",{"2":{"36":1,"57":1,"67":2,"130":1,"146":1,"193":1,"218":1,"266":1}}],["but",{"2":{"34":1,"35":1,"248":1,"266":1,"292":1,"308":1,"326":1,"339":1,"346":1}}],["business",{"2":{"10":1}}],["bbb",{"2":{"34":1,"346":1}}],["bottlenecks",{"2":{"367":1,"385":1}}],["both",{"2":{"87":1,"140":1,"178":2,"179":2,"252":1,"261":1,"385":1,"386":1}}],["body",{"2":{"125":1}}],["boxshadow",{"2":{"58":1,"66":1}}],["border",{"2":{"58":1,"66":1}}],["borderradius",{"2":{"57":1,"66":1}}],["bold",{"2":{"42":1,"45":2,"48":1,"49":2,"61":1,"66":1}}],["bonjour",{"2":{"34":1,"346":1,"348":1}}],["boolean>",{"2":{"284":1}}],["boolean",{"2":{"16":1,"73":1,"75":1,"76":1,"92":2,"94":1,"107":1,"109":1,"275":1,"278":1,"279":1,"280":1,"282":1,"285":1,"288":1,"289":1,"291":1}}],["bienvenue",{"2":{"30":1}}],["baidu",{"2":{"167":2}}],["back",{"2":{"92":1,"93":1,"173":1}}],["backgroundcolor",{"2":{"56":1,"57":1,"61":1,"66":3}}],["basis",{"2":{"354":1}}],["basic",{"0":{"44":1,"65":1,"79":1,"100":1,"116":1,"128":1,"253":1,"272":1},"1":{"273":1},"2":{"67":1,"128":1,"253":1,"303":3}}],["bashcrowdin",{"2":{"225":1,"230":1,"231":1}}],["bashgit",{"2":{"194":1,"195":1,"199":1,"217":1}}],["bashi18n",{"2":{"165":2,"166":2,"168":1,"169":2,"170":2,"171":2,"172":2,"173":2,"174":2,"175":2,"176":2,"177":2,"178":2,"179":4,"180":6}}],["bashnpm",{"2":{"161":1,"200":1,"201":1,"202":1,"203":2,"204":1,"205":1,"206":1,"207":1,"211":1,"212":1,"224":1,"271":1,"315":1,"390":1}}],["baseurl",{"0":{"110":1},"2":{"110":1,"119":1,"126":1}}],["base",{"0":{"119":1,"329":1,"330":1},"1":{"330":1},"2":{"15":2,"110":1,"119":1,"126":2,"227":2,"228":4,"281":2,"292":2,"299":1,"303":3,"308":1,"327":1,"329":1,"330":3,"331":1,"332":2,"333":2,"338":2}}],["based",{"0":{"33":1,"336":1},"2":{"5":1,"9":1,"18":1,"28":1,"29":1,"31":2,"32":2,"39":1,"81":1,"87":1,"93":1,"97":1,"107":1,"122":1,"125":1,"148":1,"149":1,"156":1,"179":1,"219":1,"242":1,"261":1,"282":1,"284":1,"313":1,"336":1,"342":2,"346":1,"347":1,"348":1,"349":2,"368":1,"374":1,"383":1,"389":1}}],["ban",{"2":{"8":1}}],["benefit",{"2":{"383":1}}],["benefits",{"0":{"5":1,"10":1,"383":1},"2":{"270":1,"354":1,"366":1}}],["beneficial",{"2":{"371":1}}],["become",{"2":{"367":1}}],["behave",{"2":{"247":1}}],["behavior",{"2":{"2":1,"31":1,"65":1,"106":1,"240":2,"342":1,"385":1}}],["better",{"2":{"220":1,"243":1,"312":1,"364":1,"371":1,"383":2}}],["between",{"0":{"361":1},"2":{"26":1,"53":1,"60":1,"177":1,"287":1,"313":1,"320":1,"335":1,"368":1,"375":1,"383":1,"389":1}}],["begin",{"2":{"197":1,"313":1}}],["best",{"0":{"183":1,"232":1,"244":1,"263":1,"309":1,"338":1,"347":1},"1":{"184":1,"185":1,"186":1,"187":1,"233":1,"234":1,"235":1,"264":1,"265":1,"266":1,"267":1},"2":{"377":1}}],["being",{"2":{"179":1,"324":1}}],["before",{"2":{"138":1,"179":1,"192":1,"197":1,"211":2,"313":1,"316":1,"318":1}}],["below",{"2":{"137":1,"227":1,"348":1,"363":1,"368":1}}],["be",{"2":{"9":1,"21":1,"26":1,"27":1,"31":1,"32":1,"35":2,"41":1,"42":1,"49":1,"55":1,"67":1,"83":1,"87":1,"111":1,"112":1,"136":1,"152":1,"166":1,"175":1,"176":1,"179":2,"188":1,"190":1,"214":1,"219":2,"220":1,"227":1,"229":2,"235":1,"247":1,"248":1,"249":1,"256":1,"258":3,"262":1,"275":1,"290":1,"294":1,"295":2,"296":1,"299":1,"344":1,"350":1,"353":1,"376":1,"384":1}}],["by",{"0":{"248":1,"266":1,"314":1},"1":{"315":1,"316":1,"317":1,"318":1,"319":1,"320":1},"2":{"2":2,"4":1,"7":1,"10":2,"32":2,"48":1,"67":2,"80":1,"84":1,"126":1,"165":1,"166":2,"169":1,"179":2,"182":1,"188":1,"201":1,"202":1,"211":1,"222":1,"225":1,"235":1,"238":1,"240":1,"246":1,"248":1,"251":1,"256":1,"276":1,"285":1,"292":1,"295":1,"299":2,"303":1,"304":1,"311":1,"317":1,"326":3,"327":1,"329":1,"335":1,"339":1,"346":1,"349":1,"350":2,"354":1,"364":2,"367":1,"370":1,"377":1,"379":1,"383":1}}],["risk",{"2":{"371":1}}],["right",{"2":{"193":1,"275":2}}],["rankings",{"2":{"383":1}}],["range",{"2":{"147":1,"256":1,"274":1}}],["rates",{"2":{"363":1}}],["rate",{"2":{"359":1,"360":1,"361":1}}],["rather",{"2":{"297":1}}],["raw",{"2":{"75":1}}],["rtl",{"2":{"107":1,"249":1,"272":1,"275":2,"301":1,"381":1,"382":1,"390":1}}],["robust",{"2":{"326":1,"339":1}}],["rotating",{"2":{"63":1}}],["routing",{"0":{"336":1,"374":1},"2":{"32":2,"133":1,"237":1,"244":2,"313":1,"336":1,"344":1,"346":1,"348":1,"349":1,"350":1,"374":2,"389":2}}],["router",{"2":{"215":1,"246":1,"286":1}}],["routedefinition",{"2":{"31":1,"343":1}}],["routeslocalelinks",{"0":{"287":1}}],["routes",{"0":{"123":1,"236":1,"257":1,"261":1},"1":{"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"258":1},"2":{"26":1,"31":3,"32":1,"39":1,"105":1,"123":1,"237":1,"238":1,"239":1,"240":2,"242":1,"243":2,"244":2,"246":1,"257":1,"258":4,"261":1,"262":1,"285":2,"295":1,"313":1,"323":1,"342":2,"344":1,"346":1,"347":2,"349":1,"374":1,"376":1,"389":2}}],["routefr",{"2":{"23":1,"24":2}}],["routeobject",{"2":{"15":1}}],["routename",{"2":{"15":1,"98":1,"256":1}}],["routelocationresolved",{"2":{"28":1}}],["routelocationresolvedgeneric",{"2":{"15":2,"26":3}}],["routelocationraw",{"2":{"23":1,"28":2,"29":2,"97":2}}],["routelocationnormalizedloaded",{"2":{"15":2,"26":3}}],["route",{"0":{"103":1,"246":1,"258":1,"323":1},"2":{"15":6,"23":2,"24":1,"25":2,"26":13,"27":1,"28":5,"29":3,"30":1,"31":2,"32":1,"33":1,"35":2,"41":2,"42":1,"87":1,"97":3,"103":2,"122":1,"239":2,"240":1,"242":1,"246":3,"258":3,"261":1,"283":2,"286":1,"313":2,"342":1,"344":2,"345":1,"346":2,"348":3,"374":2}}],["rgba",{"2":{"58":1,"66":1}}],["runtime",{"2":{"247":1,"262":1,"288":1,"376":1,"377":1,"385":1,"389":1}}],["running",{"0":{"204":1,"207":1},"2":{"211":1,"225":1,"326":1,"335":1,"339":1}}],["run",{"0":{"201":1,"211":1},"2":{"162":1,"169":1,"200":2,"201":2,"202":1,"203":3,"204":3,"205":2,"206":2,"207":2,"208":12,"211":1,"212":2,"271":1,"335":1}}],["russian",{"2":{"34":1,"238":2,"239":1,"242":1,"296":2,"345":1,"346":1,"348":1}}],["rules",{"2":{"71":1,"77":1,"81":1,"152":2,"249":1}}],["rule",{"0":{"85":1},"2":{"18":1}}],["ru",{"2":{"2":1,"31":2,"34":1,"239":1,"242":1,"295":2,"296":3,"345":2,"346":1,"348":3}}],["reorganize",{"0":{"317":1}}],["reusable",{"2":{"299":1}}],["renaming",{"2":{"257":1}}],["rendered",{"2":{"86":1,"376":1}}],["render",{"2":{"76":1,"84":1,"137":1,"262":1,"377":1}}],["rendering",{"0":{"84":1,"137":1,"138":1,"140":1,"262":1,"376":1},"1":{"138":1,"139":1,"140":1,"141":1},"2":{"75":1,"138":1,"140":1,"142":1,"247":1,"262":2,"297":1,"376":2,"377":1}}],["renders",{"2":{"65":1,"79":1}}],["reflect",{"2":{"364":1}}],["refactor",{"2":{"216":1}}],["refer",{"2":{"377":1}}],["referral",{"2":{"249":1}}],["referencing",{"2":{"179":1}}],["reference",{"2":{"171":1,"179":1}}],["refers",{"2":{"179":1}}],["requested",{"2":{"297":1}}],["request",{"0":{"218":1},"2":{"218":1,"219":1,"292":1,"363":1,"370":2,"388":2}}],["requests",{"0":{"388":1},"2":{"192":1,"262":1,"297":1,"353":2,"359":1,"360":1,"361":1,"363":2,"370":4,"371":1,"376":2,"388":3}}],["requires",{"2":{"353":1}}],["required",{"2":{"41":1,"70":1,"168":1,"179":2,"252":1,"275":1,"347":1,"363":1}}],["require",{"2":{"32":1,"168":1,"187":1,"237":1,"344":1}}],["requirements",{"2":{"10":1,"302":1,"326":1,"331":1,"339":1}}],["requiring",{"2":{"10":1,"304":1,"379":1}}],["reason",{"2":{"244":1}}],["readability",{"2":{"266":1}}],["ready",{"2":{"202":1,"363":1,"390":1}}],["read",{"2":{"192":1,"247":1}}],["real",{"2":{"5":1,"354":1,"363":1}}],["regardless",{"2":{"313":1,"374":1,"389":1}}],["regexp",{"2":{"286":1}}],["regex",{"2":{"179":9,"286":2,"313":1,"374":1,"389":1}}],["regularly",{"0":{"267":1},"2":{"185":1}}],["regular",{"0":{"185":1,"234":1},"2":{"179":2}}],["regional",{"2":{"153":1,"237":1,"350":1}}],["region",{"2":{"32":1}}],["regions",{"2":{"32":1,"336":1,"346":1}}],["registration",{"2":{"7":1}}],["registering",{"0":{"7":1},"2":{"9":1,"10":1}}],["registers",{"2":{"4":1,"7":1}}],["registered",{"2":{"2":1,"246":1}}],["register",{"0":{"1":1},"1":{"2":1,"3":1,"4":1,"5":1},"2":{"1":1,"2":2,"3":4,"4":2,"5":1,"7":1,"8":5,"9":2}}],["remain",{"2":{"295":1,"364":1}}],["remains",{"2":{"5":1,"296":1}}],["removed",{"2":{"267":1}}],["remove",{"2":{"185":1,"319":1}}],["removes",{"2":{"172":1}}],["review",{"2":{"219":1,"234":1,"267":1}}],["reverso",{"2":{"167":2}}],["revoir",{"2":{"34":1,"346":1,"348":1}}],["representative",{"2":{"354":1}}],["represents",{"2":{"344":1}}],["representing",{"2":{"2":1,"26":1,"59":1}}],["repeatedly",{"2":{"262":1}}],["repetition",{"2":{"178":1}}],["repository",{"0":{"193":1,"199":1},"2":{"188":1,"193":2,"194":1,"199":1,"218":2}}],["reports",{"2":{"178":1}}],["replacing",{"2":{"92":1,"166":1,"180":1}}],["replaces",{"2":{"179":1}}],["replacement",{"2":{"179":12}}],["replacements",{"2":{"179":3}}],["replace",{"0":{"179":1,"318":1},"2":{"83":1,"142":2,"166":1,"179":12,"180":1,"194":1,"284":1,"316":1,"318":1}}],["replaced",{"2":{"80":1,"179":1}}],["relationships",{"2":{"383":1}}],["related",{"2":{"109":1,"118":1,"125":1,"266":2,"278":1,"281":1,"301":1,"320":1,"383":1}}],["releasing",{"2":{"248":1}}],["relevant",{"2":{"32":1,"123":1,"218":1,"220":1,"238":1,"244":1,"346":1,"347":1}}],["relies",{"2":{"181":1}}],["rel",{"2":{"114":1,"126":1}}],["rel=",{"2":{"46":1,"121":2,"125":2,"381":2}}],["relying",{"2":{"42":1}}],["redundant",{"2":{"319":1}}],["reduced",{"2":{"312":1,"326":1,"371":1,"383":1}}],["reduces",{"2":{"270":1,"297":1,"371":2,"373":1,"389":1}}],["reduce",{"2":{"269":1,"335":1,"339":1,"377":2}}],["reducing",{"2":{"244":1,"256":1,"262":1,"287":1,"364":1,"374":1,"376":1,"384":1}}],["red",{"2":{"42":1}}],["redirection",{"2":{"282":1}}],["redirecting",{"2":{"26":2,"285":1}}],["redirects",{"2":{"25":2,"282":1,"285":1}}],["redeployment",{"2":{"10":1}}],["redeploy",{"2":{"5":1}}],["recognize",{"2":{"354":1,"381":1}}],["record",{"2":{"16":3,"17":3,"27":6,"30":2,"31":6,"55":1,"73":1,"92":1,"112":1,"113":1,"114":1,"284":1,"287":1,"295":3,"343":3}}],["recommended",{"0":{"252":1},"1":{"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1},"2":{"6":1,"251":1}}],["retrieve",{"2":{"100":1,"297":1}}],["retrieves",{"2":{"15":1}}],["retrieval",{"0":{"100":1}}],["returns",{"2":{"12":1,"13":1,"14":1,"17":1,"27":1,"88":1,"89":1,"90":1,"91":1,"111":1,"125":1,"151":3}}],["returned",{"2":{"9":1,"126":1}}],["return",{"0":{"88":1,"111":1},"1":{"89":1,"112":1,"113":1,"114":1},"2":{"8":2,"16":1,"17":1,"18":1,"23":1,"24":1,"27":1,"29":1,"77":2,"85":1,"152":2,"284":4}}],["resolution",{"2":{"374":1}}],["resolves",{"2":{"26":1}}],["resolve",{"2":{"7":1,"215":1}}],["resources",{"2":{"363":1}}],["resource",{"0":{"357":1,"369":1,"387":1},"2":{"297":1,"312":1,"364":2}}],["results",{"0":{"351":1,"371":1},"1":{"352":1,"353":1,"354":1,"355":1,"356":1,"357":1,"358":1,"359":1,"360":1,"361":1,"362":1,"363":1,"364":1},"2":{"377":2,"388":1}}],["result",{"2":{"297":1}}],["restructured",{"2":{"267":1}}],["respectful",{"2":{"220":2}}],["respective",{"2":{"67":1,"337":1,"338":1}}],["response",{"2":{"27":5,"359":3,"360":3,"361":3,"363":1,"367":1,"376":1,"377":1,"385":1}}],["responsive",{"2":{"10":1,"364":1}}],["re",{"2":{"7":1,"210":1,"212":1,"390":1}}],["gzip",{"2":{"369":2,"387":2}}],["gives",{"2":{"295":1}}],["given",{"2":{"16":1,"17":1,"18":1,"23":1,"24":1,"25":1,"26":2,"92":1,"93":1,"295":1,"375":1}}],["git",{"2":{"194":1,"199":1}}],["github",{"0":{"217":1},"2":{"193":1,"194":2,"199":1,"217":1,"218":1}}],["gpt",{"2":{"166":1,"168":1}}],["guide",{"0":{"158":1,"181":1,"189":1,"221":1,"226":1,"250":1,"365":1,"378":1},"1":{"159":1,"160":1,"161":1,"162":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"180":1,"181":1,"182":2,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"190":1,"191":1,"192":1,"193":1,"194":1,"195":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":2,"228":2,"229":2,"230":1,"231":1,"232":1,"233":1,"234":1,"235":1,"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1,"366":1,"367":1,"368":1,"369":1,"370":1,"371":1,"372":1,"373":1,"374":1,"375":1,"376":1,"377":1,"379":1,"380":1,"381":1,"382":1,"383":1},"2":{"159":1,"188":1,"190":1,"215":1,"222":1,"225":1,"235":1,"251":1,"311":1,"366":1,"379":1}}],["ground",{"2":{"384":1}}],["group",{"2":{"179":2,"266":2}}],["groups",{"2":{"179":5}}],["grow",{"2":{"364":1}}],["grows",{"2":{"265":1}}],["granular",{"2":{"354":1}}],["grammatical",{"2":{"249":1}}],["graph",{"2":{"113":1,"381":2}}],["gray",{"2":{"62":1,"66":1}}],["green",{"2":{"49":1,"61":1,"66":1}}],["greetings",{"2":{"349":1}}],["greeting",{"2":{"3":1,"4":1,"31":2,"34":3,"73":1,"92":2,"142":1,"143":1,"242":2,"345":3,"346":3,"348":5}}],["goal",{"2":{"220":1}}],["good",{"2":{"192":1}}],["goodbye",{"2":{"3":1,"31":1,"34":1,"345":1,"346":1,"348":1}}],["google",{"2":{"166":2,"167":2,"180":3}}],["go",{"2":{"36":1,"218":1,"242":2}}],["general",{"2":{"338":1}}],["generation",{"2":{"126":1,"215":1,"278":1,"279":1,"307":1,"308":1,"313":1,"319":1}}],["generating",{"0":{"103":1},"2":{"123":1,"281":1,"313":1,"379":1}}],["generate",{"2":{"103":1,"110":1,"116":1,"118":1,"126":1,"301":1,"374":1,"389":1}}],["generated",{"2":{"28":1,"29":1,"108":1,"117":1,"125":1,"313":1,"320":1,"324":1,"389":1}}],["generates",{"2":{"28":1,"97":1,"105":1,"121":1,"126":1,"278":1,"374":1,"381":3,"385":1,"389":1}}],["generic",{"2":{"338":1}}],["german",{"0":{"333":1},"2":{"239":1,"296":2,"308":3,"332":1,"333":3}}],["getter",{"2":{"284":2}}],["getting",{"0":{"191":1,"198":1,"268":1},"1":{"192":1,"193":1,"194":1,"195":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1}}],["gettranslation",{"2":{"77":2}}],["get",{"2":{"128":1,"190":1,"223":1,"377":1}}],["getnews",{"2":{"27":1}}],["gt",{"0":{"39":1,"53":1,"68":1,"132":1,"133":1,"142":1,"143":1,"318":2},"1":{"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"86":1,"134":1,"135":1,"136":1,"143":1,"144":1,"145":1},"2":{"12":1,"13":1,"14":2,"15":1,"16":3,"17":3,"18":1,"19":1,"21":1,"23":1,"24":1,"25":1,"26":1,"27":7,"28":1,"29":1,"30":3,"31":7,"39":2,"42":1,"53":1,"55":1,"56":1,"58":1,"59":1,"60":1,"67":1,"68":1,"73":1,"77":1,"79":1,"80":2,"89":1,"90":1,"91":1,"92":3,"93":1,"94":1,"95":1,"96":1,"97":1,"98":2,"111":1,"112":2,"113":2,"114":2,"125":5,"127":3,"132":1,"133":1,"142":1,"194":1,"248":2,"249":1,"284":1,"287":1,"295":3,"318":2,"381":3}}],["g",{"2":{"2":1,"9":1,"23":1,"24":1,"28":1,"29":1,"89":1,"91":1,"92":1,"93":1,"94":1,"123":1,"152":1,"161":1,"166":2,"179":1,"224":1,"255":1,"256":1,"275":2,"286":1,"344":1,"353":1,"381":1,"389":1}}],["globallocaleroutes",{"0":{"295":1}}],["globally",{"2":{"161":2,"223":1,"224":1,"309":1}}],["global",{"0":{"255":1,"306":1},"2":{"1":1,"2":1,"9":1,"123":1,"178":3,"179":1,"251":1,"252":1,"264":1,"273":2,"289":2,"290":1,"300":1,"307":1,"308":1,"313":1,"326":1,"339":1,"375":1,"381":1,"389":1,"391":1}}],["own",{"2":{"240":1,"304":1,"308":1}}],["old",{"2":{"179":1}}],["outperforms",{"2":{"388":1}}],["outputs",{"2":{"149":3,"154":2,"157":2}}],["output",{"2":{"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"21":1,"22":1,"23":1,"24":1,"25":1,"28":1,"29":1,"30":1,"90":1,"112":1,"113":1,"114":1}}],["out",{"2":{"377":1}}],["outlines",{"2":{"190":1}}],["our",{"2":{"141":2,"147":3,"256":2}}],["og",{"2":{"109":2,"113":2,"121":3,"125":2,"215":1,"381":2}}],["overhead",{"2":{"364":1,"373":1,"377":1}}],["overuse",{"2":{"244":1}}],["over",{"2":{"137":1,"138":1,"140":1,"237":1,"267":1,"312":1,"363":1,"366":1,"384":1}}],["overriding",{"2":{"240":1,"288":1,"299":1}}],["overridden",{"2":{"67":1}}],["override",{"2":{"48":1,"56":1,"302":1,"303":1,"309":1}}],["overview",{"0":{"67":1,"269":1,"341":1},"2":{"67":1,"363":1}}],["overall",{"2":{"5":1,"10":1,"335":1,"353":1,"363":1,"371":1}}],["operation",{"2":{"179":1}}],["openaimodel",{"2":{"168":1}}],["openai",{"2":{"167":2,"168":2}}],["opened",{"2":{"63":1}}],["open",{"2":{"46":1,"113":1,"188":1,"192":1,"246":1,"381":2}}],["optimize",{"2":{"376":1}}],["optimized",{"2":{"270":1,"312":1,"354":1,"364":1,"389":1}}],["optimizing",{"2":{"123":1,"252":1,"261":1,"335":1,"367":1}}],["optimizations",{"0":{"372":1},"1":{"373":1,"374":1,"375":1,"376":1}}],["optimization",{"2":{"121":1,"313":1,"379":1}}],["option",{"2":{"59":1,"61":1,"126":2,"179":2,"280":1,"295":1,"322":1,"324":1,"381":1,"382":1,"383":1}}],["options",{"0":{"106":1,"274":1},"1":{"107":1,"108":1,"109":1,"110":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1},"2":{"19":2,"21":2,"22":1,"106":1,"116":1,"154":1,"157":1,"165":2,"166":4,"168":2,"169":2,"170":1,"171":1,"172":1,"173":2,"174":2,"175":2,"176":2,"177":1,"178":1,"179":2,"274":1}}],["optionalmessage",{"2":{"76":1,"84":1}}],["optionally",{"2":{"16":1,"17":1,"92":1,"93":1,"97":1}}],["optional",{"2":{"2":1,"15":2,"16":2,"17":2,"18":1,"19":1,"21":1,"26":1,"28":1,"29":1,"31":1,"42":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"275":3}}],["others",{"2":{"166":1,"295":1,"309":1}}],["other",{"2":{"27":1,"52":1,"80":1,"148":1,"152":1,"153":1,"177":2,"182":1,"225":1,"299":1,"300":1,"305":1,"329":1,"366":1,"374":1,"389":1}}],["otherwise",{"2":{"9":1}}],["occur",{"2":{"7":1,"283":1}}],["once",{"2":{"219":2,"230":1,"262":1}}],["ongoing",{"2":{"192":1}}],["ones",{"2":{"95":1}}],["one",{"2":{"85":1,"149":1,"150":1,"151":2,"152":2,"166":1,"246":1,"284":1,"297":1,"363":1}}],["only",{"2":{"32":1,"33":1,"35":2,"165":1,"252":1,"256":1,"261":1,"266":1,"283":1,"289":2,"290":1,"295":1,"296":1,"309":1,"313":2,"326":1,"339":1,"346":2,"373":1,"374":1,"375":2,"377":1,"389":2}}],["on",{"0":{"33":1,"336":1,"367":1},"2":{"5":1,"9":2,"18":1,"23":1,"24":1,"26":1,"28":1,"29":1,"31":2,"32":2,"39":1,"42":1,"45":1,"81":1,"87":1,"93":1,"97":1,"107":1,"122":1,"125":1,"148":1,"149":1,"152":1,"156":1,"161":1,"179":1,"181":1,"188":1,"197":1,"201":1,"217":1,"218":1,"219":1,"222":1,"223":1,"242":1,"255":1,"261":1,"270":2,"282":1,"283":2,"284":1,"336":1,"337":1,"342":2,"346":1,"347":1,"348":1,"349":2,"354":1,"363":2,"364":2,"367":2,"368":2,"371":1,"381":1,"383":1,"384":1,"386":1,"389":1}}],["organization",{"2":{"252":1}}],["organizing",{"2":{"251":1}}],["organize",{"0":{"266":1},"2":{"377":1}}],["organizes",{"2":{"169":1,"252":1}}],["organized",{"2":{"2":1,"234":1,"235":1,"273":1,"317":1,"347":1,"354":1,"391":1}}],["origin",{"2":{"217":1}}],["original",{"2":{"179":1,"218":1,"229":1,"385":1,"388":1}}],["or",{"0":{"249":1},"2":{"5":2,"6":1,"10":3,"15":1,"20":1,"21":1,"22":1,"26":1,"27":1,"31":1,"32":2,"38":1,"41":2,"61":1,"63":1,"68":1,"80":1,"103":1,"107":1,"148":1,"151":1,"153":1,"168":1,"171":1,"177":1,"178":1,"179":2,"186":1,"187":1,"188":2,"190":1,"195":1,"197":2,"216":4,"220":1,"231":1,"237":2,"243":1,"244":1,"247":1,"249":2,"255":1,"264":1,"267":1,"275":1,"288":1,"295":2,"296":1,"299":1,"302":2,"303":1,"305":1,"309":2,"311":1,"318":1,"327":1,"341":1,"344":1,"346":2,"347":1,"381":1}}],["objects",{"2":{"347":1}}],["objective",{"0":{"327":1}}],["object",{"0":{"140":1},"2":{"2":1,"15":1,"21":1,"23":1,"26":1,"28":3,"29":1,"32":1,"35":4,"41":1,"88":1,"106":1,"111":1,"125":1,"126":1,"140":2,"275":1,"344":3,"346":1,"347":1}}],["offer",{"2":{"256":1}}],["offering",{"2":{"237":1,"251":1,"326":1,"342":1,"366":1,"384":1}}],["offers",{"2":{"32":2,"87":1,"147":1,"312":1,"313":1,"350":1,"371":1}}],["of",{"0":{"10":1,"125":1,"208":1,"238":1,"254":1,"371":1},"1":{"239":1,"240":1,"255":1,"256":1},"2":{"1":1,"2":1,"7":1,"10":1,"14":1,"16":1,"17":2,"24":1,"25":1,"27":2,"32":1,"35":1,"36":1,"47":1,"55":1,"58":1,"67":2,"75":1,"80":2,"87":1,"89":1,"91":1,"98":1,"100":1,"105":2,"110":1,"111":1,"114":1,"121":1,"123":1,"125":2,"126":1,"138":1,"140":1,"141":1,"147":1,"149":2,"165":2,"167":1,"178":1,"179":4,"186":1,"193":1,"218":1,"220":1,"228":1,"229":1,"235":2,"237":1,"238":1,"239":1,"242":1,"253":1,"256":2,"259":1,"262":1,"270":1,"274":1,"286":1,"288":1,"291":2,"292":1,"293":1,"295":2,"296":1,"297":2,"299":3,"301":1,"302":3,"303":1,"305":1,"309":1,"311":1,"312":1,"313":2,"319":1,"322":1,"331":1,"335":2,"338":1,"341":1,"344":1,"347":1,"348":1,"349":1,"350":1,"353":3,"354":2,"363":5,"364":2,"366":1,"368":1,"371":3,"374":3,"376":1,"377":3,"379":2,"381":2,"386":1,"389":2}}],["f0f0f0",{"2":{"61":1,"66":1}}],["fff",{"2":{"57":1,"66":1}}],["f8f9fa",{"2":{"56":1,"66":1}}],["feat",{"2":{"215":1,"216":1}}],["feature",{"2":{"195":3,"210":1,"216":2,"217":2,"220":1,"237":2,"350":1}}],["features",{"0":{"50":1,"82":1,"120":1,"248":1,"381":1,"389":1},"1":{"51":1,"52":1,"83":1,"84":1,"85":1,"86":1,"121":1,"122":1,"123":1},"2":{"39":1,"190":1,"267":1,"297":1,"377":1,"382":1}}],["feel",{"2":{"188":1}}],["feedback",{"0":{"219":1},"2":{"70":1,"72":1,"75":1,"79":2,"80":3,"219":1,"248":2}}],["fewer",{"2":{"312":1}}],["few",{"2":{"152":3,"377":1}}],["fetching",{"2":{"292":1}}],["fetch",{"2":{"140":1,"262":1,"292":1,"297":1}}],["fetches",{"2":{"16":1,"17":1,"18":1,"138":1,"231":1}}],["flat",{"2":{"257":1}}],["flows",{"2":{"32":1,"346":1,"349":1}}],["flexibly",{"2":{"299":1}}],["flexible",{"2":{"1":1,"5":1,"32":1,"51":1,"68":1,"248":1,"326":1,"339":1,"350":1}}],["flexibility",{"2":{"5":1,"10":1,"32":1,"237":1,"295":1,"347":1}}],["fine",{"2":{"274":1}}],["finding",{"2":{"247":1}}],["fixtures",{"0":{"355":1,"356":1,"359":1,"360":1},"1":{"357":1},"2":{"352":2}}],["fixing",{"2":{"212":1}}],["fix",{"2":{"195":1,"203":2,"208":2,"211":1,"212":1,"215":1,"216":3,"246":1}}],["fixes",{"2":{"190":1}}],["fill",{"2":{"166":1}}],["file",{"0":{"139":1,"141":1,"227":1},"2":{"136":1,"140":1,"150":1,"175":2,"176":1,"178":1,"179":2,"227":1,"229":1,"231":1,"246":1,"258":1,"259":1,"262":1,"272":1,"301":1,"330":1,"354":1,"368":1,"382":1,"386":1,"389":1}}],["files",{"0":{"137":1,"229":1,"230":1,"255":1,"256":1,"264":1,"317":1,"322":1},"1":{"138":1,"139":1,"140":1,"141":1},"2":{"6":1,"8":1,"9":2,"70":1,"137":1,"159":1,"163":1,"170":1,"171":1,"172":1,"173":2,"174":2,"175":3,"176":4,"177":1,"178":2,"179":2,"180":2,"182":1,"185":1,"186":1,"202":1,"227":2,"228":2,"229":4,"230":2,"233":1,"234":1,"235":1,"247":6,"251":1,"252":2,"255":1,"256":1,"258":3,"259":2,"261":1,"262":2,"264":2,"265":1,"266":1,"267":1,"273":3,"277":2,"287":1,"288":1,"289":1,"290":2,"291":2,"297":1,"311":1,"312":1,"313":3,"317":1,"322":2,"363":1,"367":1,"375":2,"376":2,"377":1,"385":2,"389":2,"391":1}}],["fit",{"2":{"77":1}}],["first",{"2":{"27":2,"139":1,"151":1,"179":1,"199":1,"224":1,"315":1}}],["faster",{"2":{"312":1,"364":1,"369":1,"370":1,"371":2,"387":1,"388":1}}],["fast",{"2":{"264":1,"384":1}}],["faq",{"0":{"245":1},"1":{"246":1,"247":1,"248":1,"249":1}}],["familiarize",{"0":{"192":1},"2":{"192":1}}],["familiar",{"2":{"156":1}}],["falling",{"2":{"92":1,"93":1}}],["fallbacklocale",{"0":{"294":1},"2":{"182":1,"294":1}}],["fallback",{"2":{"74":1,"101":1,"294":2}}],["false",{"2":{"75":1,"76":1,"107":1,"109":1,"118":1,"128":3,"165":1,"166":1,"179":1,"275":1,"279":1,"282":1,"285":1,"286":1,"288":1,"289":1,"291":1,"295":3,"303":1,"307":1,"308":1,"332":1,"333":1}}],["facilitates",{"2":{"26":1}}],["farewells",{"2":{"349":1}}],["farewell",{"2":{"3":1,"4":1,"31":2,"34":3,"345":3,"346":3,"348":5}}],["français",{"2":{"55":1,"66":1,"128":1,"131":1,"132":1}}],["fraction",{"2":{"20":1}}],["friends",{"2":{"249":1}}],["friendly",{"2":{"53":1,"220":1,"350":1}}],["friday",{"2":{"21":1,"157":1}}],["freeing",{"2":{"383":1}}],["free",{"2":{"178":1,"188":1}}],["french",{"0":{"332":1},"2":{"25":1,"26":1,"30":1,"303":1,"332":3,"333":1,"348":1}}],["frequently",{"2":{"10":1}}],["fr",{"2":{"14":3,"15":1,"23":2,"24":2,"25":1,"26":1,"27":4,"28":1,"33":1,"34":1,"55":1,"66":1,"91":3,"96":1,"97":1,"98":1,"103":1,"128":3,"131":1,"132":1,"182":3,"253":3,"258":3,"261":2,"272":3,"273":3,"275":3,"290":1,"294":3,"301":3,"303":7,"306":3,"307":3,"308":3,"316":6,"317":3,"332":6,"333":3,"334":2,"344":1,"346":2,"348":3,"382":3,"390":3,"391":3}}],["from",{"0":{"137":1,"140":1,"231":1,"310":1},"1":{"138":1,"139":1,"140":1,"141":1,"311":1,"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1},"2":{"8":2,"10":1,"13":1,"15":1,"33":1,"34":1,"36":1,"37":1,"38":1,"62":1,"90":1,"126":1,"130":1,"133":1,"138":2,"140":1,"146":1,"149":1,"154":1,"157":1,"159":1,"166":1,"169":1,"172":1,"175":1,"176":2,"179":1,"190":1,"231":1,"242":1,"247":1,"248":1,"261":2,"262":1,"292":1,"297":1,"303":3,"311":2,"332":1,"333":1,"346":2,"348":2,"383":2,"384":1}}],["further",{"2":{"262":1,"375":1}}],["future",{"2":{"248":1,"309":1}}],["fully",{"2":{"66":1,"354":1}}],["full",{"2":{"10":1,"123":1,"157":1,"165":2}}],["functions",{"2":{"247":1}}],["functional",{"2":{"216":1}}],["functionality",{"2":{"212":1}}],["functionalities",{"2":{"87":1,"326":1,"339":1}}],["functioning",{"2":{"204":1}}],["function",{"0":{"342":1},"1":{"343":1,"344":1,"345":1},"2":{"2":2,"4":1,"8":1,"9":2,"32":1,"77":1,"85":1,"148":1,"153":1,"156":1,"239":1,"284":1,"341":1,"342":1,"348":1,"350":1}}],["focusing",{"2":{"363":1,"364":1,"384":1,"389":1}}],["focus",{"0":{"367":1},"2":{"270":1,"353":1,"364":1}}],["folders",{"2":{"247":1}}],["folder",{"0":{"247":2,"250":1,"252":1,"258":1,"273":1,"290":1,"391":1},"1":{"251":1,"252":1,"253":2,"254":2,"255":2,"256":2,"257":2,"258":2,"259":2,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1},"2":{"228":1,"247":3,"251":1,"253":1,"257":1,"258":6}}],["follows",{"2":{"214":1,"238":1}}],["follow",{"2":{"210":1,"213":1,"220":1,"237":1,"253":1,"322":1}}],["followed",{"2":{"179":1}}],["following",{"2":{"3":1,"121":1,"124":1,"149":1,"188":1,"197":1,"201":1,"202":1,"204":1,"206":1,"207":1,"230":1,"235":1,"246":1,"271":1,"296":1,"381":1}}],["footers",{"2":{"255":1}}],["footer",{"2":{"146":4,"147":1,"255":1}}],["footer>",{"2":{"146":2}}],["footernote",{"2":{"141":1}}],["fontsize",{"2":{"63":1,"66":1}}],["font",{"2":{"48":1}}],["fontweight",{"2":{"42":1,"45":1,"49":1,"61":1,"66":1}}],["foundation",{"2":{"329":1}}],["found",{"0":{"323":1},"2":{"16":1,"17":1,"18":1,"74":1,"92":1,"93":1,"178":2,"179":2,"247":1,"248":1,"385":1}}],["forked",{"2":{"194":1,"218":1}}],["fork",{"0":{"193":1,"194":1},"2":{"193":1,"217":1}}],["form",{"2":{"151":3,"266":1}}],["forms",{"2":{"149":1,"150":1,"266":1,"284":9}}],["formatteddate",{"2":{"21":1}}],["formattednumber",{"2":{"19":1}}],["formatting",{"0":{"153":1,"154":1,"155":2,"156":1,"157":1},"1":{"154":1,"155":1,"157":1},"2":{"19":1,"20":1,"21":1,"216":1}}],["format",{"0":{"214":1},"2":{"19":1,"20":2,"21":1,"22":1,"154":2,"157":2,"173":1,"175":1,"213":2,"215":1,"238":1,"258":1,"317":1,"322":1,"347":1}}],["formats",{"2":{"19":1,"21":1,"22":2,"153":2,"156":2}}],["for=",{"2":{"36":1,"130":1,"138":1,"140":1,"146":1}}],["for",{"0":{"10":1,"34":1,"51":1,"80":1,"131":1,"133":1,"134":1,"136":1,"142":1,"143":1,"145":1,"147":1,"148":1,"149":1,"150":1,"153":1,"154":1,"155":2,"156":1,"157":1,"241":1,"244":1,"307":1,"308":1,"309":1,"332":1,"333":1,"334":1,"335":1,"355":1,"356":1,"359":1,"360":1,"377":1,"378":1},"1":{"134":1,"135":1,"136":1,"143":1,"144":1,"145":1,"149":1,"150":1,"151":1,"152":1,"154":1,"155":1,"157":1,"242":1,"243":1,"357":1,"379":1,"380":1,"381":1,"382":1,"383":1},"2":{"2":3,"4":2,"8":1,"9":1,"10":1,"16":1,"17":1,"18":3,"26":2,"27":3,"28":1,"29":1,"30":1,"31":4,"32":3,"33":1,"35":5,"39":1,"41":2,"42":1,"46":1,"47":1,"51":1,"53":1,"55":1,"58":1,"61":1,"62":1,"63":1,"71":1,"73":1,"79":1,"87":1,"88":1,"94":1,"95":1,"98":1,"104":1,"105":2,"108":1,"109":1,"110":1,"113":1,"114":1,"117":1,"119":1,"121":4,"122":1,"123":3,"125":1,"126":1,"132":1,"136":1,"138":1,"141":1,"142":1,"148":1,"152":2,"153":1,"156":1,"165":1,"166":1,"168":1,"171":1,"174":1,"175":2,"176":1,"178":2,"179":5,"188":2,"190":1,"195":1,"202":1,"205":1,"208":2,"210":1,"228":3,"229":1,"230":1,"237":1,"238":4,"239":3,"242":2,"243":3,"244":2,"248":2,"251":1,"255":1,"256":1,"258":6,"259":1,"261":1,"262":2,"264":1,"265":1,"266":1,"269":2,"270":1,"275":5,"277":1,"278":1,"281":2,"284":3,"288":1,"292":1,"295":7,"296":4,"297":1,"299":2,"300":1,"301":1,"302":3,"303":1,"308":1,"309":2,"313":2,"317":1,"318":1,"326":4,"327":1,"329":2,"331":2,"332":1,"333":1,"334":2,"335":1,"339":3,"341":2,"342":2,"344":4,"345":1,"346":7,"347":4,"348":3,"349":3,"353":1,"354":4,"363":3,"364":2,"367":1,"371":1,"374":1,"375":1,"376":3,"377":1,"379":2,"381":7,"384":1,"385":1,"389":4}}],["phase",{"2":{"363":2}}],["phases",{"2":{"363":1}}],["phone",{"2":{"146":1,"147":1}}],["push",{"0":{"217":1},"2":{"217":2}}],["publishing",{"2":{"208":1}}],["pull",{"0":{"218":1},"2":{"192":1,"218":1,"219":1}}],["purposes",{"2":{"110":1,"354":1}}],["purpose",{"2":{"2":1,"255":1,"256":1,"309":1}}],["pipeline",{"2":{"186":1,"235":1}}],["personalized",{"2":{"383":1}}],["per",{"0":{"340":1,"348":1},"1":{"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1},"2":{"243":1,"341":1,"347":1,"350":1,"354":1,"359":1,"360":1,"361":1,"363":2,"370":5,"388":5}}],["periodically",{"2":{"234":1,"267":1}}],["permissions",{"2":{"228":1}}],["performances",{"2":{"286":1}}],["performance",{"0":{"351":1,"355":1,"356":1,"358":1,"362":1,"365":1,"367":1,"368":1,"370":1,"377":1,"386":1,"388":1},"1":{"352":1,"353":1,"354":1,"355":1,"356":1,"357":2,"358":1,"359":1,"360":1,"361":1,"362":1,"363":2,"364":2,"366":1,"367":1,"368":1,"369":2,"370":2,"371":2,"372":1,"373":1,"374":1,"375":1,"376":1,"377":1,"387":1,"388":1},"2":{"248":1,"252":1,"256":1,"261":1,"262":1,"269":1,"270":1,"311":1,"312":1,"352":1,"353":2,"354":1,"363":1,"364":1,"366":2,"367":1,"368":1,"370":1,"371":1,"373":1,"375":1,"376":1,"377":3,"384":1,"385":4,"389":1}}],["perform",{"2":{"179":1,"364":1}}],["percent",{"2":{"154":1}}],["percentages",{"2":{"20":1,"153":1}}],["poor",{"2":{"367":1}}],["potential",{"2":{"354":1}}],["pots",{"2":{"173":2,"174":2}}],["potsdir",{"2":{"173":2,"174":2}}],["powered",{"2":{"350":1}}],["powerful",{"2":{"248":1,"350":1,"389":1}}],["portal",{"0":{"308":1},"2":{"305":1,"308":3}}],["postinstall",{"2":{"280":1}}],["positioning",{"2":{"67":1}}],["po",{"2":{"173":2,"174":2}}],["p",{"2":{"169":1}}],["please",{"2":{"213":1,"377":1}}],["plaintext",{"2":{"253":1,"258":3,"317":1,"391":1}}],["placed",{"2":{"227":1}}],["placeholders",{"2":{"92":1,"229":1}}],["placeholder",{"2":{"80":1}}],["platforms",{"2":{"222":1,"247":2}}],["playwright",{"2":{"204":1}}],["playground",{"0":{"207":1},"2":{"200":1,"201":1,"207":3,"208":2}}],["plural=",{"2":{"71":1,"77":1,"81":1,"85":1}}],["plural",{"0":{"71":1,"284":1},"2":{"18":1,"149":1,"150":1,"284":1}}],["pluralization",{"0":{"81":1,"85":1,"148":1,"149":1,"150":1,"152":1},"1":{"149":1,"150":1,"151":1,"152":1},"2":{"18":1,"71":1,"77":2,"81":1,"85":1,"93":1,"148":1,"152":1,"284":1}}],["pluralized",{"2":{"18":1,"149":1}}],["pluraltranslations",{"2":{"16":1,"92":1}}],["plugin",{"0":{"7":1,"8":1},"2":{"7":2,"8":2,"9":1,"288":2}}],["plugins",{"0":{"6":1,"10":1},"1":{"7":1,"8":1,"9":1,"10":1},"2":{"6":2,"7":2,"10":2,"373":1,"389":1}}],["p>current",{"2":{"36":1,"130":1}}],["p>",{"2":{"36":3,"130":1,"138":2,"140":2,"146":4,"149":6,"154":4,"157":4,"242":2,"348":2}}],["primarily",{"2":{"244":1}}],["primary",{"0":{"238":1,"300":1,"301":1,"303":1,"306":1},"1":{"239":1,"240":1,"301":1},"2":{"238":1,"240":1,"300":1,"301":1,"302":1,"303":2,"309":2,"381":1}}],["pr",{"2":{"218":2,"219":1}}],["practices",{"0":{"183":1,"232":1,"244":1,"263":1,"309":1,"338":1,"347":1},"1":{"184":1,"185":1,"186":1,"187":1,"233":1,"234":1,"235":1,"264":1,"265":1,"266":1,"267":1}}],["present",{"2":{"313":1,"389":1}}],["preserve",{"2":{"227":1,"228":1}}],["pre",{"0":{"262":1,"376":1},"2":{"262":3,"376":3,"377":2}}],["prerendering",{"2":{"247":3}}],["prerequisites",{"0":{"197":1}}],["prepares",{"2":{"202":1}}],["prepare",{"2":{"200":1,"208":1}}],["prepared",{"2":{"123":1,"219":1}}],["prepack",{"2":{"200":1,"202":1,"208":1}}],["prevents",{"2":{"265":1}}],["preventing",{"2":{"62":1,"178":1}}],["preview",{"2":{"206":1}}],["previewing",{"0":{"206":1}}],["previous",{"2":{"136":1}}],["premier",{"2":{"27":2}}],["prefixed",{"2":{"123":1}}],["prefixes",{"2":{"15":1,"296":1}}],["prefix",{"2":{"87":1,"285":1}}],["preference",{"2":{"349":1}}],["preferences",{"2":{"10":1,"350":1,"383":1}}],["prefer",{"2":{"175":1,"259":1}}],["preferred",{"2":{"32":1,"282":1,"301":1,"346":1,"349":1}}],["pronounced",{"2":{"367":1}}],["proceeding",{"2":{"211":1}}],["processes",{"2":{"371":1}}],["processing",{"2":{"353":1,"371":1}}],["process",{"2":{"1":1,"10":1,"123":1,"159":2,"166":1,"222":1,"225":1,"247":3,"251":1,"262":1,"279":1,"280":1,"312":1,"313":1,"364":1,"376":1,"379":1}}],["products",{"2":{"256":1,"258":10,"287":2}}],["product",{"2":{"243":1}}],["production",{"2":{"169":1,"247":3,"364":1}}],["prod",{"2":{"169":1}}],["prompted",{"2":{"166":1}}],["prompt",{"2":{"166":1}}],["promise",{"2":{"98":1}}],["progress",{"2":{"165":1,"177":1}}],["programmatically",{"0":{"130":1},"2":{"130":1}}],["project",{"0":{"162":1,"192":1,"225":1,"352":1},"1":{"353":1,"354":1},"2":{"159":1,"162":2,"165":1,"188":3,"190":1,"192":1,"200":1,"203":1,"210":1,"211":1,"213":1,"220":1,"222":2,"223":1,"225":2,"227":2,"228":4,"231":1,"235":1,"280":1,"309":1,"315":1,"326":1,"335":1,"336":1,"339":1,"363":1,"377":1}}],["projects",{"0":{"335":1},"2":{"159":1,"269":1,"311":1,"326":1,"335":1,"339":1,"364":1,"367":1,"384":1,"385":1,"389":1}}],["proper",{"2":{"249":1}}],["properly",{"2":{"246":1}}],["properties",{"2":{"88":1,"111":1}}],["property",{"2":{"31":1,"32":1,"113":1,"126":1,"346":1,"347":1,"349":2}}],["prop",{"2":{"47":1,"48":1,"84":1}}],["props",{"0":{"40":1,"54":1,"69":1},"1":{"41":1,"42":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1},"2":{"67":2}}],["providing",{"0":{"34":1},"2":{"10":1,"32":2,"39":1,"48":1,"179":1,"339":1,"341":1,"346":1}}],["provides",{"2":{"53":1,"73":1,"83":1,"127":1,"132":1,"159":1,"222":1,"274":1,"311":1,"366":1}}],["provide",{"2":{"6":1,"31":1,"35":2,"87":1,"147":1,"168":1,"238":1,"243":1,"342":1,"346":1,"364":1}}],["provided",{"2":{"2":2,"4":2,"26":1,"34":1,"83":1,"92":1,"93":1,"149":1,"166":2,"179":1,"346":1}}],["pay",{"2":{"320":1}}],["payload",{"2":{"2":1}}],["panel",{"0":{"307":1},"2":{"305":1,"307":2,"308":1}}],["packaging",{"2":{"202":1}}],["pattern",{"2":{"179":3,"244":1,"286":1,"296":1,"354":1}}],["patterns",{"2":{"179":1}}],["paths",{"0":{"257":1},"1":{"258":1},"2":{"32":1,"41":1,"175":1,"229":2,"231":1,"237":1,"238":1,"257":1,"295":1,"296":2,"346":1,"349":1}}],["path",{"2":{"26":5,"41":1,"70":1,"123":1,"138":1,"179":2,"227":1,"228":1,"229":2,"239":2,"240":2,"242":1,"255":1,"256":1,"259":1,"283":1,"292":1,"295":2,"344":1,"345":1,"348":4,"352":2}}],["papago",{"2":{"167":2}}],["padding",{"2":{"56":1,"59":1,"60":1,"66":3}}],["passing",{"2":{"67":2}}],["pass",{"2":{"35":3,"51":1}}],["passed",{"2":{"27":1}}],["paragraph",{"2":{"125":1}}],["params=",{"2":{"73":1,"144":1}}],["params",{"0":{"73":1},"2":{"16":2,"17":2,"23":1,"27":4,"28":1,"92":1,"284":1}}],["parameters",{"0":{"101":1,"228":1,"344":1},"2":{"15":1,"16":2,"17":2,"18":1,"19":1,"21":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"73":1,"92":1,"101":1,"248":1}}],["part",{"2":{"179":2}}],["parts",{"2":{"80":1,"299":2,"302":2,"312":1}}],["particular",{"2":{"256":1,"302":1,"303":1}}],["particularly",{"2":{"32":1,"237":1,"246":1,"354":1,"371":1,"381":1,"385":1}}],["partial",{"2":{"42":1}}],["page2",{"2":{"295":4,"296":6}}],["pagename",{"2":{"246":1}}],["pages",{"2":{"27":1,"126":1,"178":1,"227":2,"243":2,"252":1,"253":1,"255":1,"256":5,"258":3,"261":2,"264":1,"273":2,"287":1,"290":1,"295":3,"317":1,"341":1,"391":1}}],["page",{"0":{"104":1,"242":1,"256":1,"264":1,"348":1},"2":{"26":2,"44":1,"45":1,"98":1,"104":1,"114":1,"121":1,"125":2,"142":2,"143":1,"146":1,"178":2,"179":1,"238":1,"242":1,"246":1,"251":1,"252":1,"256":1,"261":1,"264":2,"273":2,"289":2,"290":1,"295":6,"296":2,"313":1,"347":1,"354":1,"375":1,"377":3,"381":1,"389":1,"391":1}}],["pairs",{"2":{"2":1,"16":1,"17":1,"35":1,"166":1}}],["drastically",{"2":{"297":1,"371":1}}],["dropdown",{"2":{"53":1,"57":1,"63":2,"67":5,"132":1}}],["duplication",{"2":{"184":1,"233":1,"287":1}}],["duplicated",{"2":{"178":1}}],["duplicate",{"2":{"178":2}}],["duplicates",{"0":{"178":1},"2":{"178":4}}],["during",{"2":{"179":1,"247":4,"262":1,"279":1,"280":1,"291":1,"297":1,"363":1,"364":1,"371":1,"376":1,"385":1}}],["d+",{"2":{"179":1}}],["domain",{"0":{"325":1,"328":1,"331":1,"332":1,"333":1,"334":1,"336":1},"1":{"326":1,"327":1,"328":1,"329":2,"330":2,"331":2,"332":3,"333":3,"334":2,"335":2,"336":2,"337":2,"338":1,"339":1},"2":{"326":2,"327":1,"329":1,"331":3,"332":1,"333":1,"334":1,"335":2,"336":2,"337":2,"338":2,"339":2}}],["domains",{"2":{"147":1,"326":1,"327":1,"337":1,"338":1,"339":1}}],["does",{"2":{"247":1,"294":1}}],["doesn",{"0":{"246":1},"2":{"246":1}}],["downloads",{"0":{"235":1}}],["download",{"2":{"228":1,"231":2,"235":1}}],["downloading",{"0":{"231":1},"2":{"222":1}}],["docs",{"2":{"206":2,"208":3,"215":1,"216":1}}],["documentation",{"0":{"206":1},"2":{"190":1,"192":1,"206":2,"208":3,"216":1,"220":2,"243":1}}],["document",{"2":{"105":1,"107":1,"108":1,"122":1,"125":1,"244":2,"309":2,"347":2}}],["do",{"2":{"35":1,"77":1,"178":1,"212":1}}],["dashboard",{"2":{"104":1}}],["data",{"2":{"27":1,"108":1,"117":1,"175":1,"176":1,"252":1,"256":1,"262":1,"297":1,"375":1,"377":2}}],["dates",{"2":{"22":1,"156":2}}],["datetimeformat",{"2":{"21":1,"156":1}}],["datetimeformatoptions",{"2":{"21":3}}],["date",{"0":{"156":1,"157":1},"1":{"157":1},"2":{"21":7,"22":2,"157":4,"235":1}}],["day",{"2":{"21":1,"157":1}}],["differ",{"2":{"247":1}}],["difference",{"2":{"353":1,"358":3,"361":12}}],["differences",{"0":{"313":1},"2":{"244":1,"313":1}}],["differently",{"2":{"247":1,"295":1}}],["differentiating",{"2":{"108":1}}],["different",{"0":{"243":1,"335":1},"2":{"31":1,"32":1,"51":1,"53":1,"102":1,"150":1,"178":2,"188":1,"237":1,"238":2,"248":1,"249":1,"259":1,"266":1,"278":1,"287":1,"292":1,"299":2,"302":2,"305":1,"326":1,"327":1,"336":1,"339":2,"342":1,"344":1,"346":1,"347":1,"349":1,"383":1}}],["diff",{"0":{"177":1},"2":{"177":2}}],["digit",{"2":{"157":3}}],["digits",{"2":{"20":1}}],["divided",{"2":{"363":1}}],["div",{"2":{"56":1,"72":1,"138":1,"140":1}}],["div>",{"2":{"36":10,"124":2,"130":4,"132":2,"133":2,"135":2,"138":3,"140":3,"146":8,"149":2,"154":2,"157":2,"242":4,"348":2}}],["direct",{"2":{"336":1}}],["directories",{"2":{"273":1}}],["directory",{"0":{"259":1},"2":{"9":1,"162":1,"163":2,"173":2,"174":1,"175":1,"176":1,"177":1,"182":2,"201":1,"207":1,"223":1,"228":2,"252":1,"259":6,"277":2,"290":1,"301":1,"317":1,"322":1}}],["direction",{"0":{"122":1},"2":{"107":1,"275":1,"381":2}}],["directly",{"0":{"155":1,"249":1},"2":{"45":1,"111":1,"248":1,"262":1,"290":1,"341":1,"347":1,"349":1}}],["dir",{"2":{"14":3,"105":1,"107":1,"112":2,"122":1,"125":1,"126":1,"128":3,"272":3,"275":4,"294":3,"301":3,"303":5,"306":2,"307":3,"308":3,"316":2,"330":3,"332":4,"333":4,"381":1,"382":3,"390":3}}],["distribute",{"2":{"339":1}}],["distribution",{"2":{"326":1,"335":1}}],["distinct",{"2":{"238":1,"243":1,"305":1}}],["discrepancies",{"2":{"177":1}}],["display",{"2":{"149":2,"165":2,"242":1,"349":1}}],["displayed",{"2":{"55":1,"125":1}}],["displaying",{"2":{"22":1,"153":1,"156":1}}],["displayname",{"2":{"13":1,"90":1,"128":3}}],["disablewatcher",{"0":{"291":1}}],["disablepagelocales",{"0":{"289":1,"290":1},"2":{"290":1}}],["disables",{"2":{"288":1,"291":2,"308":1}}],["disabled",{"2":{"128":3,"275":3,"332":3,"333":3}}],["disabled=",{"2":{"36":1,"130":1,"146":1}}],["disable",{"0":{"118":1},"2":{"8":1,"62":1,"280":1,"288":1,"289":2,"295":3,"303":2,"307":1,"308":1,"331":1,"332":4,"333":4}}],["decreases",{"2":{"371":1}}],["decimals",{"2":{"20":1}}],["debugging",{"2":{"279":2}}],["debug",{"0":{"279":1}}],["delays",{"2":{"262":1}}],["delivers",{"2":{"269":1}}],["delivering",{"2":{"32":1,"346":1,"349":1}}],["delimiter",{"2":{"175":2,"176":2}}],["dealing",{"2":{"249":1,"258":1}}],["demand",{"2":{"248":1}}],["demonstrate",{"2":{"368":1,"388":1}}],["demonstrates",{"2":{"3":1,"66":1,"124":1,"126":1,"130":1,"137":1}}],["demonstration",{"2":{"354":1}}],["demonstrating",{"2":{"127":1,"146":1,"242":1}}],["deemed",{"2":{"248":1}}],["deepl",{"2":{"166":4,"167":2,"180":2}}],["depth",{"2":{"366":1}}],["deploy",{"0":{"334":1,"337":1},"2":{"334":3}}],["deploying",{"2":{"247":2,"337":1}}],["dependencies",{"0":{"200":1},"2":{"200":1,"216":1}}],["depending",{"2":{"26":1,"152":1,"337":1}}],["developers",{"2":{"341":1,"364":1}}],["development",{"0":{"196":1,"201":1},"1":{"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1},"2":{"147":2,"186":1,"201":2,"208":2,"247":1,"291":1,"313":1,"347":1,"371":1}}],["deviate",{"2":{"244":1}}],["dev",{"2":{"201":1,"207":1,"208":3,"389":1}}],["deutsch",{"2":{"128":1,"131":1,"132":1}}],["detect",{"2":{"301":1}}],["detection",{"2":{"282":1,"283":2,"303":1,"308":1,"332":1,"333":1}}],["detects",{"2":{"46":1,"282":1}}],["determine",{"2":{"363":1}}],["determined",{"2":{"125":1}}],["determines",{"2":{"26":1,"31":1,"122":1,"261":1}}],["detailed",{"0":{"9":1,"362":1},"1":{"363":1,"364":1},"2":{"368":1,"377":1}}],["details",{"0":{"2":1},"2":{"179":1,"225":1,"258":3}}],["despite",{"2":{"384":1,"389":1}}],["describe",{"2":{"218":1}}],["descriptive",{"2":{"184":1,"195":1}}],["description>",{"2":{"214":1}}],["description",{"0":{"353":1},"2":{"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"21":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"41":1,"42":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"89":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"107":1,"108":1,"109":1,"110":1,"112":1,"113":1,"114":1,"141":2,"165":1,"166":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"256":2}}],["designed",{"2":{"87":1,"159":1,"269":1,"363":1,"364":1,"366":1,"384":1,"389":1}}],["design",{"0":{"373":1},"2":{"53":1,"389":1}}],["destination",{"2":{"26":1}}],["de",{"2":{"9":1,"27":4,"33":1,"34":1,"102":1,"104":1,"128":3,"131":1,"132":1,"239":1,"286":2,"295":2,"296":3,"303":3,"308":5,"330":3,"332":3,"333":6,"334":2,"344":1,"345":1,"346":2,"348":1}}],["definitions",{"2":{"205":1}}],["defining",{"0":{"239":1,"301":1},"2":{"32":1,"299":1}}],["definei18nroute",{"2":{"347":1}}],["definenuxtconfig",{"2":{"128":1,"259":1,"272":1,"301":1,"303":2,"306":1,"307":1,"308":1,"316":2,"330":1,"332":1,"333":1,"382":1,"390":1}}],["definenuxtplugin",{"2":{"8":2}}],["define",{"0":{"288":1},"2":{"55":1,"77":1,"150":1,"237":1,"239":1,"242":1,"244":1,"246":1,"288":2,"295":1,"301":1,"341":1,"346":2,"347":1,"348":1}}],["defines",{"2":{"31":1,"41":1,"63":1,"70":1,"227":1,"229":1,"275":1,"292":1,"300":1,"344":1}}],["defined",{"2":{"18":1,"67":1,"152":1,"240":2,"290":1,"296":1,"349":1,"350":1}}],["defaultlocale",{"0":{"276":1},"2":{"128":1,"182":1,"272":1,"294":1,"301":1,"303":2,"306":1,"307":1,"308":1,"316":2,"330":1,"332":1,"333":1,"382":1,"390":1}}],["default=",{"2":{"83":1,"86":1,"142":1}}],["defaultvalue=",{"2":{"74":1}}],["defaultvalue",{"0":{"74":1},"2":{"16":2,"17":2,"18":2,"92":1,"93":1,"284":1}}],["default",{"0":{"48":1,"83":1},"2":{"8":2,"16":1,"17":1,"18":1,"48":1,"55":1,"56":2,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"65":1,"67":1,"72":1,"74":1,"75":1,"76":1,"77":1,"83":1,"92":1,"93":1,"101":1,"107":1,"108":1,"109":1,"110":1,"116":1,"124":1,"128":1,"163":1,"165":1,"166":1,"173":1,"174":1,"175":1,"176":1,"177":2,"179":1,"182":2,"240":2,"259":2,"272":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"285":3,"286":1,"288":1,"289":1,"291":1,"292":3,"293":1,"294":1,"295":1,"300":2,"301":2,"302":1,"303":3,"306":1,"307":1,"308":2,"316":2,"330":1,"332":2,"333":2,"382":1,"390":1}}],["defaults",{"2":{"2":1,"163":1,"308":1}}],["dynamicobject",{"2":{"140":1,"141":1}}],["dynamically",{"2":{"3":1,"6":1,"8":1,"9":1,"10":1,"80":1,"105":1,"122":1,"125":1,"127":1,"140":1,"148":1,"179":1,"229":1}}],["dynamic",{"0":{"80":1,"122":1,"137":1,"138":1,"140":1,"257":1,"258":1,"261":1},"1":{"138":1,"139":1,"140":1,"141":1,"258":1},"2":{"1":1,"2":1,"5":1,"7":1,"10":1,"68":1,"73":1,"101":1,"137":1,"138":2,"139":1,"142":1,"249":1,"257":1,"258":4,"261":1,"313":1,"374":1,"389":1}}],["cpu",{"2":{"353":1,"355":3,"356":3,"357":2,"358":3,"359":3,"360":3,"361":3,"363":2,"364":2,"369":2,"371":2,"387":2}}],["critical",{"2":{"300":1,"385":1,"388":1}}],["creating",{"2":{"299":1,"329":1}}],["creation",{"2":{"249":1,"291":2}}],["created",{"2":{"385":1}}],["create",{"0":{"195":1,"218":1,"329":1,"331":1},"1":{"330":1,"332":1,"333":1},"2":{"193":1,"195":1,"326":1,"327":1,"330":1,"331":1,"332":1,"333":1,"339":1,"346":1,"350":1}}],["creates",{"2":{"44":1,"105":1,"287":1,"313":1}}],["crowdin",{"0":{"221":1,"224":1,"225":1,"227":2,"230":1,"231":1},"1":{"222":1,"223":1,"224":1,"225":1,"226":1,"227":1,"228":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"235":1},"2":{"222":2,"223":2,"224":2,"225":1,"227":3,"228":4,"229":1,"230":2,"231":2,"235":2}}],["cd",{"2":{"186":1,"194":1,"199":1,"200":2,"235":1,"371":1}}],["ci",{"2":{"186":1,"235":1,"371":1}}],["city",{"2":{"146":1,"147":1}}],["csvdir",{"2":{"175":2,"176":2}}],["csv",{"0":{"175":1,"176":1},"2":{"175":7,"176":7}}],["cssproperties",{"2":{"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1}}],["css",{"2":{"42":1}}],["cssstyledeclaration",{"2":{"42":1}}],["cwd",{"2":{"163":1}}],["child",{"0":{"302":1,"303":1,"307":1,"308":1,"331":1},"1":{"303":1,"304":1,"305":1,"306":1,"307":1,"308":1,"332":1,"333":1},"2":{"302":2,"303":2,"309":2,"327":1,"331":1,"332":1,"333":1}}],["choose",{"0":{"270":1}}],["chore",{"2":{"216":1}}],["chosen",{"2":{"166":1,"364":1}}],["challenges",{"2":{"192":1,"367":1}}],["change",{"2":{"220":1,"292":1}}],["changes",{"0":{"209":1,"212":1,"213":1},"1":{"210":1,"211":1,"212":1,"213":1,"214":2,"215":2,"216":2,"217":1,"218":1,"219":1,"220":1},"2":{"26":2,"179":2,"192":1,"207":1,"210":1,"211":1,"212":1,"216":3,"217":1,"218":1,"219":1}}],["changing",{"2":{"10":1}}],["checking",{"0":{"205":1},"2":{"205":1}}],["checkout",{"2":{"195":1}}],["check",{"0":{"178":1},"2":{"178":3,"208":2,"323":1}}],["checked",{"2":{"138":1}}],["checks",{"2":{"94":1,"178":2,"205":1,"286":1}}],["clearly",{"2":{"244":1,"309":1,"347":1,"371":1,"388":1}}],["clear",{"2":{"179":1,"251":1,"375":1}}],["cleanliness",{"2":{"220":1}}],["cleaning",{"2":{"180":1}}],["clean",{"0":{"172":1,"267":1},"2":{"172":2,"180":1,"185":2,"220":1,"234":1,"267":1,"304":1,"335":1}}],["clarity",{"2":{"178":1,"244":1,"265":1,"309":1,"338":1,"347":1}}],["class",{"2":{"47":1}}],["classes",{"2":{"42":1}}],["closely",{"2":{"349":1}}],["close",{"2":{"347":1}}],["closed",{"2":{"63":1}}],["clone",{"0":{"194":1,"199":1},"2":{"194":2,"199":2}}],["cloud",{"2":{"167":1}}],["client",{"2":{"261":1}}],["click",{"2":{"193":1,"218":1}}],["click=",{"2":{"36":1,"130":1,"146":1}}],["cli",{"0":{"158":1,"161":1,"224":1},"1":{"159":1,"160":1,"161":1,"162":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1},"2":{"159":2,"161":2,"181":1,"182":1,"186":1,"188":1,"223":1,"224":2,"235":1}}],["certain",{"2":{"32":1,"202":1,"237":1,"247":1,"295":2,"303":1}}],["cursor",{"2":{"62":1,"66":1}}],["currency",{"2":{"19":2,"20":2,"153":1,"154":3}}],["currently",{"2":{"61":1}}],["current",{"2":{"12":2,"13":1,"19":1,"21":1,"23":1,"24":1,"26":4,"27":1,"28":1,"30":1,"31":1,"32":1,"35":1,"39":1,"42":1,"44":1,"62":1,"87":1,"89":1,"90":1,"94":1,"95":1,"100":1,"103":1,"107":1,"121":1,"122":1,"125":1,"126":1,"135":1,"153":1,"156":1,"163":1,"242":1,"261":1,"294":1,"342":1,"349":1,"354":1,"381":1}}],["customer",{"0":{"308":1},"2":{"305":1}}],["customregexmatcher",{"0":{"286":1}}],["custompluralrule=",{"2":{"77":1,"85":1}}],["custompluralrule",{"0":{"77":1}}],["customdisabledlinkstyle=",{"2":{"62":1,"66":1}}],["customdisabledlinkstyle",{"0":{"62":1}}],["customdropdownstyle=",{"2":{"58":1,"66":1}}],["customdropdownstyle",{"0":{"58":1}}],["customactivelinkstyle=",{"2":{"61":1,"66":1}}],["customactivelinkstyle",{"0":{"61":1}}],["customlinkstyle=",{"2":{"60":1,"66":1}}],["customlinkstyle",{"0":{"60":1}}],["customlabels=",{"2":{"55":1,"66":1}}],["customlabels",{"0":{"55":1}}],["customiconstyle=",{"2":{"63":1,"66":1}}],["customiconstyle",{"0":{"63":1}}],["customitemstyle=",{"2":{"59":1,"66":1}}],["customitemstyle",{"0":{"59":1}}],["customizations",{"2":{"309":1}}],["customizable",{"2":{"53":1,"132":1,"274":1}}],["customizing",{"0":{"259":1},"2":{"20":1,"22":1,"259":1,"327":1}}],["customized",{"2":{"66":1,"83":1,"350":1}}],["customize",{"0":{"117":1},"2":{"19":1,"21":1,"42":1,"47":1,"57":1,"60":1,"67":1,"86":1,"106":1,"259":1,"295":1,"299":1}}],["custombuttonstyle=",{"2":{"57":1,"66":1}}],["custombuttonstyle",{"0":{"57":1}}],["customwrapperstyle=",{"2":{"56":1,"66":1}}],["customwrapperstyle",{"0":{"56":1}}],["custom",{"0":{"49":1,"51":1,"66":1,"85":1,"236":1},"1":{"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1},"2":{"31":2,"32":1,"48":1,"51":1,"55":1,"58":1,"59":1,"61":1,"62":1,"63":1,"66":1,"67":2,"68":1,"77":1,"85":1,"117":1,"119":1,"126":1,"132":1,"147":1,"154":1,"237":1,"239":3,"240":1,"242":2,"243":1,"244":2,"259":1,"277":1,"281":1,"284":1,"286":1,"292":2,"295":6,"296":6,"342":1,"344":2,"345":1,"346":2,"347":2,"348":3,"349":2}}],["causes",{"2":{"385":1}}],["caching",{"0":{"262":1,"297":1,"376":1},"2":{"262":2,"297":2,"376":2,"377":2}}],["cached",{"2":{"247":1,"262":1,"292":3,"376":1}}],["cache",{"2":{"30":2,"297":2}}],["category",{"2":{"243":1,"258":3}}],["catch",{"2":{"8":1}}],["campaigns",{"2":{"243":1}}],["capturing",{"2":{"179":6}}],["capabilities",{"2":{"1":1}}],["case",{"0":{"238":1},"1":{"239":1,"240":1},"2":{"138":1,"179":1,"238":1,"284":2}}],["cases",{"0":{"20":1,"22":1,"32":1,"241":1,"346":1},"1":{"242":1,"243":1},"2":{"32":1,"51":1,"152":1}}],["called",{"2":{"9":1,"27":1,"125":1}}],["canonical",{"2":{"110":1,"114":2,"119":1,"121":2,"125":2,"126":1,"281":1,"381":3}}],["can",{"0":{"249":1},"2":{"5":1,"8":1,"10":2,"21":1,"26":1,"31":1,"32":2,"41":1,"42":1,"47":1,"48":1,"51":1,"67":2,"83":1,"87":1,"111":1,"114":1,"126":1,"136":1,"148":1,"150":1,"152":1,"162":1,"168":1,"179":2,"190":1,"201":1,"203":1,"207":1,"230":1,"231":1,"240":1,"246":2,"247":1,"249":1,"259":1,"262":1,"280":1,"286":1,"292":1,"295":1,"297":1,"299":2,"303":1,"304":1,"311":1,"326":2,"331":1,"335":1,"339":2,"344":1,"353":1,"367":1,"376":1,"383":1}}],["cookie",{"2":{"293":1}}],["cover",{"2":{"212":1,"248":1,"338":1}}],["coding",{"2":{"203":1,"211":1,"220":1}}],["codebase",{"2":{"159":1,"169":1,"192":1,"210":1}}],["codes",{"2":{"9":1,"35":1,"55":1,"123":1,"295":1,"323":1}}],["code",{"0":{"125":1,"203":1,"210":1},"2":{"2":1,"10":1,"12":1,"14":3,"15":1,"35":1,"36":2,"91":2,"128":3,"130":4,"146":4,"182":3,"203":1,"208":1,"210":1,"211":1,"216":2,"220":2,"227":2,"229":2,"247":1,"272":3,"275":5,"294":3,"301":3,"303":5,"306":2,"307":3,"308":3,"316":4,"324":1,"330":3,"332":4,"333":4,"344":2,"382":3,"390":3}}],["copyright",{"2":{"255":1}}],["copy",{"2":{"193":1}}],["corner",{"2":{"193":1}}],["correct",{"2":{"126":1,"228":1,"322":1,"335":1,"336":1,"337":2,"383":1}}],["correctly",{"2":{"18":1,"122":1,"126":1,"320":1,"323":1}}],["corresponding",{"2":{"9":1,"92":1,"166":1,"176":1,"246":1,"261":1,"295":1}}],["could",{"2":{"152":2}}],["counts",{"2":{"148":1}}],["count",{"2":{"18":4,"77":4,"81":1,"85":3,"93":2,"148":1,"149":1,"150":1,"151":4,"152":2,"284":7}}],["color",{"2":{"42":1,"48":3,"49":1,"57":1,"60":1,"61":1,"62":1,"63":1,"66":5}}],["combined",{"2":{"165":1}}],["commerce",{"2":{"243":1,"305":1}}],["comment",{"2":{"8":1}}],["communications",{"2":{"220":1}}],["communication",{"2":{"220":1}}],["community",{"2":{"190":1}}],["commits",{"2":{"213":1}}],["commit",{"0":{"213":1,"214":1,"216":1},"1":{"214":1,"215":1,"216":1},"2":{"213":1,"214":1,"215":1}}],["committing",{"2":{"211":1}}],["committed",{"2":{"187":1}}],["commas",{"2":{"166":1}}],["commands",{"0":{"164":1},"1":{"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1},"2":{"162":1,"186":1,"206":1,"235":1}}],["command",{"0":{"165":1,"166":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1},"1":{"167":1,"168":1},"2":{"159":1,"161":1,"165":1,"166":3,"167":1,"168":1,"175":2,"176":1,"177":1,"178":4,"179":3,"185":1,"201":2,"202":2,"204":1,"207":1,"225":1,"230":2,"231":1,"271":1}}],["commonly",{"2":{"309":1}}],["common",{"0":{"163":1,"208":1,"245":1,"321":1},"1":{"246":1,"247":1,"248":1,"249":1,"322":1,"323":1,"324":1},"2":{"220":1,"240":1,"246":1,"255":1,"329":1,"389":1}}],["comparison",{"0":{"358":1,"361":1,"368":1,"386":1},"1":{"369":1,"370":1,"371":1,"387":1,"388":1},"2":{"368":1}}],["compare",{"2":{"218":1}}],["compares",{"2":{"177":1,"353":1,"366":1}}],["compared",{"2":{"165":1,"171":1,"177":1,"247":1,"269":1}}],["compatibility",{"2":{"318":1}}],["compact",{"2":{"270":1,"384":1,"389":1}}],["company",{"2":{"255":1}}],["completing",{"2":{"320":1}}],["completely",{"2":{"296":1}}],["completed",{"2":{"231":1}}],["complexity",{"2":{"244":1,"309":1,"326":1,"335":1,"339":1,"374":1}}],["complex",{"0":{"152":1},"2":{"146":1,"152":1,"179":1,"258":1,"264":1,"326":1,"339":1,"367":1}}],["comprehensive",{"0":{"146":1},"1":{"147":1},"2":{"364":1}}],["composable",{"0":{"38":1,"87":1,"105":1},"1":{"88":1,"89":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"103":1,"104":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1},"2":{"87":1,"88":1,"105":1,"106":1,"111":1,"121":1,"122":1,"123":2,"124":1,"125":2,"126":1}}],["components",{"2":{"68":1,"80":1,"126":1,"127":1,"202":1,"248":1,"341":2,"347":1,"373":1,"389":1}}],["component",{"0":{"36":1,"39":1,"53":1,"68":1,"132":1,"340":1,"348":1},"1":{"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"86":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1},"2":{"36":1,"39":3,"46":1,"47":1,"51":1,"52":1,"53":2,"67":1,"68":2,"76":1,"80":3,"124":1,"132":1,"133":1,"142":1,"242":1,"249":1,"341":1,"347":2,"348":1,"349":4,"350":2}}],["comes",{"2":{"67":1}}],["com",{"2":{"46":2,"110":1,"114":1,"119":1,"194":1,"199":1,"227":1,"281":1,"334":2}}],["conditions",{"2":{"368":1,"386":1}}],["conditionally",{"2":{"137":1}}],["conditional",{"0":{"84":1}}],["conducted",{"2":{"363":1,"368":1,"386":1}}],["concurrent",{"2":{"363":1}}],["conclusion",{"0":{"339":1}}],["concerns",{"2":{"10":1,"338":1}}],["confusion",{"2":{"184":1,"233":1}}],["confirm",{"2":{"322":1,"337":1}}],["confirms",{"2":{"178":1}}],["configures",{"2":{"342":1}}],["configure",{"0":{"336":1},"2":{"259":1}}],["configured",{"2":{"14":1,"122":1,"181":1,"262":1,"336":1,"376":1}}],["configuring",{"2":{"159":1,"337":1}}],["configurations",{"0":{"319":1},"2":{"168":1,"299":1,"319":2,"327":1,"329":1,"335":1,"338":1}}],["configuration",{"0":{"168":1,"181":1,"226":1,"227":1,"228":1,"229":1,"274":1,"300":1,"301":1,"305":1,"306":1,"316":1,"330":1,"332":1,"333":1,"382":1},"1":{"182":1,"227":1,"228":1,"229":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"301":1,"306":1,"307":1,"308":1},"2":{"7":1,"26":1,"162":1,"181":1,"222":1,"225":1,"227":2,"230":2,"231":1,"240":1,"288":1,"299":1,"300":2,"301":1,"302":1,"303":2,"304":1,"308":1,"309":2,"312":1,"316":2,"322":1,"323":1,"324":1,"327":1,"329":2,"330":1,"331":1,"332":2,"333":2,"334":3,"335":1,"338":2,"374":1,"379":1,"383":1}}],["config",{"0":{"182":1},"2":{"13":1,"90":1,"162":1,"181":1,"259":1,"272":1,"301":1,"303":2,"306":1,"307":2,"308":2,"316":2,"330":2,"332":2,"333":2,"382":1,"390":1}}],["convention",{"2":{"257":1}}],["conventions",{"2":{"210":1,"237":1,"265":1}}],["convenience",{"2":{"87":1}}],["converts",{"2":{"173":1,"258":1}}],["consolidating",{"2":{"354":1}}],["console",{"2":{"8":1,"89":1,"91":1,"92":1,"93":1,"94":1,"112":1,"113":1,"114":1}}],["consumes",{"2":{"385":1}}],["consumption",{"0":{"357":1,"369":1,"387":1},"2":{"270":2,"297":1,"363":1,"364":1,"371":1,"385":1}}],["consulting",{"2":{"147":2}}],["consistent",{"0":{"184":1,"233":1,"265":1},"2":{"184":1,"233":1,"244":1,"257":1,"265":1}}],["consistency",{"2":{"178":1,"213":1,"244":1,"285":1,"309":1,"336":1}}],["consider",{"2":{"15":1,"187":1,"210":1}}],["constrained",{"2":{"364":1}}],["const",{"2":{"8":3,"23":1,"24":1,"27":3,"33":1,"34":1,"36":1,"37":1,"38":2,"77":1,"89":1,"91":1,"92":1,"93":1,"94":1,"97":1,"100":1,"101":1,"103":1,"124":1,"130":1,"133":1,"138":1,"140":1,"146":1,"149":1,"154":1,"157":1,"242":1,"284":2,"346":2,"348":1}}],["contributing",{"2":{"190":1}}],["contribution",{"0":{"189":1,"220":1},"1":{"190":1,"191":1,"192":1,"193":1,"194":1,"195":1},"2":{"215":2}}],["contributions",{"0":{"188":1},"2":{"190":2}}],["contribute",{"2":{"188":1}}],["controls",{"2":{"67":1}}],["controlling",{"0":{"33":1},"2":{"32":1,"346":1}}],["control",{"2":{"31":1,"32":1,"187":1,"237":1,"342":1,"347":1,"354":1}}],["contact",{"2":{"146":5,"147":4,"255":2}}],["contain",{"2":{"255":1,"273":2,"309":1}}],["container",{"2":{"247":1}}],["contains",{"2":{"56":1,"58":1,"80":1,"112":1,"113":1,"114":1}}],["containing",{"2":{"2":1,"41":1,"88":1,"125":1,"163":1,"173":1,"176":1,"344":1}}],["content",{"0":{"51":1,"80":1},"2":{"10":2,"32":2,"51":1,"68":2,"72":1,"80":1,"86":1,"105":1,"113":1,"125":1,"126":1,"142":1,"146":1,"147":1,"243":1,"255":1,"256":2,"264":1,"341":1,"346":2,"347":1,"349":1,"350":1,"379":1,"381":2}}],["contexts",{"0":{"243":1},"2":{"299":1}}],["context",{"0":{"266":1},"2":{"1":1,"2":1,"9":1,"303":1,"348":1}}],["nitro",{"2":{"247":1}}],["npm",{"2":{"161":1,"197":1,"200":3,"206":1,"208":10,"224":1}}],["naming",{"0":{"184":1,"233":1},"2":{"265":1}}],["names",{"2":{"22":1,"140":1,"195":1,"248":1}}],["name",{"2":{"13":1,"15":4,"23":1,"26":2,"28":2,"29":1,"36":1,"41":1,"73":1,"80":1,"90":1,"92":1,"101":1,"133":1,"179":5,"195":1,"217":1,"242":2,"246":3,"248":1,"249":1,"293":1,"295":1,"318":3}}],["named",{"2":{"9":1,"26":4,"258":3}}],["navigating",{"2":{"201":1}}],["navigation",{"0":{"133":1,"134":1},"1":{"134":1,"135":1,"136":1},"2":{"42":1,"242":1,"255":1,"318":1,"320":1}}],["navigational",{"2":{"32":1,"346":1,"349":1}}],["navigate",{"2":{"193":1,"246":1}}],["nav",{"2":{"146":4,"147":1}}],["nav>",{"2":{"146":2}}],["nachricht",{"2":{"27":2}}],["nor",{"2":{"216":1}}],["noreferrer",{"2":{"46":1}}],["node",{"2":{"197":1}}],["nonexistentkey",{"2":{"74":1}}],["none",{"2":{"60":1,"66":1}}],["now",{"2":{"47":1,"248":1,"390":1}}],["noopener",{"2":{"46":1}}],["no",{"0":{"155":1},"2":{"34":1,"48":1,"77":1,"83":1,"149":1,"150":1,"151":1,"152":1,"178":1,"205":1,"212":1,"216":1,"276":1,"284":1,"344":1,"346":1}}],["nouvelles",{"2":{"24":1,"27":2,"29":1}}],["noticeable",{"2":{"385":1}}],["notifications",{"2":{"148":1}}],["note",{"0":{"354":1}}],["notes",{"0":{"126":1}}],["nothing",{"2":{"84":1}}],["not",{"0":{"322":1,"323":1},"2":{"2":1,"16":1,"17":1,"18":1,"26":1,"35":1,"62":1,"66":1,"74":1,"76":1,"77":1,"92":1,"93":1,"166":2,"178":1,"187":1,"212":1,"246":1,"247":4,"248":1,"266":1,"294":1,"295":2,"296":1,"313":1,"324":1,"326":1,"331":1,"339":1,"354":2,"389":1}}],["numeric",{"2":{"21":2,"157":2}}],["numbers",{"2":{"20":1,"153":2,"179":1}}],["numberformat",{"2":{"19":1,"153":1}}],["numberformatoptions",{"2":{"19":3,"20":1}}],["number",{"0":{"153":1,"154":1,"155":2},"1":{"154":1,"155":1},"2":{"16":1,"18":2,"19":4,"20":1,"21":2,"71":2,"73":1,"77":1,"92":2,"93":1,"148":1,"149":2,"153":1,"154":2,"165":1,"284":3,"313":1,"374":1,"389":1}}],["null",{"2":{"8":1,"13":1,"16":1,"27":3,"77":1,"90":1,"92":1}}],["nuxtjs",{"2":{"182":1}}],["nuxtlinkprops",{"2":{"41":1}}],["nuxtlink>",{"2":{"36":1,"242":2,"318":1}}],["nuxtlink",{"0":{"249":1,"318":1},"2":{"36":1,"39":1,"60":1,"242":2,"249":1,"318":2}}],["nuxtapp",{"2":{"8":2,"9":1}}],["nuxt",{"0":{"127":1,"158":1,"161":1,"182":1,"236":1,"248":1,"268":1,"270":1,"298":1,"310":2,"315":1,"318":1,"325":1,"340":1,"378":1,"385":1},"1":{"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"159":1,"160":1,"161":1,"162":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1,"307":1,"308":1,"309":1,"311":2,"312":2,"313":2,"314":2,"315":2,"316":2,"317":2,"318":2,"319":2,"320":2,"321":2,"322":2,"323":2,"324":2,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1,"379":1,"380":1,"381":1,"382":1,"383":1,"386":1,"387":1,"388":1},"2":{"1":1,"4":1,"6":1,"8":1,"32":1,"36":1,"39":1,"53":1,"68":1,"80":3,"83":1,"87":2,"105":1,"111":1,"123":1,"127":2,"128":2,"137":1,"148":1,"159":4,"161":2,"162":3,"165":1,"181":4,"182":1,"186":1,"188":2,"190":1,"193":1,"194":2,"199":3,"201":1,"207":1,"218":1,"220":1,"237":1,"246":1,"248":5,"249":3,"251":2,"252":1,"257":1,"259":3,"261":1,"262":1,"269":2,"270":1,"271":2,"272":2,"274":1,"288":1,"292":1,"297":1,"299":1,"301":1,"303":2,"304":1,"306":1,"307":2,"308":2,"311":5,"312":2,"313":6,"315":3,"316":7,"318":3,"319":2,"326":1,"327":1,"330":2,"332":2,"333":2,"339":1,"341":2,"348":1,"350":1,"363":2,"364":1,"366":3,"367":1,"368":3,"369":2,"370":2,"371":1,"373":1,"374":1,"376":1,"377":1,"379":2,"381":1,"382":2,"384":3,"385":3,"386":1,"387":2,"388":3,"389":1,"390":6}}],["negatively",{"2":{"385":1}}],["netlify",{"2":{"247":2}}],["neither",{"2":{"216":1}}],["nested",{"0":{"146":1,"147":1,"257":1},"1":{"147":1,"258":1},"2":{"257":1,"258":4}}],["necessary",{"2":{"46":1,"162":1,"202":1,"252":1,"256":1,"261":1,"309":1,"323":1,"375":1}}],["next",{"2":{"8":1,"200":1}}],["need",{"2":{"199":1,"223":1,"237":1,"249":1,"262":1,"305":1,"326":1,"335":1,"339":1,"376":2,"377":1,"383":1}}],["needs",{"2":{"5":1,"10":1,"77":1,"147":1,"152":1,"248":1,"256":2,"303":1}}],["needing",{"2":{"5":1}}],["needed",{"0":{"155":1},"2":{"1":1,"10":1,"26":1,"168":1,"182":1,"297":1,"331":1,"344":1}}],["newtranslations",{"2":{"30":2,"95":1}}],["news",{"2":{"23":2,"24":1,"27":4,"29":1}}],["new",{"2":{"1":1,"2":1,"9":1,"21":1,"23":1,"24":1,"26":1,"29":1,"30":3,"46":1,"157":2,"179":1,"190":1,"195":2,"210":1,"216":1,"318":1}}],["ms",{"2":{"359":3,"360":3,"361":3,"370":2,"388":2}}],["mb",{"2":{"355":3,"356":3,"357":2,"358":3,"359":3,"360":3,"361":3,"369":5,"370":2,"387":5,"388":2}}],["mymemory",{"2":{"167":2}}],["mywebsite",{"2":{"119":1}}],["multi",{"0":{"325":1,"328":1},"1":{"326":1,"327":1,"328":1,"329":2,"330":2,"331":2,"332":2,"333":2,"334":2,"335":2,"336":2,"337":2,"338":1,"339":1},"2":{"258":1,"326":1,"339":1}}],["multiple",{"0":{"335":1},"2":{"146":1,"149":1,"167":1,"178":1,"222":1,"255":1,"304":1,"326":1,"335":1,"371":1}}],["multilingual",{"2":{"10":1,"379":2}}],["must",{"2":{"27":1}}],["migrate",{"0":{"312":1}}],["migrating",{"2":{"311":1}}],["migration",{"0":{"310":1,"314":1},"1":{"311":1,"312":1,"313":1,"314":1,"315":2,"316":2,"317":2,"318":2,"319":2,"320":2,"321":1,"322":1,"323":1,"324":1},"2":{"313":1,"320":1}}],["might",{"2":{"238":1,"239":1,"246":1,"247":2,"267":1,"301":1,"302":2,"304":1,"305":1}}],["middleware",{"2":{"247":1}}],["mission",{"2":{"256":1}}],["missing",{"0":{"324":1},"2":{"166":2,"171":1,"177":1,"180":1}}],["miscellaneous",{"2":{"216":1}}],["mind",{"2":{"366":1,"384":1}}],["min",{"2":{"355":2,"356":2,"359":3,"360":3,"361":3}}],["minimizing",{"2":{"364":1,"371":1,"384":1}}],["minimalist",{"0":{"373":1},"2":{"373":1,"389":1}}],["minimal",{"2":{"270":1,"367":1}}],["minimumfractiondigits",{"2":{"154":1}}],["minimum",{"2":{"20":1}}],["minor",{"2":{"244":1}}],["minute",{"2":{"157":1}}],["micro",{"0":{"127":1,"158":1,"161":1,"236":1,"248":1,"268":1,"270":1,"298":1,"310":1,"315":1,"325":1,"340":1,"355":1,"360":1,"361":1,"378":1,"385":1},"1":{"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"159":1,"160":1,"161":1,"162":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1,"307":1,"308":1,"309":1,"311":1,"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1,"379":1,"380":1,"381":1,"382":1,"383":1,"386":1,"387":1,"388":1},"2":{"1":1,"4":1,"39":1,"53":1,"68":1,"87":1,"105":1,"127":1,"128":2,"137":1,"148":1,"159":2,"161":3,"162":1,"165":2,"166":2,"168":1,"169":2,"170":2,"171":2,"172":2,"173":2,"174":2,"175":2,"176":2,"177":2,"178":2,"179":4,"180":6,"181":1,"182":1,"186":1,"188":1,"190":1,"193":1,"194":2,"199":3,"218":1,"220":1,"237":1,"246":1,"248":1,"249":1,"251":2,"252":1,"257":1,"259":2,"261":1,"262":1,"269":1,"270":1,"271":1,"272":1,"274":1,"286":1,"297":1,"299":1,"311":2,"312":1,"313":4,"315":2,"316":3,"319":1,"326":1,"339":1,"341":1,"352":2,"353":2,"354":3,"357":1,"358":1,"363":1,"364":1,"366":2,"367":1,"368":2,"369":1,"370":1,"371":1,"373":1,"374":1,"376":1,"377":1,"379":2,"381":1,"382":1,"384":1,"385":1,"386":1,"387":1,"388":2,"389":1,"390":3}}],["media",{"2":{"381":1}}],["mean",{"2":{"370":4,"388":4}}],["means",{"2":{"297":1}}],["measure",{"2":{"363":1}}],["measures",{"2":{"363":1}}],["merely",{"2":{"354":1}}],["merged",{"2":{"219":1}}],["merge",{"2":{"30":1}}],["merges",{"2":{"2":1,"4":1,"9":1,"30":1,"95":1}}],["mechanism",{"0":{"297":1},"2":{"297":1}}],["memory",{"2":{"269":1,"270":2,"312":1,"353":1,"355":3,"356":3,"357":2,"358":3,"359":3,"360":3,"361":3,"363":3,"364":2,"367":2,"369":3,"370":3,"371":3,"385":4,"387":3,"388":3,"389":1}}],["members",{"2":{"244":1}}],["meet",{"2":{"147":1,"256":1,"331":1}}],["meets",{"2":{"10":1}}],["metrics",{"2":{"371":1}}],["meticulously",{"2":{"286":1}}],["metadata",{"2":{"381":1}}],["metabaseurl",{"0":{"281":1}}],["meta",{"0":{"113":1,"121":1,"278":1},"2":{"105":2,"108":1,"109":1,"111":1,"113":3,"118":1,"125":3,"128":1,"215":1,"272":1,"278":2,"281":2,"301":2,"303":1,"306":1,"307":2,"308":1,"313":1,"316":1,"319":1,"324":1,"330":1,"379":1,"381":2,"382":2,"383":2,"390":1}}],["methodology",{"2":{"363":1,"364":1}}],["method",{"0":{"343":1},"2":{"26":1,"31":1,"248":1,"249":1,"261":1,"327":1,"341":1}}],["methods",{"0":{"11":1},"1":{"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1},"2":{"27":1,"36":1,"87":2,"88":1}}],["message",{"0":{"214":1},"2":{"83":1,"93":2,"149":2,"213":1,"214":1,"215":1,"242":1}}],["messages",{"2":{"16":1,"17":1,"145":1,"148":1}}],["menu",{"2":{"57":1,"255":1}}],["menus",{"2":{"42":1,"255":1,"389":1}}],["monitors",{"2":{"363":1}}],["month",{"2":{"21":1,"157":1}}],["move",{"2":{"317":1}}],["moved",{"2":{"247":1}}],["moving",{"2":{"312":1}}],["most",{"2":{"309":1}}],["mobile",{"2":{"147":1}}],["more",{"0":{"152":1},"2":{"10":1,"52":2,"151":1,"152":1,"179":1,"256":1,"258":1,"312":1,"341":1,"353":1,"354":1,"367":1,"370":1,"371":1,"383":1,"388":1}}],["modular",{"0":{"304":1,"305":1},"1":{"306":1,"307":1,"308":1},"2":{"244":1,"302":1,"304":1,"308":1,"341":1}}],["module",{"0":{"202":1,"274":1},"1":{"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1},"2":{"7":2,"14":1,"159":1,"181":1,"201":1,"202":2,"208":1,"258":1,"261":1,"269":1,"271":1,"272":1,"274":1,"289":1,"290":1,"292":1,"312":1,"318":1,"363":2,"364":1,"368":1,"370":1,"373":1,"375":1,"381":5,"383":1,"384":2,"385":2,"388":1,"389":2,"390":1}}],["modules",{"2":{"6":1,"128":1,"182":1,"272":1,"316":2,"366":1,"374":1,"382":1,"386":1,"389":1,"390":1}}],["mode",{"2":{"169":1,"208":1,"313":1,"389":1}}],["modernmt",{"2":{"167":2}}],["model",{"2":{"166":1}}],["modifies",{"2":{"331":1}}],["modifiers",{"0":{"248":1},"2":{"248":4}}],["modified",{"2":{"179":1}}],["modifications",{"0":{"10":1},"2":{"7":1,"8":1,"179":1}}],["modify",{"2":{"6":1,"10":2,"302":1}}],["modifying",{"0":{"6":1},"1":{"7":1,"8":1,"9":1,"10":1},"2":{"327":1}}],["marketing",{"2":{"243":1}}],["margin",{"2":{"59":1,"66":1}}],["maps",{"2":{"229":1}}],["mapped",{"2":{"227":1}}],["machine",{"2":{"194":1,"197":1,"199":1,"223":1}}],["made",{"2":{"179":1}}],["matching",{"2":{"286":1}}],["match",{"2":{"179":1,"243":1}}],["matcher",{"2":{"286":1}}],["matched",{"2":{"179":2}}],["matches",{"2":{"42":1,"153":1,"179":2,"182":1,"286":1,"322":1}}],["maximizing",{"0":{"377":1}}],["maximum",{"2":{"363":1}}],["max",{"2":{"166":1,"168":1,"355":2,"356":2,"357":4,"358":4,"359":3,"360":3,"361":3,"369":4,"370":2,"387":4,"388":2}}],["makes",{"2":{"266":1}}],["make",{"2":{"161":1,"210":1,"212":1,"219":1,"247":1,"309":1,"377":1}}],["making",{"0":{"209":1},"1":{"210":1,"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1},"2":{"1":1,"10":1,"32":1,"51":1,"177":1,"179":1,"192":1,"213":1,"220":1,"222":1,"230":1,"269":1,"349":1,"364":1,"389":2}}],["manual",{"2":{"383":1}}],["manually",{"2":{"246":1,"383":1}}],["manner",{"2":{"257":1}}],["many",{"2":{"152":2,"165":1,"353":1}}],["managing",{"2":{"88":1,"235":1,"251":1,"265":1,"341":1,"379":1}}],["manages",{"2":{"363":1,"381":1}}],["manageable",{"2":{"234":1}}],["managed",{"2":{"228":1}}],["management",{"2":{"10":1,"87":1,"174":1,"187":1,"312":1,"313":1,"326":1,"339":1,"382":1}}],["manage",{"2":{"8":1,"32":1,"105":1,"159":2,"188":1,"222":1,"266":1,"299":1,"349":1,"350":1}}],["may",{"2":{"137":1,"248":1,"354":1}}],["mainheader",{"2":{"146":1,"147":1}}],["maintaining",{"2":{"244":1,"249":1,"251":1,"336":1}}],["maintainer",{"2":{"219":1,"248":1}}],["maintain",{"2":{"178":2,"228":1,"244":1,"265":1,"304":1,"309":1,"327":1,"335":1,"338":1,"347":1,"389":1}}],["maintainable",{"2":{"10":1,"267":1,"326":1,"339":1,"341":1,"347":1}}],["maintenance",{"0":{"185":1,"234":1},"2":{"10":1,"347":1}}],["main",{"2":{"10":1,"125":1,"147":1,"218":1,"219":1,"305":1,"353":1,"363":2}}],["slowdowns",{"2":{"385":1}}],["slow",{"2":{"367":1,"385":1}}],["slots",{"0":{"80":1,"86":1,"142":1},"1":{"143":1,"144":1,"145":1},"2":{"51":1,"68":1,"80":1,"86":1}}],["slot",{"0":{"51":1,"83":1},"2":{"83":2}}],["slightly",{"2":{"353":1}}],["small",{"2":{"377":1,"389":1}}],["smaller",{"2":{"312":1,"369":1,"371":1,"387":1}}],["smoothly",{"2":{"311":1}}],["smooth",{"2":{"188":1}}],["ssr",{"2":{"247":3,"297":1}}],["s00d",{"2":{"199":1,"218":1}}],["shrinking",{"2":{"384":1}}],["sharing",{"2":{"381":1}}],["shared",{"2":{"255":1,"273":1}}],["share",{"2":{"178":1,"249":1,"287":1}}],["showcase",{"2":{"354":1,"386":1}}],["shows",{"2":{"353":1}}],["show",{"2":{"179":1}}],["showing",{"2":{"165":1,"179":1}}],["should",{"2":{"35":1,"214":1,"227":1,"253":1,"275":1,"283":1,"295":1,"309":1,"338":1}}],["short",{"2":{"22":1,"214":1}}],["sa",{"2":{"272":1,"275":1,"301":1,"382":1,"390":1}}],["sandbox",{"2":{"207":1}}],["sample",{"2":{"207":1}}],["same",{"2":{"136":1,"170":1,"177":1,"178":2,"248":1,"262":1,"297":1,"368":1,"386":1}}],["saved",{"2":{"175":1,"247":1}}],["save",{"2":{"174":1}}],["saves",{"2":{"173":1,"231":1}}],["synchronization",{"2":{"186":1}}],["synchronizing",{"2":{"180":1}}],["synchronizes",{"2":{"170":1}}],["synchronize",{"2":{"159":1}}],["sync",{"0":{"170":1},"2":{"170":2,"180":1}}],["systran",{"2":{"167":2}}],["systems",{"2":{"187":1}}],["system",{"2":{"161":1,"251":1,"297":1,"327":1}}],["social",{"2":{"381":1}}],["so",{"2":{"296":1}}],["source",{"0":{"230":1},"2":{"227":3,"228":2,"229":2,"230":2,"235":1}}],["sources",{"2":{"222":1,"230":1}}],["solution",{"2":{"246":1,"326":1,"339":1,"342":1}}],["solutions",{"0":{"245":1},"1":{"246":1,"247":1,"248":1,"249":1},"2":{"187":1,"269":1,"366":1,"384":1}}],["solid",{"2":{"58":1,"66":1}}],["software",{"2":{"147":1,"175":1}}],["some",{"2":{"137":1,"167":1,"168":1,"246":1,"248":1,"270":1}}],["significant",{"2":{"366":1,"384":1,"385":1}}],["significantly",{"2":{"244":1,"270":1,"297":1,"311":1,"371":1,"374":1,"388":1}}],["signature",{"0":{"343":1}}],["sizes",{"2":{"312":1,"384":1}}],["size",{"2":{"270":2,"367":1,"369":2,"371":2,"377":1,"384":1,"385":1,"387":2,"389":1}}],["since",{"2":{"248":1}}],["single",{"2":{"146":1,"354":1}}],["simulating",{"2":{"370":1}}],["simulates",{"2":{"363":1}}],["simulate",{"2":{"363":1}}],["similarly",{"2":{"333":1}}],["similar",{"2":{"248":1}}],["simplify",{"2":{"347":1}}],["simplifying",{"2":{"335":1}}],["simplified",{"2":{"312":1}}],["simplifies",{"2":{"123":1,"166":1,"251":1,"326":1,"354":1,"373":1,"379":1}}],["simple",{"2":{"41":1,"125":1,"179":2,"242":1,"309":1,"384":1}}],["side",{"2":{"247":1,"261":1,"297":1}}],["silent",{"2":{"163":1}}],["sites",{"2":{"243":2,"379":1}}],["site",{"2":{"123":1,"141":1,"208":3,"299":1,"302":1,"303":1,"305":1,"379":3,"383":1}}],["scratch",{"2":{"248":1}}],["scripts",{"0":{"208":1},"2":{"216":1}}],["script>",{"2":{"36":1,"124":1,"130":1,"133":1,"138":1,"140":1,"146":1,"149":1,"154":1,"157":1,"242":1,"348":1}}],["script",{"2":{"36":1,"124":1,"125":1,"130":1,"133":1,"138":1,"140":1,"146":1,"149":1,"154":1,"157":1,"242":1,"348":1,"352":1,"353":1}}],["scalability",{"2":{"364":1}}],["scalable",{"2":{"10":1,"251":1,"304":1,"326":1,"339":1}}],["scale",{"2":{"270":1,"326":1,"339":1,"354":1,"364":1,"367":1,"389":1}}],["scans",{"2":{"179":1}}],["scope>",{"2":{"214":1}}],["scope",{"2":{"169":1}}],["scenario",{"2":{"136":1}}],["scenarios",{"2":{"68":1,"137":1,"179":1,"344":1,"354":1,"363":1,"364":1}}],["speeding",{"2":{"374":1}}],["speed",{"2":{"367":1,"377":1}}],["special",{"2":{"288":1,"320":1}}],["specify",{"0":{"119":1},"2":{"35":1,"125":1,"163":1,"168":1,"175":1,"176":1,"182":1,"295":1}}],["specifying",{"2":{"32":1}}],["specifies",{"2":{"71":1,"72":1,"108":1,"228":1,"229":1,"277":1,"283":1,"293":1,"294":1}}],["specified",{"2":{"2":2,"9":1,"26":1,"48":1,"96":1,"97":2,"98":1,"103":1,"166":1,"230":1,"231":1,"292":1,"363":1}}],["specifics",{"2":{"309":1}}],["specific",{"0":{"104":1,"256":1,"264":1,"331":1},"1":{"332":1,"333":1},"2":{"2":1,"15":1,"31":3,"32":2,"35":1,"77":1,"80":1,"83":1,"104":1,"116":1,"133":1,"138":1,"152":1,"168":1,"178":2,"179":1,"237":2,"239":1,"240":2,"242":1,"251":1,"252":1,"256":1,"257":1,"264":1,"273":3,"276":1,"289":2,"290":1,"294":1,"295":1,"299":1,"302":1,"307":1,"308":1,"309":1,"313":1,"319":1,"327":1,"329":1,"331":2,"338":2,"341":1,"342":2,"344":1,"346":3,"347":1,"348":3,"349":2,"375":1,"377":1,"389":1,"391":1}}],["spread",{"2":{"363":1}}],["spreadsheets",{"2":{"176":1}}],["spreadsheet",{"2":{"175":1}}],["split",{"2":{"249":1,"284":1,"313":1,"389":1}}],["span",{"2":{"72":1,"79":1,"138":1}}],["span>",{"2":{"51":1,"138":1}}],["span>about",{"2":{"51":1}}],["spanish",{"2":{"26":1,"308":1,"332":1,"333":1}}],["switcher>",{"2":{"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1}}],["switcher",{"0":{"53":1,"132":1},"1":{"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1},"2":{"53":1,"55":1,"56":2,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"65":2,"66":2,"67":2,"127":1,"132":2}}],["switches",{"2":{"25":1,"26":5,"96":1}}],["switchlocale",{"2":{"27":1}}],["switchroute",{"2":{"26":4}}],["switching",{"0":{"102":1,"129":1,"130":1,"131":1},"1":{"130":1,"131":1,"132":1},"2":{"26":1,"53":1,"132":1,"215":1,"283":1}}],["switch",{"2":{"25":1,"26":2,"36":1,"60":1,"102":1,"127":1,"130":2,"146":1}}],["store",{"2":{"259":1,"293":1}}],["stored",{"2":{"137":1,"140":1,"182":1,"228":1,"229":2,"257":1,"258":3,"259":1,"277":1,"297":1,"301":1}}],["step",{"0":{"314":2},"1":{"315":2,"316":2,"317":2,"318":2,"319":2,"320":2},"2":{"222":2,"311":2}}],["steps",{"0":{"328":1},"1":{"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1},"2":{"190":1,"320":1}}],["stubbing",{"2":{"202":1}}],["standout",{"2":{"297":1}}],["standard",{"2":{"296":1}}],["standardized",{"2":{"213":1}}],["standards",{"2":{"203":1,"211":1,"220":1}}],["start",{"2":{"201":2,"207":1,"208":2,"329":1}}],["starting",{"2":{"179":1}}],["started",{"0":{"191":1,"198":1,"268":1},"1":{"192":1,"193":1,"194":1,"195":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1},"2":{"128":1,"190":1,"223":1}}],["static",{"2":{"258":1}}],["statistics",{"2":{"165":2}}],["stats",{"0":{"165":1},"2":{"165":3}}],["state",{"2":{"47":1,"63":1,"179":1}}],["styling",{"0":{"45":1,"135":1,"136":1},"2":{"39":1,"65":1,"67":1}}],["styles",{"0":{"45":1,"47":1,"48":1,"49":1,"66":1,"67":1},"1":{"48":1,"49":1},"2":{"42":1,"45":1,"47":2,"48":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"66":1,"67":10}}],["style",{"2":{"19":1,"45":1,"154":2,"210":1,"216":2}}],["still",{"2":{"35":1}}],["straightforward",{"2":{"309":1}}],["strategy",{"2":{"5":1,"10":1}}],["strong",{"2":{"244":1}}],["strong>",{"2":{"86":2,"142":2}}],["stress",{"0":{"359":1,"360":1},"2":{"353":1,"359":1,"360":1,"361":1,"363":2}}],["streamlining",{"2":{"188":1}}],["streamlined",{"0":{"375":1},"2":{"312":1,"389":1}}],["streamlines",{"2":{"222":1}}],["streamline",{"2":{"159":1}}],["street",{"2":{"147":1}}],["structures",{"2":{"237":1,"346":1}}],["structure",{"0":{"250":1,"252":1,"253":1,"254":1,"258":1,"259":1,"273":1,"290":1,"391":1},"1":{"251":1,"252":1,"253":2,"254":2,"255":3,"256":3,"257":2,"258":2,"259":2,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1},"2":{"146":1,"228":1,"237":1,"240":1,"243":1,"244":1,"249":1,"251":1,"253":1,"257":1,"258":4,"304":1,"335":1,"349":1,"354":1,"379":1}}],["structured",{"2":{"6":1,"10":1,"214":1,"389":1}}],["string>",{"2":{"343":1}}],["strings",{"0":{"249":1},"2":{"152":1,"249":1,"344":1}}],["string",{"2":{"2":1,"3":2,"8":3,"12":1,"13":1,"14":3,"15":3,"16":7,"17":8,"18":5,"19":1,"21":4,"23":2,"24":3,"25":2,"26":7,"27":6,"28":2,"29":3,"30":4,"31":10,"41":2,"55":2,"70":2,"71":1,"72":1,"73":2,"74":1,"77":3,"80":1,"83":1,"84":1,"89":1,"90":1,"92":6,"93":3,"94":1,"96":1,"97":1,"98":2,"101":1,"108":1,"110":1,"112":2,"113":2,"114":2,"179":7,"275":3,"276":1,"277":1,"281":1,"283":1,"284":9,"286":1,"287":2,"292":1,"293":1,"294":1,"295":6,"343":4,"344":1}}],["suitable",{"2":{"364":1}}],["suite",{"2":{"204":1,"208":1}}],["suppose",{"2":{"303":1}}],["supported",{"0":{"167":1},"2":{"167":1,"300":1,"313":1,"389":1}}],["support",{"0":{"188":1,"308":1},"2":{"39":1,"195":1,"303":1,"305":1,"308":5,"313":1}}],["supports",{"2":{"5":1,"52":1,"68":1,"80":1,"167":1,"179":1,"249":1,"262":1,"375":1,"376":1}}],["superior",{"2":{"269":1,"371":1}}],["sure",{"2":{"212":1,"247":1}}],["summary",{"0":{"208":1,"350":1}}],["suggestions",{"2":{"188":1}}],["subjected",{"2":{"363":1}}],["subsequent",{"2":{"262":1,"297":1,"376":1}}],["subsection2",{"2":{"146":4,"147":1}}],["subsection1",{"2":{"146":2,"147":1}}],["subfolders",{"2":{"246":1}}],["submitted",{"2":{"219":1}}],["subdirectories",{"2":{"177":1}}],["such",{"2":{"20":1,"39":1,"63":1,"109":1,"112":1,"148":1,"153":1,"195":1,"216":1,"258":1,"278":1,"292":1,"296":1,"299":1}}],["successful",{"2":{"9":1}}],["suffixes",{"2":{"15":1}}],["src",{"2":{"7":1}}],["sent",{"2":{"363":1}}],["series",{"2":{"363":1,"368":1}}],["serving",{"2":{"337":1}}],["service",{"0":{"168":1},"2":{"166":5,"168":2,"180":2}}],["services",{"0":{"167":1},"2":{"141":1,"146":1,"147":5,"159":1,"166":2,"167":2,"168":1,"187":1,"256":1}}],["served",{"2":{"262":1,"376":1,"383":1}}],["serves",{"2":{"207":1,"248":1,"335":1,"336":1}}],["serve",{"2":{"206":2,"208":2,"327":1,"329":1}}],["server",{"0":{"201":1,"247":1,"370":1,"388":1},"2":{"201":2,"208":1,"247":6,"261":1,"262":1,"269":1,"270":1,"292":1,"297":2,"312":1,"353":1,"363":4,"364":1,"367":1,"370":1,"371":1,"377":1,"384":1,"385":1,"389":1}}],["segment",{"2":{"258":1}}],["segments",{"2":{"257":1}}],["searching",{"2":{"297":1}}],["search",{"2":{"123":1,"126":1,"179":8,"379":3,"381":3,"383":2}}],["seamlessly",{"2":{"67":1,"235":1}}],["seamless",{"2":{"1":1,"26":1,"53":1}}],["sec",{"2":{"370":2,"388":2}}],["secure",{"0":{"187":1},"2":{"187":2}}],["security",{"2":{"46":1}}],["seconds",{"2":{"355":1,"356":1,"357":2,"358":3,"359":1,"360":1,"361":1,"363":2}}],["second",{"2":{"139":1,"151":1,"157":1,"359":1,"360":1,"361":1,"363":2,"370":3,"388":3}}],["section1",{"2":{"146":8,"147":1}}],["section>",{"2":{"146":2}}],["sections",{"0":{"146":1,"147":1},"1":{"147":1},"2":{"299":1,"304":1,"305":1}}],["section",{"2":{"111":1,"125":3,"127":1,"229":1,"302":1,"303":3,"305":1,"308":1}}],["seo",{"0":{"118":1,"121":1,"319":1,"324":1,"378":1,"380":1,"381":1},"1":{"379":1,"380":1,"381":2,"382":2,"383":2},"2":{"105":2,"109":1,"110":1,"113":1,"118":1,"121":1,"123":1,"125":1,"126":3,"215":1,"243":1,"244":1,"278":2,"281":1,"301":1,"313":2,"319":2,"320":1,"324":1,"379":3,"381":1,"382":2,"383":2}}],["several",{"2":{"88":1,"312":1}}],["select",{"2":{"166":1}}],["selecting",{"2":{"62":1}}],["selected",{"2":{"61":1,"276":1,"293":1}}],["see",{"2":{"32":1,"127":1,"346":1}}],["september",{"2":{"21":1,"157":1}}],["separate",{"2":{"247":1,"313":1,"326":1,"335":1,"339":1,"374":1,"389":1}}],["separated",{"2":{"166":1}}],["separately",{"2":{"10":1}}],["separation",{"2":{"10":1,"335":1,"338":1,"375":1}}],["setting",{"0":{"325":1},"1":{"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1},"2":{"222":1,"225":1}}],["settings",{"2":{"22":1,"32":1,"124":1,"148":1,"153":1,"156":1,"282":1,"288":1,"299":2,"300":2,"304":1,"305":1,"307":1,"308":2,"309":2,"329":1,"338":1}}],["setups",{"2":{"367":1}}],["setup",{"0":{"128":1,"160":1,"196":1,"223":1,"272":1,"390":1},"1":{"161":1,"162":1,"163":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"224":1,"225":1,"273":1},"2":{"125":1,"128":1,"225":1,"274":1,"312":1,"326":1,"327":1,"335":1,"339":1,"348":1,"349":1,"354":1}}],["setup>",{"2":{"36":1,"124":1,"130":1,"133":1,"138":1,"140":1,"146":1,"149":1,"154":1,"157":1,"242":1}}],["sets",{"2":{"58":1,"61":1,"276":1,"281":1,"381":1}}],["set",{"0":{"335":1},"2":{"2":1,"4":1,"27":1,"31":1,"119":1,"126":2,"152":1,"162":1,"163":1,"228":1,"229":1,"230":1,"292":2,"295":1,"300":1,"305":1,"323":1,"332":1,"333":1,"342":1,"347":1,"349":1,"382":1}}],["s",{"2":{"1":2,"5":1,"7":1,"8":1,"10":1,"22":1,"32":1,"36":1,"48":1,"53":1,"67":2,"96":1,"107":1,"122":1,"126":1,"128":1,"139":3,"146":1,"150":1,"153":1,"159":1,"188":1,"190":1,"192":2,"203":1,"210":1,"211":1,"220":1,"239":1,"242":1,"244":1,"246":1,"253":1,"262":1,"264":1,"269":1,"270":1,"282":1,"283":1,"288":1,"293":1,"297":1,"301":2,"303":1,"313":1,"316":1,"319":1,"327":1,"335":1,"346":1,"347":1,"348":1,"349":1,"363":1,"367":1,"371":1,"379":1,"384":1,"390":1}}],["again",{"2":{"297":1}}],["avg",{"2":{"361":2}}],["average",{"2":{"355":2,"356":2,"359":3,"360":3,"361":1}}],["avoids",{"2":{"309":1}}],["avoid",{"2":{"184":1,"233":1,"244":1,"264":1,"377":1}}],["available",{"2":{"2":1,"9":1,"14":1,"31":2,"32":1,"91":1,"161":1,"165":1,"230":1,"247":1,"275":1,"294":1,"342":1,"344":2,"381":2}}],["azure",{"2":{"167":2}}],["after",{"2":{"162":1,"179":3,"231":1,"272":1,"316":1,"318":1,"320":1,"337":1,"376":1}}],["amount",{"2":{"256":1}}],["amp",{"0":{"245":1},"1":{"246":1,"247":1,"248":1,"249":1},"2":{"218":1}}],["am",{"2":{"157":1}}],["a>",{"2":{"146":4}}],["ability",{"2":{"353":1,"363":1}}],["above",{"2":{"296":1}}],["about",{"0":{"248":1},"2":{"26":2,"41":1,"42":1,"44":2,"45":2,"49":1,"51":1,"52":3,"97":1,"103":1,"114":1,"123":1,"133":2,"134":2,"135":1,"146":1,"147":2,"149":1,"242":2,"253":1,"255":2,"256":3,"261":2,"273":1,"287":2,"317":1,"379":1,"391":1}}],["able",{"2":{"35":1,"188":1,"235":1}}],["aaa",{"2":{"34":1,"346":1}}],["auto",{"2":{"283":1,"313":1,"389":1}}],["autodetectpath",{"0":{"283":1}}],["autodetectlanguage",{"0":{"282":1},"2":{"301":1,"303":1,"306":1,"308":1,"330":1,"332":1,"333":1}}],["automatic",{"0":{"380":1},"1":{"381":1,"382":1,"383":1},"2":{"215":1,"278":1,"282":1,"291":2,"303":1,"307":1,"308":1,"313":1,"319":1,"332":1,"333":1,"382":1}}],["automatically",{"2":{"39":1,"46":1,"81":1,"121":1,"126":1,"133":1,"166":1,"203":1,"208":1,"246":1,"257":1,"278":1,"282":1,"285":1,"301":2,"379":1,"381":2,"383":1}}],["automate",{"0":{"186":1,"235":1},"2":{"159":1,"186":1,"235":1}}],["authentication",{"2":{"228":1}}],["auf",{"2":{"34":1,"345":1,"346":1,"348":1}}],["au",{"2":{"34":1,"346":1,"348":1}}],["audiences",{"2":{"123":1,"381":1}}],["audience",{"2":{"32":1,"238":1,"350":1}}],["apibaseurl",{"0":{"292":1}}],["apis",{"2":{"166":1}}],["api",{"0":{"187":1},"2":{"27":1,"153":1,"156":1,"166":2,"168":3,"180":2,"187":1,"225":1,"227":3,"228":3,"292":2}}],["appears",{"2":{"178":1,"255":1}}],["apps",{"2":{"147":1}}],["approved",{"2":{"219":1}}],["appropriate",{"2":{"20":1,"25":1,"26":2,"261":1,"282":1,"334":1,"336":1}}],["approach",{"0":{"364":1},"2":{"10":1,"235":1,"244":1,"248":1,"251":1,"309":1,"311":1,"326":1,"339":1,"341":1,"354":1,"374":1}}],["apply",{"2":{"244":1,"309":1}}],["applying",{"2":{"176":1}}],["applicable",{"2":{"338":1}}],["applications",{"2":{"10":1,"244":1,"270":1,"302":1,"326":1,"339":1,"354":2,"364":1,"389":1}}],["application",{"0":{"304":1,"305":1,"320":1,"334":1},"1":{"306":1,"307":1,"308":1},"2":{"1":2,"2":1,"5":3,"6":1,"9":1,"10":3,"32":1,"53":2,"67":1,"87":1,"89":1,"91":1,"96":1,"100":1,"102":1,"110":1,"111":1,"123":1,"126":1,"127":1,"152":1,"207":1,"237":1,"246":1,"255":1,"265":1,"267":1,"271":1,"275":1,"299":2,"300":1,"302":2,"304":1,"309":1,"311":1,"320":1,"323":1,"326":1,"329":1,"334":1,"335":1,"337":1,"339":1,"341":1,"350":1,"364":1,"367":1,"371":2,"385":1,"390":1}}],["applies",{"2":{"59":1,"62":1,"81":1}}],["applied",{"2":{"23":1,"24":1,"28":1,"29":1,"42":1,"46":1,"56":1,"57":1,"60":1,"125":1}}],["apple",{"2":{"149":1,"150":1,"151":1,"152":1,"284":1}}],["apples",{"2":{"18":3,"36":1,"93":3,"149":7,"150":3,"151":5,"152":10,"284":1}}],["applecountmessage",{"2":{"18":1}}],["app",{"2":{"8":1,"201":1,"207":1,"270":1,"273":1,"292":1,"301":1,"390":1}}],["alternative",{"2":{"248":1}}],["alternate",{"2":{"109":1,"110":1,"113":1,"114":1,"119":1,"121":3,"125":3,"126":1,"278":1,"281":1,"381":2}}],["also",{"2":{"179":1,"266":1,"322":1,"326":1,"339":1,"349":1,"370":1}}],["along",{"2":{"178":1}}],["align",{"2":{"243":1}}],["aligns",{"2":{"22":1}}],["alice",{"2":{"16":2,"17":2,"36":1,"144":1}}],["always",{"2":{"17":1,"235":1}}],["all",{"2":{"14":1,"27":1,"87":1,"91":1,"166":1,"170":1,"178":1,"179":5,"180":1,"204":1,"212":1,"220":1,"230":1,"233":1,"240":1,"247":1,"257":1,"262":1,"266":2,"308":1,"320":1,"323":1,"329":1,"338":1,"354":1,"376":1,"381":1}}],["allowing",{"2":{"45":1,"53":1,"206":1,"262":1,"327":1,"350":1,"371":1}}],["allowed",{"2":{"33":1,"34":1,"35":1,"62":1,"66":1,"346":3}}],["allow",{"2":{"10":1,"35":1,"299":1}}],["allows",{"2":{"1":1,"2":1,"32":1,"42":1,"55":1,"56":1,"57":1,"60":1,"68":1,"77":1,"179":2,"237":1,"249":1,"256":1,"259":1,"288":1,"289":1,"295":1,"326":1,"339":1,"341":1,"344":1,"346":1,"349":2,"354":1}}],["await",{"0":{"219":1},"2":{"8":2,"27":2,"98":1,"104":1}}],["attention",{"2":{"320":1}}],["attempt",{"2":{"203":1}}],["attributed",{"2":{"353":1}}],["attribute",{"0":{"117":1},"2":{"107":1,"108":1,"117":1,"275":1}}],["attributes",{"0":{"118":1},"2":{"46":1,"52":1,"105":2,"109":1,"112":1,"116":1,"118":1,"122":1,"123":1,"125":1,"126":3,"379":1,"381":2,"383":1}}],["at",{"2":{"7":1,"192":1,"207":1,"296":1,"350":1,"366":1,"375":1}}],["advantage",{"2":{"319":1}}],["advantages",{"2":{"312":1}}],["advanced",{"0":{"86":1},"2":{"68":1,"179":1}}],["admin",{"0":{"307":1},"2":{"305":1,"307":3,"308":2}}],["adheres",{"2":{"203":1,"211":1}}],["adjust",{"2":{"299":1}}],["adjusting",{"2":{"148":1}}],["adjusts",{"2":{"123":1}}],["adjustments",{"2":{"5":1,"219":1}}],["adapt",{"2":{"326":1,"339":1}}],["adaptive",{"2":{"10":1}}],["adaptable",{"2":{"5":1,"10":1}}],["adopting",{"2":{"10":1}}],["address",{"2":{"146":1,"147":1,"247":1,"248":1,"367":1,"385":1}}],["address>",{"2":{"146":2}}],["added",{"0":{"247":1},"2":{"112":1,"247":1,"248":1,"303":1}}],["adddirattribute",{"0":{"107":1},"2":{"107":1,"124":1}}],["addseoattributes",{"0":{"109":1},"2":{"109":1,"118":1,"121":1,"124":1,"126":1}}],["adds",{"2":{"46":1,"107":1,"280":1,"308":2}}],["adding",{"2":{"4":1,"7":1,"118":1,"210":1,"216":1,"246":1,"248":1}}],["additional",{"0":{"50":1,"82":1,"120":1,"152":1},"1":{"51":1,"52":1,"83":1,"84":1,"85":1,"86":1,"121":1,"122":1,"123":1},"2":{"2":1,"39":1,"95":1,"166":1,"168":1,"302":1,"303":1,"353":1,"379":1}}],["addition",{"2":{"1":1,"288":1}}],["add",{"2":{"3":1,"5":1,"8":1,"182":1,"195":1,"212":1,"215":1,"216":1,"220":1,"272":1,"302":1,"315":1,"332":1,"383":1,"390":1}}],["achieve",{"2":{"137":1,"303":1}}],["activeclass=",{"2":{"135":1}}],["activestyle=",{"2":{"42":1,"45":1,"49":1}}],["activestyle",{"0":{"42":1},"2":{"47":1,"48":2}}],["active",{"0":{"45":1,"48":1,"49":1,"135":1,"136":1},"2":{"39":1,"42":1,"45":1,"47":1,"49":1,"61":1}}],["acts",{"2":{"39":1}}],["accumulate",{"2":{"267":1}}],["accurate",{"2":{"123":1}}],["accidental",{"2":{"178":1}}],["accepts",{"2":{"106":1}}],["accessing",{"2":{"336":1}}],["accessibility",{"0":{"52":1},"2":{"52":1}}],["accessible",{"2":{"32":1,"52":1,"247":2,"257":1,"295":1,"296":1,"379":1}}],["accessed",{"2":{"87":1}}],["access",{"0":{"33":1},"2":{"31":1,"32":1,"35":2,"87":1,"207":1,"342":1,"346":1,"347":1,"348":1}}],["account",{"2":{"193":1}}],["accommodating",{"2":{"26":1}}],["accordingly",{"2":{"152":1}}],["according",{"2":{"2":1,"9":1,"19":1,"21":1,"153":1,"156":1,"210":1,"231":1,"381":1}}],["across",{"2":{"2":1,"159":1,"170":1,"178":2,"179":4,"213":1,"222":1,"233":1,"244":1,"255":1,"265":1,"266":1,"273":1,"285":1,"299":1,"309":1,"326":1,"336":1,"339":1,"363":1,"371":1}}],["arabic",{"2":{"381":1}}],["ar",{"2":{"253":3,"258":3,"272":2,"273":3,"275":2,"290":1,"301":2,"317":3,"382":2,"390":2,"391":3}}],["arises",{"2":{"248":1}}],["aria",{"2":{"52":2}}],["architecture",{"2":{"192":1,"210":1,"373":1}}],["around",{"2":{"39":1,"373":1,"389":1}}],["artillery",{"0":{"359":1,"360":1}}],["artikel",{"2":{"27":2}}],["article",{"2":{"27":4}}],["array",{"2":{"14":2,"35":2,"91":1,"113":1,"114":1,"138":1,"323":1,"344":1}}],["area",{"2":{"388":1}}],["are",{"0":{"260":1},"1":{"261":1,"262":1},"2":{"2":1,"9":2,"31":1,"32":1,"33":1,"34":1,"35":1,"123":2,"125":5,"126":1,"156":1,"165":1,"167":1,"178":2,"179":1,"182":1,"184":1,"187":1,"203":1,"205":1,"212":1,"220":1,"227":1,"228":2,"229":1,"231":1,"233":1,"235":1,"238":1,"247":7,"248":1,"255":1,"256":2,"257":1,"259":1,"261":1,"267":1,"270":1,"273":1,"277":1,"296":1,"301":1,"302":2,"313":3,"317":1,"318":1,"319":1,"320":2,"322":1,"323":1,"324":1,"331":1,"336":1,"344":2,"346":3,"347":1,"349":1,"354":1,"363":1,"364":1,"376":2,"377":1,"381":1,"383":1,"389":2,"391":1}}],["arguments",{"0":{"163":1},"2":{"2":1}}],["analysis",{"0":{"362":1},"1":{"363":1,"364":1}}],["another",{"2":{"80":1}}],["anytown",{"2":{"147":1}}],["anything",{"2":{"76":1}}],["any",{"2":{"15":1,"16":2,"17":2,"179":1,"203":1,"211":1,"212":1,"218":1,"244":1,"255":1,"292":1,"296":1,"319":1,"347":1,"375":1}}],["an",{"0":{"140":1},"2":{"2":1,"8":1,"9":1,"14":1,"35":4,"36":1,"41":1,"87":1,"88":1,"91":1,"106":1,"111":1,"125":1,"138":1,"140":1,"188":1,"227":1,"235":1,"239":1,"301":1,"305":1,"316":1,"344":5,"347":1,"348":1,"363":1,"366":1}}],["and",{"0":{"66":1,"121":1,"122":1,"127":1,"142":1,"156":1,"157":1,"160":1,"188":1,"206":1,"223":1,"235":1,"257":1,"262":1,"321":1,"337":1,"357":1,"361":1,"369":1,"376":1,"387":1},"1":{"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":2,"144":2,"145":2,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":2,"161":1,"162":1,"163":1,"224":1,"225":1,"258":1,"322":1,"323":1,"324":1},"2":{"1":1,"4":1,"5":1,"7":1,"8":1,"9":2,"10":7,"17":1,"22":1,"25":1,"26":3,"27":1,"30":1,"32":2,"39":1,"46":1,"49":1,"52":1,"53":1,"65":1,"66":1,"87":3,"88":1,"92":1,"97":1,"98":1,"104":1,"105":4,"108":1,"109":2,"110":1,"111":1,"112":1,"113":1,"114":1,"118":1,"119":1,"121":1,"122":1,"123":2,"125":8,"126":2,"127":2,"137":1,"138":1,"140":2,"142":1,"148":1,"156":2,"159":3,"162":1,"166":1,"168":2,"169":1,"173":1,"175":1,"177":2,"178":4,"179":9,"181":1,"184":2,"185":1,"186":1,"187":1,"188":1,"190":1,"192":4,"201":1,"202":1,"206":2,"208":1,"210":1,"212":1,"218":1,"220":2,"222":3,"223":1,"225":1,"227":1,"228":1,"231":1,"233":1,"234":2,"235":2,"237":1,"238":2,"242":1,"243":1,"244":1,"246":1,"247":2,"248":4,"251":3,"252":2,"256":2,"257":2,"261":3,"262":2,"264":1,"265":1,"266":1,"267":2,"269":2,"270":2,"273":1,"279":2,"281":1,"282":2,"283":1,"284":1,"295":1,"296":2,"297":1,"299":1,"300":1,"301":1,"304":1,"305":1,"308":2,"309":2,"312":2,"313":3,"317":1,"320":2,"322":1,"323":1,"324":1,"326":4,"332":1,"335":3,"336":1,"337":1,"338":1,"339":4,"341":1,"344":2,"347":3,"348":1,"349":4,"350":4,"353":3,"354":2,"363":3,"364":3,"366":1,"367":3,"368":1,"371":3,"373":2,"374":1,"375":1,"376":4,"377":2,"379":4,"381":4,"383":1,"384":2,"385":5,"389":6,"391":1}}],["a",{"0":{"36":1,"103":1,"119":1,"195":1,"218":1,"242":1,"246":1,"303":1,"304":1,"305":1},"1":{"306":1,"307":1,"308":1},"2":{"2":2,"6":1,"7":1,"8":1,"10":3,"16":2,"17":4,"18":1,"19":1,"21":4,"22":1,"23":1,"26":6,"28":2,"32":1,"35":3,"36":1,"39":2,"41":1,"44":1,"46":1,"47":1,"52":1,"53":1,"59":1,"65":1,"66":1,"67":1,"68":1,"71":1,"77":1,"79":1,"85":1,"87":1,"92":2,"93":2,"94":1,"97":1,"101":2,"102":1,"103":1,"104":1,"105":1,"117":1,"119":1,"124":1,"125":1,"128":1,"132":1,"138":1,"141":1,"146":6,"147":1,"149":2,"152":2,"153":1,"154":2,"157":2,"159":1,"175":2,"176":1,"178":1,"179":5,"188":1,"192":2,"193":1,"195":1,"207":2,"210":1,"212":1,"213":1,"216":4,"219":1,"220":1,"222":1,"238":2,"240":1,"242":1,"244":2,"246":2,"247":2,"248":1,"251":2,"253":1,"256":3,"257":3,"258":7,"259":1,"261":2,"262":1,"266":2,"269":1,"270":1,"274":1,"275":1,"285":1,"286":4,"288":1,"292":1,"294":3,"295":3,"296":1,"297":2,"302":1,"303":3,"304":2,"305":1,"308":2,"311":1,"312":1,"313":1,"324":1,"326":2,"327":2,"329":1,"331":2,"332":1,"333":1,"335":2,"339":2,"341":2,"342":1,"344":2,"347":1,"348":1,"350":2,"354":2,"363":2,"364":3,"366":1,"368":3,"373":1,"374":1,"375":1,"377":1,"381":1,"383":1,"384":1,"385":1,"386":1,"389":1}}],["aspects",{"2":{"363":1,"381":1}}],["assess",{"2":{"363":1}}],["assets",{"0":{"247":1},"2":{"247":4}}],["assign",{"2":{"246":1}}],["associated",{"2":{"140":1}}],["assuming",{"2":{"12":1,"15":1,"18":1}}],["async",{"2":{"3":1,"8":3,"27":1}}],["as",{"2":{"1":1,"10":1,"20":2,"39":2,"63":1,"75":1,"109":1,"112":1,"136":1,"148":1,"153":1,"154":1,"166":1,"182":1,"195":1,"201":1,"204":1,"207":1,"214":1,"216":1,"246":1,"248":1,"258":1,"265":1,"278":1,"292":1,"294":1,"296":1,"299":1,"300":1,"308":2,"320":2,"329":1,"332":1,"333":1,"364":1}}],["tune",{"2":{"274":1}}],["turbo",{"2":{"166":1,"168":1}}],["tied",{"2":{"349":1}}],["tips",{"0":{"220":1,"377":1},"2":{"377":1}}],["title",{"2":{"141":1,"256":2}}],["times",{"2":{"156":2,"269":1,"270":1,"312":1,"353":2,"363":1,"364":1,"367":2,"371":3,"376":1,"377":1,"384":1,"385":1,"389":1}}],["timestamp",{"2":{"21":1}}],["timezone",{"2":{"22":1}}],["time",{"0":{"156":1,"157":1,"357":1,"369":1,"387":1},"1":{"157":1},"2":{"5":1,"22":1,"157":1,"267":1,"297":1,"353":1,"355":1,"356":1,"357":2,"358":1,"359":4,"360":4,"361":4,"363":2,"364":1,"369":2,"370":2,"375":1,"387":2,"388":2}}],["t>",{"2":{"74":1,"76":1,"77":1,"80":1,"83":1,"84":1,"85":1,"86":1,"142":1,"144":1,"248":1,"249":1}}],["t",{"0":{"68":1,"142":1,"143":1,"246":1},"1":{"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"86":1,"143":1,"144":1,"145":1},"2":{"68":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"79":1,"80":3,"81":1,"83":1,"84":1,"85":1,"86":1,"92":2,"127":1,"142":2,"144":1,"246":1,"248":3,"249":3,"284":2,"348":3}}],["tested",{"2":{"370":1,"386":1}}],["test",{"0":{"212":1,"320":1,"351":1,"355":1,"356":1,"359":2,"360":2,"363":1},"1":{"352":1,"353":1,"354":1,"355":1,"356":1,"357":2,"358":1,"359":1,"360":1,"361":1,"362":1,"363":1,"364":1},"2":{"204":2,"207":1,"208":2,"212":1,"216":1,"320":1,"337":1,"352":5,"353":2,"354":1,"359":1,"360":1,"361":1,"363":4,"377":1}}],["tests",{"0":{"204":1},"2":{"204":1,"210":1,"212":2,"216":1,"363":2,"364":1,"368":1,"371":1,"377":1,"386":1}}],["testing",{"2":{"201":1,"363":1,"364":1}}],["tencent",{"2":{"167":2}}],["teams",{"2":{"175":1}}],["team",{"2":{"147":1,"244":1}}],["template",{"2":{"80":1,"83":1,"86":1,"142":1,"248":1,"249":1}}],["template>",{"2":{"36":2,"65":2,"66":2,"80":1,"83":1,"86":1,"124":2,"130":2,"132":2,"133":2,"135":2,"138":2,"140":2,"142":3,"144":2,"146":2,"149":2,"154":2,"157":2,"242":2,"248":3,"249":3,"348":2}}],["texts",{"2":{"266":1,"389":1}}],["textdecoration",{"2":{"60":1,"66":1}}],["text",{"2":{"45":1,"70":1,"72":1,"74":1,"75":1,"79":2,"80":2,"179":4,"248":1,"249":2,"255":1,"275":1,"381":1}}],["tasks",{"2":{"216":1,"383":1}}],["take",{"2":{"192":1,"319":1}}],["takes",{"2":{"2":1}}],["tags",{"0":{"121":1,"324":1},"2":{"105":2,"108":2,"109":1,"113":2,"114":1,"117":1,"118":1,"121":1,"125":4,"126":2,"142":1,"278":2,"281":2,"301":1,"313":1,"320":1,"324":1,"379":1,"381":2,"383":1}}],["tag=",{"2":{"72":1,"142":1}}],["tag",{"0":{"72":1},"2":{"72":1,"79":1,"112":1,"125":2,"215":1,"308":1,"313":1,"319":1,"381":1}}],["table",{"2":{"368":1}}],["tab",{"2":{"46":1}}],["tailored",{"2":{"237":1,"335":1,"349":1,"350":1}}],["tailor",{"2":{"32":1,"243":1}}],["targets",{"2":{"218":1}}],["target",{"2":{"23":1,"24":1,"26":1,"28":2,"29":2,"41":1,"238":1}}],["type>",{"2":{"214":1}}],["types",{"0":{"216":1,"280":1},"2":{"208":1,"280":2}}],["typescriptgloballocaleroutes",{"2":{"295":1}}],["typescriptapibaseurl",{"2":{"292":1}}],["typescriptautodetectpath",{"2":{"283":1}}],["typescriptautodetectlanguage",{"2":{"282":1}}],["typescriptdisablewatcher",{"2":{"291":1}}],["typescriptdisablepagelocales",{"2":{"289":1}}],["typescriptdefine",{"2":{"288":1}}],["typescriptdefaultlocale",{"2":{"276":1}}],["typescriptdebug",{"2":{"279":1}}],["typescriptrouteslocalelinks",{"2":{"287":1}}],["typescriptcustomregexmatcher",{"2":{"286":1}}],["typescriptconst",{"2":{"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"21":1,"28":1,"29":1,"90":1}}],["typescripti18n",{"2":{"294":1}}],["typescriptincludedefaultlocaleroute",{"2":{"285":1}}],["typescriptimport",{"2":{"8":1,"33":1,"34":1,"37":1,"38":1,"346":2}}],["typescripttypes",{"2":{"280":1}}],["typescripttranslationdir",{"2":{"277":1}}],["typescriptmetabaseurl",{"2":{"281":1}}],["typescriptmeta",{"2":{"278":1}}],["typescriptlocales",{"2":{"275":1}}],["typescriptexport",{"2":{"128":1,"259":1,"272":1,"284":1,"301":1,"316":2,"382":1,"390":1}}],["typescript$definei18nroute",{"2":{"31":1,"239":1,"343":1,"345":1}}],["typescript$mergetranslations",{"2":{"30":1}}],["typescript$switchlocale",{"2":{"25":1}}],["typescript",{"2":{"8":1,"23":1,"24":1,"26":4,"27":1,"205":1,"208":1,"303":2,"306":1,"307":1,"308":1,"330":1,"332":1,"333":1}}],["typescriptnuxt",{"2":{"3":1}}],["typecheck",{"2":{"205":1,"208":1}}],["type",{"0":{"205":1},"2":{"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"21":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"41":1,"42":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"89":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"107":1,"108":1,"109":1,"110":1,"112":1,"113":1,"114":1,"205":3,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":2,"285":1,"286":1,"287":1,"288":1,"289":1,"291":1,"292":1,"293":1,"294":1,"295":1}}],["ts",{"2":{"8":2,"259":1,"272":1,"301":1,"303":2,"306":1,"307":1,"308":1,"316":1,"330":2,"332":2,"333":2,"348":1,"352":1,"382":1,"390":1}}],["trim",{"2":{"284":4}}],["triggering",{"2":{"4":1}}],["triggered",{"2":{"2":1,"9":1}}],["troubleshooting",{"0":{"321":1},"1":{"322":1,"323":1,"324":1},"2":{"279":1}}],["traffic",{"2":{"269":1,"311":1,"363":1,"364":1,"367":1,"385":1,"389":1}}],["traditional",{"2":{"269":1,"312":1,"366":1,"368":1,"384":1}}],["transition",{"2":{"311":1}}],["transforms",{"2":{"257":1}}],["translating",{"2":{"180":2}}],["translationdir",{"0":{"277":1},"2":{"128":1,"163":1,"182":2,"259":1,"272":1,"301":1,"303":1,"306":1,"316":1,"322":1,"330":1,"382":1,"390":1}}],["translationobject>>",{"2":{"343":1}}],["translationobject",{"2":{"31":2}}],["translation",{"0":{"10":1,"101":1,"137":1,"139":1,"141":1,"167":1,"186":1,"249":1,"255":1,"256":1,"258":1,"265":1,"317":1,"322":1,"375":1},"1":{"138":1,"139":1,"140":1,"141":1},"2":{"6":1,"7":1,"9":1,"16":4,"17":4,"18":3,"30":3,"68":1,"70":1,"73":1,"74":1,"75":1,"76":1,"77":3,"79":1,"80":3,"83":3,"84":1,"86":3,"87":1,"94":1,"127":1,"137":1,"138":1,"140":1,"142":2,"146":1,"149":1,"150":1,"152":1,"159":4,"163":1,"165":1,"166":5,"167":1,"169":1,"170":1,"171":1,"172":2,"173":1,"174":1,"175":2,"176":2,"177":2,"178":7,"179":6,"180":3,"182":1,"184":1,"185":2,"186":2,"187":1,"195":1,"222":1,"227":2,"229":2,"230":1,"233":1,"234":1,"249":2,"251":1,"252":1,"258":3,"259":3,"261":1,"262":3,"264":1,"265":1,"267":2,"273":1,"277":2,"284":4,"288":1,"289":1,"290":1,"294":1,"297":3,"311":1,"312":1,"313":1,"317":1,"322":2,"354":1,"363":1,"367":1,"368":1,"375":1,"376":2,"377":1,"385":2,"386":1,"389":1}}],["translations",{"0":{"6":1,"34":1,"104":1,"142":1,"231":1,"260":1,"266":1,"267":1,"340":1,"348":1},"1":{"7":1,"8":1,"9":1,"10":1,"143":1,"144":1,"145":1,"261":1,"262":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1},"2":{"1":2,"2":8,"3":2,"4":3,"5":1,"6":1,"7":1,"8":9,"9":6,"10":2,"16":1,"30":2,"31":1,"32":2,"34":1,"35":3,"68":1,"92":1,"95":2,"98":2,"104":1,"142":1,"159":2,"165":2,"166":2,"174":1,"178":3,"179":2,"180":2,"188":1,"222":2,"227":1,"228":3,"229":1,"231":2,"235":2,"242":1,"247":1,"249":2,"251":2,"252":1,"255":1,"256":2,"257":1,"259":1,"261":4,"264":1,"265":1,"266":2,"273":2,"284":1,"287":1,"289":3,"290":1,"292":4,"297":1,"301":1,"313":1,"320":1,"341":3,"342":1,"344":2,"346":3,"347":4,"348":2,"349":3,"350":1,"354":2,"375":1,"376":2,"377":2,"389":1,"391":1}}],["translator",{"2":{"167":1}}],["translate",{"0":{"166":1},"1":{"167":1,"168":1},"2":{"101":1,"166":5,"167":9,"168":2,"180":3}}],["translates",{"2":{"92":1,"93":1,"166":1}}],["translated",{"2":{"72":1,"83":1,"165":1,"229":1}}],["tracks",{"2":{"363":1}}],["track",{"2":{"177":1,"179":1}}],["true",{"0":{"290":1},"2":{"76":2,"84":1,"94":1,"107":2,"109":2,"124":2,"126":1,"128":1,"227":1,"228":1,"272":1,"278":2,"279":1,"280":2,"282":1,"285":1,"288":1,"289":1,"291":1,"301":2,"303":1,"306":2,"316":1,"330":2,"332":3,"333":3,"382":2,"390":1}}],["try",{"2":{"8":1}}],["two",{"2":{"2":1,"151":1,"152":3,"227":2,"229":1,"313":1,"353":1,"363":1,"374":1}}],["thoroughly",{"2":{"320":1,"337":1}}],["than",{"2":{"297":1}}],["thanks",{"2":{"389":1}}],["thank",{"2":{"141":1,"190":1}}],["that",{"2":{"2":1,"5":1,"10":1,"17":1,"22":1,"32":1,"35":1,"39":1,"56":1,"57":1,"58":1,"63":1,"67":2,"68":1,"77":1,"105":1,"122":1,"123":2,"148":2,"153":1,"156":1,"162":1,"178":3,"182":1,"187":1,"190":1,"197":1,"211":1,"216":1,"220":1,"246":2,"247":2,"248":1,"249":1,"252":1,"255":2,"256":2,"257":1,"261":1,"269":1,"288":1,"292":1,"297":1,"299":1,"303":2,"309":1,"319":2,"320":3,"322":2,"323":2,"324":2,"329":1,"331":3,"335":1,"336":2,"337":1,"339":1,"341":1,"344":1,"354":1,"363":1,"364":2,"368":1,"371":1,"374":1,"375":1,"376":1,"379":2,"381":1,"388":1,"389":1,"390":1}}],["third",{"2":{"139":1,"151":1}}],["this",{"0":{"364":1},"2":{"1":1,"7":1,"9":1,"10":1,"26":1,"31":2,"32":1,"33":1,"35":2,"42":1,"44":1,"46":1,"49":1,"53":1,"65":1,"66":1,"79":1,"80":1,"81":1,"108":1,"123":1,"125":2,"126":1,"127":1,"130":1,"136":1,"137":1,"138":2,"139":3,"140":1,"141":1,"148":1,"153":1,"156":1,"159":1,"161":1,"166":1,"175":1,"176":1,"178":1,"179":4,"188":1,"190":1,"201":1,"202":1,"204":1,"205":1,"206":1,"213":1,"222":1,"225":1,"228":3,"230":1,"231":1,"235":1,"237":1,"244":1,"246":3,"247":3,"248":1,"249":1,"251":2,"252":1,"255":1,"256":1,"257":1,"259":2,"261":1,"264":1,"265":1,"266":1,"280":1,"286":1,"292":1,"295":2,"296":1,"297":2,"300":1,"303":2,"308":1,"309":2,"311":1,"326":1,"327":1,"329":1,"335":1,"336":1,"339":1,"341":1,"344":2,"346":2,"349":3,"353":2,"354":2,"366":1,"373":1,"374":1,"375":1,"376":1,"379":1,"381":1}}],["throughput",{"2":{"363":1}}],["through",{"2":{"10":1,"48":1,"67":1,"159":1,"179":1,"192":1,"225":1,"249":1,"251":1,"295":1,"297":1,"379":1}}],["throughout",{"2":{"9":1}}],["then",{"2":{"390":1}}],["there",{"2":{"203":1,"205":1,"212":1,"244":1,"247":1}}],["they",{"2":{"178":1,"179":1,"243":1,"247":1,"308":1,"317":1,"320":1,"336":1,"364":1}}],["their",{"2":{"32":1,"137":1,"140":1,"156":1,"175":1,"177":1,"240":1,"337":1,"338":1,"346":1,"383":1}}],["them",{"2":{"8":1,"138":1,"169":1,"173":1,"179":2,"203":1,"230":1,"231":2,"262":1,"267":1,"337":1,"349":1}}],["these",{"2":{"4":1,"33":1,"36":1,"47":1,"48":1,"67":1,"251":1,"255":1,"256":1,"346":1,"367":2,"371":1,"382":1,"388":1}}],["the",{"0":{"7":1,"8":1,"125":1,"192":1,"193":1,"199":1,"201":1,"202":1,"203":1,"206":1,"207":1,"247":2,"259":1,"301":1,"303":1,"329":1,"332":1,"333":1,"334":1},"1":{"330":1},"2":{"1":2,"2":13,"3":2,"4":7,"5":2,"7":2,"8":2,"9":15,"10":2,"12":2,"13":1,"14":1,"15":6,"16":5,"17":5,"18":7,"19":4,"20":2,"21":4,"22":1,"23":2,"24":1,"25":7,"26":19,"28":5,"29":4,"30":5,"31":2,"32":7,"35":3,"39":3,"41":2,"42":4,"44":2,"45":4,"46":2,"47":3,"48":2,"49":1,"51":2,"52":1,"53":1,"55":1,"56":3,"57":3,"58":3,"60":2,"61":3,"62":2,"63":4,"67":11,"68":1,"70":2,"72":2,"73":1,"74":2,"75":2,"76":2,"77":1,"79":1,"80":6,"81":1,"83":3,"84":2,"86":1,"87":3,"88":1,"89":2,"90":1,"91":1,"92":2,"93":2,"94":1,"95":2,"96":2,"97":2,"98":1,"100":2,"102":1,"103":1,"105":4,"106":1,"107":3,"108":3,"110":1,"111":2,"112":1,"114":1,"117":1,"121":5,"122":3,"123":3,"124":2,"125":8,"126":7,"127":1,"132":1,"133":1,"136":2,"137":1,"139":3,"140":3,"142":1,"143":1,"148":2,"149":5,"150":1,"151":7,"152":3,"153":4,"156":4,"159":3,"161":1,"162":1,"163":2,"165":3,"166":5,"167":2,"168":3,"170":1,"171":1,"173":1,"175":3,"176":4,"177":4,"178":8,"179":29,"181":1,"182":3,"185":1,"188":2,"190":4,"192":2,"193":4,"194":1,"197":1,"199":1,"200":1,"201":7,"202":4,"203":2,"204":3,"205":1,"206":3,"207":4,"208":9,"210":3,"211":2,"212":1,"213":1,"218":4,"219":1,"220":3,"222":1,"223":1,"224":1,"225":1,"227":1,"228":9,"229":7,"230":1,"231":2,"235":2,"237":2,"238":4,"239":2,"240":3,"242":2,"243":1,"244":3,"246":6,"247":13,"248":5,"249":2,"251":1,"252":2,"253":1,"255":1,"256":2,"258":6,"259":4,"261":5,"262":4,"271":2,"272":1,"273":1,"274":1,"275":5,"276":2,"277":1,"279":1,"280":2,"281":1,"282":2,"283":3,"285":2,"288":2,"289":1,"290":4,"291":2,"292":5,"293":3,"294":1,"295":5,"296":3,"297":8,"299":1,"300":4,"301":4,"302":3,"303":7,"305":1,"307":3,"308":7,"309":5,"311":1,"312":2,"313":4,"316":1,"317":1,"318":1,"320":1,"322":4,"323":3,"324":1,"326":1,"329":2,"330":1,"331":2,"332":4,"333":4,"334":4,"335":6,"336":3,"337":5,"338":1,"339":2,"341":1,"342":2,"344":4,"345":1,"346":4,"347":3,"348":3,"349":10,"350":4,"353":5,"354":6,"363":14,"364":5,"366":1,"368":4,"371":3,"373":1,"374":2,"375":2,"376":4,"377":6,"379":2,"381":13,"382":1,"383":5,"384":2,"385":2,"386":2,"388":1,"389":3,"390":1}}],["tostring",{"2":{"284":2}}],["together",{"2":{"266":1}}],["toggle",{"2":{"67":1}}],["toggles",{"2":{"57":1}}],["towards",{"2":{"220":1}}],["tokens",{"2":{"166":1,"168":1}}],["token",{"2":{"166":2,"168":2,"180":2,"225":1,"227":2,"228":3}}],["total",{"2":{"165":1,"369":2,"387":2}}],["tool",{"2":{"159":1}}],["to=",{"2":{"36":1,"41":2,"42":1,"44":1,"45":1,"46":1,"49":1,"51":1,"52":1,"80":1,"133":2,"135":1,"242":2,"248":1,"249":1,"318":3}}],["tolocale",{"2":{"26":2}}],["to",{"0":{"41":1,"217":1,"230":1,"237":1,"247":1,"299":1,"310":1,"328":1},"1":{"311":1,"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1},"2":{"1":2,"2":2,"3":2,"5":1,"6":2,"7":1,"8":2,"9":2,"10":2,"15":2,"16":2,"17":2,"18":1,"19":3,"21":3,"25":5,"26":12,"28":2,"29":2,"30":1,"31":2,"32":3,"35":5,"36":3,"42":2,"44":2,"45":1,"52":1,"55":1,"56":2,"57":2,"59":1,"60":3,"61":1,"62":1,"68":1,"70":1,"72":1,"74":1,"77":1,"80":1,"85":1,"86":1,"87":3,"92":2,"93":1,"96":1,"97":1,"102":1,"103":1,"105":1,"106":1,"107":1,"108":1,"110":1,"112":2,"124":1,"125":3,"126":4,"127":2,"128":1,"130":2,"137":2,"141":1,"143":1,"146":1,"147":2,"150":1,"152":2,"153":1,"156":2,"159":3,"163":1,"165":2,"166":5,"171":1,"173":1,"174":2,"176":1,"177":2,"179":6,"184":1,"185":1,"186":1,"187":1,"188":3,"190":3,"192":2,"193":2,"194":1,"199":2,"201":2,"202":1,"203":3,"204":2,"205":1,"206":2,"207":2,"208":1,"210":1,"211":1,"212":2,"213":1,"217":1,"218":2,"219":1,"222":1,"223":2,"228":2,"229":2,"230":1,"231":2,"233":1,"234":1,"235":4,"237":2,"238":2,"242":2,"243":2,"244":2,"246":4,"247":10,"248":2,"249":2,"251":1,"256":5,"259":3,"261":1,"262":3,"264":2,"266":1,"267":1,"269":2,"271":1,"272":1,"273":1,"274":1,"275":2,"279":1,"280":1,"282":1,"285":2,"287":1,"288":1,"289":2,"292":5,"293":1,"294":1,"295":3,"297":1,"299":1,"302":2,"303":3,"307":1,"308":3,"309":2,"311":3,"313":1,"315":1,"317":1,"318":1,"319":2,"320":2,"326":1,"327":2,"331":1,"334":2,"335":2,"336":2,"337":2,"338":2,"339":2,"341":2,"342":2,"346":4,"347":3,"348":2,"349":5,"350":3,"353":3,"354":1,"363":10,"364":2,"366":1,"367":2,"368":2,"370":1,"371":2,"373":1,"376":1,"377":6,"379":2,"381":1,"382":2,"383":2,"384":1,"385":2,"386":1,"389":2,"390":2}}],["evaluate",{"2":{"353":1,"363":1}}],["every",{"2":{"388":1}}],["everything",{"2":{"202":1,"204":1}}],["even",{"2":{"364":1}}],["event",{"0":{"2":1},"2":{"1":2,"2":2,"3":1,"4":3,"5":1,"8":1,"9":2}}],["events",{"0":{"0":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1}}],["elapsed",{"2":{"369":2,"387":2}}],["eliminates",{"2":{"339":1,"376":1}}],["eliminating",{"2":{"249":1,"326":1}}],["elements",{"2":{"60":1,"255":1}}],["element",{"2":{"57":1,"58":1,"59":1}}],["either",{"2":{"178":1,"275":1}}],["effective",{"2":{"379":1}}],["effectively",{"2":{"159":1,"188":1,"248":1,"251":1}}],["efficiency",{"2":{"270":1,"354":1,"367":1,"386":1,"389":1}}],["efficient",{"0":{"374":1},"2":{"87":1,"235":1,"251":1,"326":1,"371":1,"384":1,"389":1}}],["efficiently",{"2":{"10":1,"261":1,"339":1,"353":1,"363":1,"376":1}}],["efforts",{"2":{"188":1,"235":1}}],["empty",{"2":{"35":1,"76":1,"84":1,"344":1}}],["easy",{"2":{"32":1,"87":1,"126":1,"349":1,"389":1}}],["easier",{"2":{"10":1,"177":1,"222":1,"266":1,"309":1}}],["easily",{"2":{"5":1,"67":1,"190":1,"257":1,"326":1,"339":1}}],["each",{"0":{"334":1},"2":{"32":1,"35":2,"55":1,"59":1,"67":2,"138":1,"165":1,"178":2,"179":1,"214":1,"243":1,"264":1,"275":1,"286":1,"295":1,"296":1,"304":1,"305":1,"308":1,"309":1,"313":1,"324":1,"327":1,"331":1,"334":1,"335":3,"336":1,"337":1,"344":3,"346":1,"363":3,"364":1,"370":1,"374":1,"381":2,"389":1}}],["erster",{"2":{"27":2}}],["errors",{"0":{"323":1},"2":{"205":1,"211":1,"212":1}}],["error",{"2":{"8":4,"9":1,"195":1,"359":1,"360":1,"361":1,"363":1}}],["etc",{"2":{"20":1,"179":1,"286":1,"381":1}}],["essential",{"2":{"251":1,"300":1,"313":1,"354":1,"379":2}}],["es",{"2":{"26":1,"182":3,"294":3,"307":3,"308":1,"330":3,"332":3,"333":3}}],["eslint",{"2":{"8":2}}],["especially",{"2":{"6":1,"10":1,"244":1,"247":1,"249":1,"264":1,"265":1,"267":1,"302":1,"311":1,"363":1,"385":1}}],["execution",{"2":{"353":1}}],["exactly",{"2":{"179":1}}],["examples",{"0":{"127":1,"180":1,"215":1},"1":{"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1},"2":{"26":1,"127":1}}],["example",{"0":{"3":1,"33":1,"34":1,"36":1,"43":1,"64":1,"78":1,"86":1,"99":1,"115":1,"124":1,"131":1,"134":1,"135":1,"136":1,"138":1,"139":1,"140":1,"141":1,"143":1,"145":1,"146":1,"147":1,"149":1,"150":1,"152":1,"154":1,"155":1,"157":1,"182":1,"239":1,"242":1,"301":1,"303":1,"305":1,"332":1,"333":1,"345":1,"348":1},"1":{"44":1,"45":1,"46":1,"65":1,"66":1,"79":1,"80":1,"81":1,"100":1,"101":1,"102":1,"103":1,"104":1,"116":1,"117":1,"118":1,"119":1,"125":1,"126":1,"147":1,"306":1,"307":1,"308":1},"2":{"3":1,"4":1,"8":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"21":1,"23":1,"24":1,"25":1,"27":1,"28":1,"29":1,"30":1,"31":1,"36":1,"37":1,"38":1,"41":1,"42":1,"44":1,"46":3,"49":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"66":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"80":1,"89":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"107":1,"108":1,"109":1,"110":2,"112":1,"113":1,"114":2,"124":1,"125":1,"126":1,"130":1,"136":1,"137":1,"138":1,"140":1,"149":1,"165":1,"166":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":4,"227":1,"228":1,"229":1,"238":1,"239":1,"248":1,"249":3,"253":1,"255":1,"256":2,"258":3,"259":1,"261":1,"266":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":2,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"291":1,"292":1,"294":1,"295":1,"296":1,"301":1,"308":1,"316":1,"317":1,"334":3,"347":1,"348":1,"354":2}}],["existence",{"2":{"138":1}}],["exists",{"2":{"94":3}}],["existing",{"2":{"2":1,"4":1,"30":1,"95":1,"166":1,"180":1,"192":1,"210":1,"212":1,"316":1}}],["extra",{"2":{"171":1}}],["extraction",{"2":{"186":1}}],["extracting",{"2":{"15":1,"180":1}}],["extracts",{"2":{"169":1}}],["extracted",{"2":{"126":1}}],["extract",{"0":{"169":1},"2":{"15":1,"159":1,"169":2,"180":1}}],["extending",{"0":{"303":1},"2":{"303":1,"327":1}}],["extended",{"2":{"299":1,"303":1}}],["extends",{"2":{"92":1,"303":1,"307":1,"308":1,"332":1,"333":1}}],["extend",{"2":{"7":2,"10":1,"152":1,"302":1,"309":1,"389":1}}],["external",{"0":{"46":1},"2":{"6":1,"39":1,"46":1,"159":1,"166":1,"174":1}}],["explains",{"2":{"379":1}}],["explain",{"2":{"251":1}}],["explanation",{"0":{"4":1,"9":1,"35":1,"125":1,"151":1,"254":1,"349":1,"363":1},"1":{"255":1,"256":1},"2":{"247":1}}],["expression",{"2":{"179":1}}],["expressions",{"2":{"179":1}}],["expand",{"2":{"10":1}}],["experimented",{"2":{"248":1}}],["experience",{"2":{"5":1,"10":1,"32":2,"52":1,"188":1,"238":1,"243":1,"244":1,"336":1,"346":1,"349":1,"350":1,"371":1,"379":1,"381":1,"383":2}}],["expert",{"2":{"147":1}}],["expertise",{"2":{"147":1}}],["expected",{"2":{"9":1,"204":1,"246":1,"320":1}}],["expect",{"2":{"8":1}}],["exported",{"2":{"175":1}}],["exports",{"2":{"174":1,"175":1}}],["export",{"0":{"174":1,"175":1},"2":{"8":1,"174":2,"175":3,"303":2,"306":1,"307":1,"308":1,"330":1,"332":1,"333":1}}],["e",{"2":{"2":1,"9":1,"23":1,"24":1,"28":1,"29":1,"89":1,"91":1,"92":1,"93":1,"94":1,"123":1,"152":1,"166":2,"179":1,"243":1,"255":1,"256":1,"275":2,"286":1,"305":1,"344":1,"353":1,"381":1,"389":1}}],["endpoints",{"2":{"363":1}}],["endpoint",{"2":{"292":1}}],["env",{"2":{"292":1}}],["environments",{"2":{"311":1,"364":2,"367":1,"385":1}}],["environment",{"2":{"187":1,"201":1,"207":1,"208":1,"247":2}}],["encounter",{"2":{"188":1,"280":1,"364":1}}],["encapsulate",{"2":{"10":1}}],["enter",{"2":{"166":1}}],["entities",{"2":{"148":1}}],["entirely",{"2":{"248":1,"295":2,"354":1}}],["entire",{"2":{"5":1,"83":1,"255":1,"273":1,"300":1,"301":1}}],["engine",{"2":{"126":1,"379":1,"381":1,"383":1}}],["engines",{"2":{"123":1,"379":2,"381":2,"383":1}}],["english",{"2":{"4":1,"12":1,"13":1,"55":1,"66":1,"90":1,"128":1,"131":1,"132":1,"238":1,"275":1,"294":1,"296":2,"332":1,"333":1,"381":1}}],["enable",{"2":{"179":2,"278":1,"279":1,"282":1,"332":1,"377":1,"382":1}}],["enabled",{"2":{"121":1,"290":1,"324":1,"381":1}}],["enables",{"2":{"1":1,"75":1,"279":1,"288":1,"349":1,"382":1}}],["enabling",{"2":{"68":1,"98":1,"371":1,"383":1}}],["ensuring",{"2":{"32":1,"67":1,"122":1,"123":2,"170":1,"188":1,"202":1,"235":2,"238":1,"243":1,"364":1,"376":1,"379":1,"381":1}}],["ensures",{"2":{"178":1,"190":1,"246":1,"252":1,"257":1,"261":1,"335":1,"339":1,"375":1}}],["ensure",{"2":{"5":1,"52":1,"126":1,"162":1,"178":1,"181":1,"182":1,"184":1,"187":1,"197":1,"203":1,"204":1,"205":1,"211":1,"212":1,"213":1,"218":1,"220":1,"228":1,"233":1,"244":1,"247":1,"285":1,"309":1,"317":1,"318":1,"319":1,"320":2,"322":1,"336":2,"337":1,"346":1,"363":1,"377":1,"382":1}}],["enhance",{"2":{"262":1,"379":1}}],["enhances",{"2":{"256":1}}],["enhancements",{"0":{"52":1}}],["enhanced",{"2":{"10":1}}],["enhancing",{"2":{"1":1,"5":1,"32":1,"238":1,"336":1,"346":1,"349":1,"375":1}}],["en",{"0":{"139":1,"141":1},"2":{"2":1,"9":1,"12":1,"14":2,"19":1,"21":1,"23":1,"24":1,"27":3,"29":1,"31":1,"33":1,"34":1,"55":1,"66":1,"89":1,"91":2,"112":1,"113":1,"123":1,"128":3,"131":1,"132":1,"154":2,"157":2,"182":4,"227":2,"253":3,"255":2,"256":3,"258":3,"261":2,"272":3,"273":3,"275":4,"276":1,"286":1,"290":1,"294":4,"295":2,"296":4,"301":4,"303":7,"306":4,"307":4,"308":3,"316":6,"317":3,"330":3,"332":2,"333":2,"344":1,"345":1,"346":2,"348":1,"382":3,"390":3,"391":3}}],["imagine",{"2":{"305":1}}],["impacting",{"2":{"385":1}}],["impacts",{"2":{"244":1}}],["impact",{"2":{"216":1,"270":1,"363":1,"367":1}}],["improvement",{"2":{"366":1}}],["improvements",{"2":{"188":1,"190":1,"368":1,"384":1}}],["improves",{"2":{"266":1}}],["improved",{"2":{"243":1,"312":1,"373":1,"383":1}}],["improve",{"2":{"105":1,"126":1,"286":1,"311":1,"377":1}}],["improving",{"2":{"10":1,"376":1,"381":1}}],["important",{"0":{"354":1},"2":{"264":1}}],["imported",{"2":{"176":1}}],["imports",{"2":{"9":1,"33":1,"34":1,"36":1,"37":1,"38":1,"130":1,"133":1,"138":1,"140":1,"146":1,"149":1,"154":1,"157":1,"176":1,"242":1,"346":2,"348":1}}],["import",{"0":{"173":1,"176":1},"2":{"8":1,"36":1,"130":1,"133":1,"138":1,"140":1,"146":1,"149":1,"154":1,"157":1,"173":2,"176":3,"242":1,"348":1}}],["implements",{"2":{"376":1}}],["implement",{"0":{"328":1},"1":{"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1}}],["implementations",{"2":{"353":1}}],["implementation",{"2":{"8":1,"353":1}}],["implementing",{"0":{"8":1}}],["ignored",{"2":{"290":1}}],["i",{"0":{"249":1}}],["ibm",{"2":{"167":2}}],["i>",{"2":{"142":2}}],["icon",{"2":{"63":2,"67":2}}],["idea",{"2":{"192":1}}],["ideal",{"2":{"179":1,"269":1,"341":1,"389":1}}],["identical",{"2":{"178":1,"368":1,"386":1}}],["identifies",{"2":{"177":1,"228":1}}],["identifier",{"0":{"117":1},"2":{"117":1,"275":1}}],["identifierattribute",{"0":{"108":1},"2":{"108":1,"117":1,"124":1}}],["identify",{"2":{"108":1}}],["id",{"2":{"27":10,"108":1,"113":1,"114":1,"124":1,"225":1,"227":2,"228":2,"258":11,"287":1}}],["iterates",{"2":{"138":1}}],["iterate",{"2":{"137":1,"140":1}}],["item3",{"2":{"146":1,"147":1}}],["item2",{"2":{"146":1,"147":1}}],["item1",{"2":{"146":1,"147":1}}],["itemcount",{"2":{"71":1,"77":1,"81":2,"85":1}}],["item",{"2":{"67":2,"85":1}}],["items`",{"2":{"85":1}}],["items",{"2":{"67":1,"71":1,"77":2,"81":1,"85":1,"148":1}}],["its",{"2":{"106":1,"138":2,"295":1,"297":1,"304":1,"308":1,"353":1,"384":1,"389":1}}],["itself",{"2":{"80":1}}],["it",{"2":{"7":1,"26":2,"32":1,"39":1,"41":1,"42":1,"62":1,"68":1,"87":1,"105":1,"126":1,"159":1,"165":1,"166":1,"177":1,"178":3,"179":4,"190":1,"192":1,"206":2,"208":1,"210":1,"222":1,"223":1,"246":1,"248":1,"262":1,"266":1,"269":2,"292":1,"295":1,"296":1,"300":1,"309":2,"313":1,"318":1,"327":1,"349":1,"350":1,"354":1,"364":1,"366":1,"384":1,"385":1,"389":2,"390":2}}],["issue",{"2":{"188":1,"215":1,"246":1}}],["issues",{"0":{"245":1,"321":1},"1":{"246":1,"247":1,"248":1,"249":1,"322":1,"323":1,"324":1},"2":{"188":1,"192":1,"203":1,"208":2,"218":1,"246":1,"247":1,"248":1,"265":1,"280":1,"367":1,"385":2}}],["isolate",{"2":{"338":1}}],["isocode",{"2":{"286":1}}],["iso",{"2":{"14":3,"91":2,"128":3,"182":3,"272":3,"275":5,"294":3,"301":3,"303":5,"306":2,"307":3,"308":3,"316":4,"324":1,"330":3,"332":4,"333":4,"382":3,"390":3}}],["is",{"0":{"247":1,"248":1},"2":{"4":1,"6":1,"9":3,"10":1,"12":1,"15":1,"16":1,"17":1,"18":2,"26":1,"34":1,"35":2,"39":1,"45":1,"48":1,"53":1,"63":1,"68":1,"74":1,"76":1,"80":1,"83":1,"84":1,"86":1,"87":1,"92":1,"93":1,"105":1,"108":1,"121":1,"122":1,"123":1,"125":2,"126":2,"138":1,"139":3,"141":1,"142":1,"148":1,"151":3,"153":1,"156":1,"159":1,"162":1,"165":1,"175":1,"176":1,"178":1,"179":3,"182":1,"202":1,"204":1,"219":1,"227":1,"230":1,"237":1,"238":1,"246":2,"247":3,"248":3,"251":1,"252":1,"255":1,"262":1,"264":1,"269":1,"276":1,"290":1,"292":1,"297":3,"300":2,"324":1,"336":1,"337":2,"341":2,"344":5,"346":1,"348":1,"349":1,"353":2,"354":4,"363":5,"364":2,"366":1,"368":1,"371":1,"373":1,"375":1,"379":2,"381":2,"382":1,"384":1,"389":2}}],["if=",{"2":{"138":1}}],["if",{"0":{"246":1},"2":{"2":1,"7":1,"8":1,"16":1,"17":1,"18":1,"26":2,"27":1,"35":4,"48":1,"74":1,"76":2,"77":2,"83":1,"84":1,"92":1,"93":1,"94":1,"107":1,"109":1,"123":1,"126":1,"152":1,"166":2,"168":1,"178":2,"179":1,"188":1,"203":1,"207":1,"210":1,"212":1,"220":1,"248":1,"259":1,"267":1,"275":1,"276":1,"280":1,"284":3,"286":1,"292":1,"313":1,"318":1,"324":1,"344":1,"389":1}}],["involving",{"2":{"367":1}}],["involve",{"2":{"148":1}}],["inherited",{"2":{"303":2,"307":2,"308":2}}],["inherit",{"2":{"303":1,"307":1,"308":2,"332":1,"333":1}}],["inherits",{"2":{"48":1}}],["initial",{"2":{"376":1}}],["initialize",{"2":{"223":1,"225":1}}],["initializing",{"0":{"162":1,"225":1}}],["init",{"2":{"225":1}}],["individual",{"2":{"256":1,"341":1}}],["indicating",{"2":{"149":1}}],["indicator",{"2":{"67":1}}],["indicates",{"2":{"63":1,"275":1}}],["indicate",{"2":{"61":1,"371":1}}],["indexing",{"2":{"126":1,"381":1}}],["index",{"2":{"15":2,"28":2,"36":2,"41":1,"80":1,"133":1,"242":2,"248":1,"253":1,"256":2,"261":2,"273":1,"317":1,"318":3,"383":1,"391":1}}],["inspired",{"0":{"248":1},"2":{"248":1}}],["inspecting",{"2":{"108":1}}],["instance",{"2":{"302":1,"335":1}}],["installed",{"2":{"181":1,"197":1}}],["install",{"0":{"200":1,"315":1},"2":{"161":2,"200":2,"223":1,"224":2,"271":2,"315":1,"390":2}}],["installation",{"0":{"160":1,"223":1,"271":1},"1":{"161":1,"162":1,"163":1,"224":1,"225":1},"2":{"272":1}}],["installing",{"0":{"161":1,"224":1},"2":{"159":1,"162":1}}],["instruct",{"2":{"259":1}}],["instead",{"2":{"47":1,"55":1,"259":1,"292":1,"296":1}}],["insert",{"2":{"80":1,"179":1}}],["insertion",{"2":{"68":1}}],["inside",{"2":{"27":1,"51":1,"67":1,"249":1}}],["inline",{"0":{"45":1,"66":1},"2":{"42":1,"45":1,"47":1,"66":1,"67":1}}],["input",{"2":{"26":1}}],["inform",{"2":{"379":1}}],["information",{"0":{"352":1},"1":{"353":1,"354":1},"2":{"41":1,"279":2}}],["info",{"2":{"26":1,"163":1}}],["increased",{"2":{"367":1}}],["include",{"2":{"377":1,"385":1}}],["includedefaultlocaleroute",{"0":{"285":1}}],["included",{"2":{"125":1}}],["includes",{"2":{"109":1,"275":1,"323":1,"329":1}}],["including",{"2":{"22":1,"113":1,"125":1,"175":1,"177":1,"178":1,"179":1,"222":1,"225":1,"300":1}}],["incorporation",{"2":{"2":1}}],["intuitive",{"2":{"238":1}}],["intact",{"2":{"179":1}}],["introduction",{"0":{"159":1,"190":1,"222":1,"237":1,"251":1,"299":1,"311":1,"326":1,"366":1,"379":1,"384":1}}],["introduced",{"2":{"13":1,"15":1,"26":1,"90":1}}],["intro",{"2":{"146":1,"147":1}}],["intl",{"2":{"19":4,"20":1,"21":4,"153":1,"156":1}}],["into",{"2":{"2":2,"4":2,"8":1,"9":2,"16":1,"17":1,"30":1,"67":1,"80":1,"95":1,"126":1,"175":1,"179":1,"186":1,"190":1,"219":1,"222":1,"235":2,"252":1,"257":1,"258":1,"273":1,"313":1,"354":1,"363":1,"391":1}}],["intelligent",{"2":{"297":1}}],["intelligently",{"2":{"123":1}}],["integrating",{"2":{"222":1}}],["integration",{"0":{"221":1},"1":{"222":1,"223":1,"224":1,"225":1,"226":1,"227":1,"228":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"235":1},"2":{"53":1,"313":1}}],["integrated",{"2":{"190":1}}],["integrates",{"2":{"67":1}}],["integrate",{"2":{"1":1,"126":1,"186":1,"235":2}}],["intended",{"2":{"26":1,"320":1,"354":1}}],["internal",{"2":{"373":1}}],["international",{"2":{"122":1,"123":1}}],["internationalization",{"2":{"1":1,"10":1,"87":1,"88":1,"159":1,"188":1,"235":1,"251":1,"269":1,"274":1,"353":1,"366":1,"384":1}}],["interpretation",{"0":{"371":1}}],["interpolation",{"0":{"142":1,"144":1,"145":1},"1":{"143":1,"144":1,"145":1}}],["interpolating",{"2":{"73":1}}],["interpolate",{"2":{"16":1,"17":1,"68":1}}],["interpolates",{"2":{"16":1,"17":1}}],["interest",{"2":{"190":1}}],["interface",{"2":{"2":1,"53":1,"308":1}}],["in",{"0":{"36":1,"162":1,"225":1,"236":1,"239":1,"242":1,"243":1,"249":1,"298":1,"303":1,"304":1,"305":1,"340":1},"1":{"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":2,"307":2,"308":2,"309":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1},"2":{"1":1,"6":1,"8":2,"9":1,"14":1,"19":1,"20":1,"21":1,"22":1,"27":1,"32":4,"35":1,"36":2,"39":1,"42":1,"46":1,"48":1,"49":1,"53":2,"67":1,"68":1,"70":1,"73":1,"80":2,"87":1,"91":1,"105":1,"111":1,"125":2,"127":1,"130":1,"136":1,"137":1,"138":2,"140":2,"146":1,"147":1,"148":2,"149":1,"150":1,"153":1,"154":2,"156":1,"157":2,"159":1,"162":2,"165":1,"166":1,"169":1,"173":1,"175":1,"176":1,"177":1,"178":2,"179":5,"181":1,"188":2,"190":1,"193":2,"201":1,"206":1,"207":1,"208":1,"210":1,"218":1,"220":1,"225":1,"228":3,"229":2,"230":1,"231":2,"237":1,"239":1,"240":1,"244":2,"246":1,"247":5,"248":2,"249":1,"257":2,"258":3,"259":3,"271":1,"275":2,"284":1,"286":1,"288":1,"290":2,"296":2,"297":1,"299":1,"301":1,"302":1,"303":3,"304":1,"307":1,"308":2,"309":3,"311":1,"313":3,"316":1,"317":1,"322":2,"323":2,"324":1,"326":1,"327":1,"332":1,"333":1,"338":1,"339":1,"341":1,"346":1,"349":2,"354":3,"364":2,"366":2,"367":1,"377":1,"381":1,"382":1,"384":1,"385":3,"388":1,"389":1,"390":2}}],["i18nlink",{"0":{"249":1},"2":{"249":1}}],["i18n",{"0":{"1":1,"39":1,"53":1,"68":1,"127":1,"132":1,"133":1,"142":1,"143":1,"158":1,"161":1,"236":1,"248":2,"268":1,"270":1,"298":1,"310":2,"315":1,"325":1,"340":1,"355":1,"356":1,"359":1,"360":1,"361":2,"378":1,"385":1},"1":{"2":1,"3":1,"4":1,"5":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":1,"86":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":2,"135":2,"136":2,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":2,"144":2,"145":2,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"159":1,"160":1,"161":1,"162":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"269":1,"270":1,"271":1,"272":1,"273":1,"274":1,"275":1,"276":1,"277":1,"278":1,"279":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1,"307":1,"308":1,"309":1,"311":2,"312":2,"313":2,"314":2,"315":2,"316":2,"317":2,"318":2,"319":2,"320":2,"321":2,"322":2,"323":2,"324":2,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1,"357":1,"379":1,"380":1,"381":1,"382":1,"383":1,"386":1,"387":1,"388":1},"2":{"1":3,"3":2,"4":2,"5":1,"8":2,"9":2,"38":1,"39":2,"41":4,"42":2,"44":2,"45":2,"46":2,"49":2,"51":2,"52":2,"53":2,"55":2,"56":2,"57":2,"58":2,"59":2,"60":2,"61":2,"62":2,"63":2,"65":1,"66":1,"67":1,"68":2,"70":1,"71":1,"72":1,"73":1,"74":2,"75":1,"76":2,"77":2,"79":1,"80":4,"81":1,"83":2,"84":2,"85":2,"86":2,"87":1,"105":1,"108":1,"113":1,"114":1,"117":1,"127":4,"128":3,"132":2,"133":5,"135":2,"137":1,"142":3,"144":2,"148":1,"159":3,"161":3,"162":2,"181":3,"182":3,"186":1,"188":1,"190":1,"193":1,"194":2,"199":3,"218":1,"220":1,"237":1,"246":1,"248":9,"249":5,"251":3,"252":1,"257":1,"259":5,"261":1,"262":1,"269":1,"270":1,"271":1,"272":2,"274":1,"277":1,"286":1,"292":1,"297":1,"299":1,"300":1,"301":1,"303":2,"304":1,"305":1,"306":1,"307":1,"308":2,"311":4,"312":2,"313":6,"315":2,"316":9,"318":2,"319":2,"326":1,"330":1,"332":1,"333":1,"339":1,"341":1,"348":1,"352":4,"353":3,"354":3,"357":2,"358":2,"363":2,"364":1,"366":4,"367":2,"368":3,"369":2,"370":2,"371":1,"373":1,"374":2,"376":1,"377":1,"379":2,"381":1,"382":2,"384":4,"385":3,"386":1,"387":2,"388":3,"389":2,"390":4}}],["📏",{"2":{"389":1}}],["💼",{"2":{"385":1}}],["🐢",{"2":{"385":1}}],["🚨",{"2":{"385":1}}],["👥",{"2":{"383":1}}],["🔖",{"2":{"381":1}}],["🗄️",{"2":{"376":1}}],["🕒",{"2":{"371":1}}],["🔋",{"2":{"371":1}}],["🗜️",{"2":{"371":1}}],["📈",{"2":{"313":1,"383":1}}],["📉",{"2":{"312":1,"377":1}}],["👀",{"0":{"291":1}}],["🐛",{"0":{"279":1,"280":1},"2":{"385":1}}],["🗂",{"0":{"277":1,"391":1},"2":{"389":1}}],["🗂️",{"0":{"30":1,"175":1,"226":1,"252":1,"266":1,"298":1,"317":1},"1":{"227":1,"228":1,"229":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1,"307":1,"308":1,"309":1},"2":{"313":1,"377":1}}],["💾",{"0":{"262":1,"376":1},"2":{"377":1}}],["📂",{"0":{"228":1,"229":1,"250":1,"257":1,"264":1,"273":1,"290":1,"375":1},"1":{"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":2,"259":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":1}}],["💬",{"2":{"220":1}}],["🕵️‍♂️",{"0":{"219":1}}],["🚧",{"0":{"209":1},"1":{"210":1,"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1}}],["🖥️",{"0":{"201":1}}],["📞",{"0":{"188":1}}],["🛡️",{"0":{"187":1,"321":1},"1":{"322":1,"323":1,"324":1}}],["🔑",{"0":{"182":1,"184":1,"233":1,"265":1,"381":1,"389":1}}],["📑",{"0":{"176":1}}],["📥",{"0":{"174":1,"194":1,"199":1}}],["📤",{"0":{"173":1}}],["📊",{"0":{"165":1,"362":1,"368":1},"1":{"363":1,"364":1,"369":1,"370":1,"371":1}}],["📋",{"0":{"164":1,"215":1},"1":{"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1}}],["📄",{"0":{"163":1,"227":1,"239":1,"242":1,"254":1,"256":1,"301":1,"303":1,"305":1},"1":{"255":1,"256":1,"306":1,"307":1,"308":1}}],["🛠",{"0":{"162":1,"180":1,"186":1,"197":1,"225":1,"235":1,"259":1,"271":1,"328":1,"364":1},"1":{"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1}}],["🛠️",{"0":{"4":1,"6":1,"11":1,"37":1,"43":1,"64":1,"78":1,"87":1,"99":1,"111":1,"115":1,"124":1,"128":1,"169":1,"196":1,"216":1,"243":1,"300":1,"314":1,"315":1,"319":1,"373":1,"382":1},"1":{"7":1,"8":1,"9":1,"10":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"44":1,"45":1,"46":1,"65":1,"66":1,"79":1,"80":1,"81":1,"88":1,"89":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":2,"101":2,"102":2,"103":2,"104":2,"112":1,"113":1,"114":1,"116":1,"117":1,"118":1,"119":1,"125":1,"126":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"301":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1},"2":{"389":1}}],["📦",{"0":{"161":1,"200":1,"224":1},"2":{"270":1}}],["🔧",{"0":{"160":1,"208":1,"223":1,"253":1},"1":{"161":1,"162":1,"163":1,"224":1,"225":1},"2":{"244":1,"309":1,"312":1,"383":1}}],["📖",{"0":{"159":1,"190":1,"222":1,"237":1,"251":1,"269":1,"299":1,"311":1,"340":1,"366":1,"379":1},"1":{"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1}}],["🗓️",{"0":{"156":1},"1":{"157":1}}],["📚",{"0":{"127":1,"192":1,"206":1},"1":{"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1},"2":{"244":1,"309":1}}],["🚀",{"0":{"50":1,"82":1,"120":1,"191":1,"198":1,"217":1,"238":1,"312":1,"365":1},"1":{"51":1,"52":1,"83":1,"84":1,"85":1,"86":1,"121":1,"122":1,"123":1,"192":1,"193":1,"194":1,"195":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"239":1,"240":1,"366":1,"367":1,"368":1,"369":1,"370":1,"371":1,"372":1,"373":1,"374":1,"375":1,"376":1,"377":1},"2":{"244":1,"270":1}}],["💻",{"0":{"36":1,"210":1}}],["🚦",{"0":{"31":1,"285":1,"286":1,"374":1},"1":{"32":1,"33":1,"34":1,"35":1}}],["📅",{"0":{"21":1},"1":{"22":1}}],["🔢",{"0":{"18":1,"19":1,"284":1},"1":{"20":1}}],["🔍",{"0":{"15":1,"16":1,"17":1,"178":1,"205":1,"278":1,"283":1,"313":1,"363":1,"371":1}}],["🔗",{"0":{"5":1,"10":1,"236":1,"281":1,"287":1,"292":1,"318":1},"1":{"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1},"2":{"381":1}}],["💡",{"0":{"3":1,"220":1}}],["📝",{"0":{"2":1,"9":1,"35":1,"126":1,"137":1,"146":1,"183":1,"213":1,"244":1,"263":1,"309":1,"326":1,"338":1,"377":1,"385":1},"1":{"138":1,"139":1,"140":1,"141":1,"147":1,"184":1,"185":1,"186":1,"187":1,"214":1,"215":1,"216":1,"264":1,"265":1,"266":1,"267":1,"386":1,"387":1,"388":1},"2":{"220":1}}],["🔄",{"0":{"1":1,"23":1,"24":1,"25":1,"26":1,"27":1,"29":1,"170":1,"179":1,"218":1,"240":1,"289":1,"297":1,"310":1,"316":1},"1":{"2":1,"3":1,"4":1,"5":1,"311":1,"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1}}],["📢",{"0":{"0":1},"1":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1}}]],"serializationVersion":2}';export{t as default}; diff --git a/assets/chunks/VPLocalSearchBox.D0OKQOhX.js b/assets/chunks/VPLocalSearchBox.D0OKQOhX.js new file mode 100644 index 0000000..09d2515 --- /dev/null +++ b/assets/chunks/VPLocalSearchBox.D0OKQOhX.js @@ -0,0 +1,7 @@ +var Nt=Object.defineProperty;var Ft=(a,e,t)=>e in a?Nt(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var Re=(a,e,t)=>Ft(a,typeof e!="symbol"?e+"":e,t);import{V as Ot,p as se,h as pe,ah as Xe,ai as Rt,aj as Ct,q as je,ak as Mt,d as At,D as ye,al as et,am as Lt,an as Dt,s as zt,ao as Pt,v as Ce,P as ue,O as we,ap as jt,aq as Vt,W as $t,R as Bt,$ as Wt,o as q,b as Kt,j as S,a0 as Jt,k as D,ar as Ut,as as qt,at as Gt,c as Y,n as tt,e as xe,C as st,F as nt,a as de,t as he,au as Ht,av as it,aw as Qt,a6 as Yt,ac as Zt,ax as Xt,_ as es}from"./framework.CBrKbnPu.js";import{u as ts,c as ss}from"./theme.DDdXCRuz.js";const ns={root:()=>Ot(()=>import("./@localSearchIndexroot.tyM1vONZ.js"),[])};/*! +* tabbable 6.2.0 +* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE +*/var vt=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],Ie=vt.join(","),mt=typeof Element>"u",ie=mt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,ke=!mt&&Element.prototype.getRootNode?function(a){var e;return a==null||(e=a.getRootNode)===null||e===void 0?void 0:e.call(a)}:function(a){return a==null?void 0:a.ownerDocument},Ne=function a(e,t){var s;t===void 0&&(t=!0);var n=e==null||(s=e.getAttribute)===null||s===void 0?void 0:s.call(e,"inert"),r=n===""||n==="true",i=r||t&&e&&a(e.parentNode);return i},is=function(e){var t,s=e==null||(t=e.getAttribute)===null||t===void 0?void 0:t.call(e,"contenteditable");return s===""||s==="true"},gt=function(e,t,s){if(Ne(e))return[];var n=Array.prototype.slice.apply(e.querySelectorAll(Ie));return t&&ie.call(e,Ie)&&n.unshift(e),n=n.filter(s),n},bt=function a(e,t,s){for(var n=[],r=Array.from(e);r.length;){var i=r.shift();if(!Ne(i,!1))if(i.tagName==="SLOT"){var o=i.assignedElements(),l=o.length?o:i.children,c=a(l,!0,s);s.flatten?n.push.apply(n,c):n.push({scopeParent:i,candidates:c})}else{var h=ie.call(i,Ie);h&&s.filter(i)&&(t||!e.includes(i))&&n.push(i);var v=i.shadowRoot||typeof s.getShadowRoot=="function"&&s.getShadowRoot(i),p=!Ne(v,!1)&&(!s.shadowRootFilter||s.shadowRootFilter(i));if(v&&p){var b=a(v===!0?i.children:v.children,!0,s);s.flatten?n.push.apply(n,b):n.push({scopeParent:i,candidates:b})}else r.unshift.apply(r,i.children)}}return n},yt=function(e){return!isNaN(parseInt(e.getAttribute("tabindex"),10))},ne=function(e){if(!e)throw new Error("No node provided");return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||is(e))&&!yt(e)?0:e.tabIndex},rs=function(e,t){var s=ne(e);return s<0&&t&&!yt(e)?0:s},as=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},wt=function(e){return e.tagName==="INPUT"},os=function(e){return wt(e)&&e.type==="hidden"},ls=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(s){return s.tagName==="SUMMARY"});return t},cs=function(e,t){for(var s=0;ssummary:first-of-type"),i=r?e.parentElement:e;if(ie.call(i,"details:not([open]) *"))return!0;if(!s||s==="full"||s==="legacy-full"){if(typeof n=="function"){for(var o=e;e;){var l=e.parentElement,c=ke(e);if(l&&!l.shadowRoot&&n(l)===!0)return rt(e);e.assignedSlot?e=e.assignedSlot:!l&&c!==e.ownerDocument?e=c.host:e=l}e=o}if(fs(e))return!e.getClientRects().length;if(s!=="legacy-full")return!0}else if(s==="non-zero-area")return rt(e);return!1},vs=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var s=0;s=0)},gs=function a(e){var t=[],s=[];return e.forEach(function(n,r){var i=!!n.scopeParent,o=i?n.scopeParent:n,l=rs(o,i),c=i?a(n.candidates):o;l===0?i?t.push.apply(t,c):t.push(o):s.push({documentOrder:r,tabIndex:l,item:n,isScope:i,content:c})}),s.sort(as).reduce(function(n,r){return r.isScope?n.push.apply(n,r.content):n.push(r.content),n},[]).concat(t)},bs=function(e,t){t=t||{};var s;return t.getShadowRoot?s=bt([e],t.includeContainer,{filter:Ve.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:ms}):s=gt(e,t.includeContainer,Ve.bind(null,t)),gs(s)},ys=function(e,t){t=t||{};var s;return t.getShadowRoot?s=bt([e],t.includeContainer,{filter:Fe.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):s=gt(e,t.includeContainer,Fe.bind(null,t)),s},re=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ie.call(e,Ie)===!1?!1:Ve(t,e)},ws=vt.concat("iframe").join(","),Me=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ie.call(e,ws)===!1?!1:Fe(t,e)};/*! +* focus-trap 7.6.0 +* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE +*/function xs(a,e,t){return(e=_s(e))in a?Object.defineProperty(a,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[e]=t,a}function at(a,e){var t=Object.keys(a);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(a);e&&(s=s.filter(function(n){return Object.getOwnPropertyDescriptor(a,n).enumerable})),t.push.apply(t,s)}return t}function ot(a){for(var e=1;e0){var s=e[e.length-1];s!==t&&s.pause()}var n=e.indexOf(t);n===-1||e.splice(n,1),e.push(t)},deactivateTrap:function(e,t){var s=e.indexOf(t);s!==-1&&e.splice(s,1),e.length>0&&e[e.length-1].unpause()}},Es=function(e){return e.tagName&&e.tagName.toLowerCase()==="input"&&typeof e.select=="function"},Ts=function(e){return(e==null?void 0:e.key)==="Escape"||(e==null?void 0:e.key)==="Esc"||(e==null?void 0:e.keyCode)===27},ve=function(e){return(e==null?void 0:e.key)==="Tab"||(e==null?void 0:e.keyCode)===9},Is=function(e){return ve(e)&&!e.shiftKey},ks=function(e){return ve(e)&&e.shiftKey},ct=function(e){return setTimeout(e,0)},ut=function(e,t){var s=-1;return e.every(function(n,r){return t(n)?(s=r,!1):!0}),s},fe=function(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1?g-1:0),E=1;E=0)d=s.activeElement;else{var u=i.tabbableGroups[0],g=u&&u.firstTabbableNode;d=g||h("fallbackFocus")}if(!d)throw new Error("Your focus-trap needs to have at least one focusable element");return d},p=function(){if(i.containerGroups=i.containers.map(function(d){var u=bs(d,r.tabbableOptions),g=ys(d,r.tabbableOptions),_=u.length>0?u[0]:void 0,E=u.length>0?u[u.length-1]:void 0,N=g.find(function(f){return re(f)}),F=g.slice().reverse().find(function(f){return re(f)}),m=!!u.find(function(f){return ne(f)>0});return{container:d,tabbableNodes:u,focusableNodes:g,posTabIndexesFound:m,firstTabbableNode:_,lastTabbableNode:E,firstDomTabbableNode:N,lastDomTabbableNode:F,nextTabbableNode:function(T){var A=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,C=u.indexOf(T);return C<0?A?g.slice(g.indexOf(T)+1).find(function(M){return re(M)}):g.slice(0,g.indexOf(T)).reverse().find(function(M){return re(M)}):u[C+(A?1:-1)]}}}),i.tabbableGroups=i.containerGroups.filter(function(d){return d.tabbableNodes.length>0}),i.tabbableGroups.length<=0&&!h("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(i.containerGroups.find(function(d){return d.posTabIndexesFound})&&i.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},b=function(d){var u=d.activeElement;if(u)return u.shadowRoot&&u.shadowRoot.activeElement!==null?b(u.shadowRoot):u},y=function(d){if(d!==!1&&d!==b(document)){if(!d||!d.focus){y(v());return}d.focus({preventScroll:!!r.preventScroll}),i.mostRecentlyFocusedNode=d,Es(d)&&d.select()}},x=function(d){var u=h("setReturnFocus",d);return u||(u===!1?!1:d)},w=function(d){var u=d.target,g=d.event,_=d.isBackward,E=_===void 0?!1:_;u=u||Se(g),p();var N=null;if(i.tabbableGroups.length>0){var F=c(u,g),m=F>=0?i.containerGroups[F]:void 0;if(F<0)E?N=i.tabbableGroups[i.tabbableGroups.length-1].lastTabbableNode:N=i.tabbableGroups[0].firstTabbableNode;else if(E){var f=ut(i.tabbableGroups,function(L){var j=L.firstTabbableNode;return u===j});if(f<0&&(m.container===u||Me(u,r.tabbableOptions)&&!re(u,r.tabbableOptions)&&!m.nextTabbableNode(u,!1))&&(f=F),f>=0){var T=f===0?i.tabbableGroups.length-1:f-1,A=i.tabbableGroups[T];N=ne(u)>=0?A.lastTabbableNode:A.lastDomTabbableNode}else ve(g)||(N=m.nextTabbableNode(u,!1))}else{var C=ut(i.tabbableGroups,function(L){var j=L.lastTabbableNode;return u===j});if(C<0&&(m.container===u||Me(u,r.tabbableOptions)&&!re(u,r.tabbableOptions)&&!m.nextTabbableNode(u))&&(C=F),C>=0){var M=C===i.tabbableGroups.length-1?0:C+1,I=i.tabbableGroups[M];N=ne(u)>=0?I.firstTabbableNode:I.firstDomTabbableNode}else ve(g)||(N=m.nextTabbableNode(u))}}else N=h("fallbackFocus");return N},O=function(d){var u=Se(d);if(!(c(u,d)>=0)){if(fe(r.clickOutsideDeactivates,d)){o.deactivate({returnFocus:r.returnFocusOnDeactivate});return}fe(r.allowOutsideClick,d)||d.preventDefault()}},R=function(d){var u=Se(d),g=c(u,d)>=0;if(g||u instanceof Document)g&&(i.mostRecentlyFocusedNode=u);else{d.stopImmediatePropagation();var _,E=!0;if(i.mostRecentlyFocusedNode)if(ne(i.mostRecentlyFocusedNode)>0){var N=c(i.mostRecentlyFocusedNode),F=i.containerGroups[N].tabbableNodes;if(F.length>0){var m=F.findIndex(function(f){return f===i.mostRecentlyFocusedNode});m>=0&&(r.isKeyForward(i.recentNavEvent)?m+1=0&&(_=F[m-1],E=!1))}}else i.containerGroups.some(function(f){return f.tabbableNodes.some(function(T){return ne(T)>0})})||(E=!1);else E=!1;E&&(_=w({target:i.mostRecentlyFocusedNode,isBackward:r.isKeyBackward(i.recentNavEvent)})),y(_||i.mostRecentlyFocusedNode||v())}i.recentNavEvent=void 0},K=function(d){var u=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;i.recentNavEvent=d;var g=w({event:d,isBackward:u});g&&(ve(d)&&d.preventDefault(),y(g))},G=function(d){(r.isKeyForward(d)||r.isKeyBackward(d))&&K(d,r.isKeyBackward(d))},W=function(d){Ts(d)&&fe(r.escapeDeactivates,d)!==!1&&(d.preventDefault(),o.deactivate())},V=function(d){var u=Se(d);c(u,d)>=0||fe(r.clickOutsideDeactivates,d)||fe(r.allowOutsideClick,d)||(d.preventDefault(),d.stopImmediatePropagation())},$=function(){if(i.active)return lt.activateTrap(n,o),i.delayInitialFocusTimer=r.delayInitialFocus?ct(function(){y(v())}):y(v()),s.addEventListener("focusin",R,!0),s.addEventListener("mousedown",O,{capture:!0,passive:!1}),s.addEventListener("touchstart",O,{capture:!0,passive:!1}),s.addEventListener("click",V,{capture:!0,passive:!1}),s.addEventListener("keydown",G,{capture:!0,passive:!1}),s.addEventListener("keydown",W),o},me=function(){if(i.active)return s.removeEventListener("focusin",R,!0),s.removeEventListener("mousedown",O,!0),s.removeEventListener("touchstart",O,!0),s.removeEventListener("click",V,!0),s.removeEventListener("keydown",G,!0),s.removeEventListener("keydown",W),o},P=function(d){var u=d.some(function(g){var _=Array.from(g.removedNodes);return _.some(function(E){return E===i.mostRecentlyFocusedNode})});u&&y(v())},H=typeof window<"u"&&"MutationObserver"in window?new MutationObserver(P):void 0,J=function(){H&&(H.disconnect(),i.active&&!i.paused&&i.containers.map(function(d){H.observe(d,{subtree:!0,childList:!0})}))};return o={get active(){return i.active},get paused(){return i.paused},activate:function(d){if(i.active)return this;var u=l(d,"onActivate"),g=l(d,"onPostActivate"),_=l(d,"checkCanFocusTrap");_||p(),i.active=!0,i.paused=!1,i.nodeFocusedBeforeActivation=s.activeElement,u==null||u();var E=function(){_&&p(),$(),J(),g==null||g()};return _?(_(i.containers.concat()).then(E,E),this):(E(),this)},deactivate:function(d){if(!i.active)return this;var u=ot({onDeactivate:r.onDeactivate,onPostDeactivate:r.onPostDeactivate,checkCanReturnFocus:r.checkCanReturnFocus},d);clearTimeout(i.delayInitialFocusTimer),i.delayInitialFocusTimer=void 0,me(),i.active=!1,i.paused=!1,J(),lt.deactivateTrap(n,o);var g=l(u,"onDeactivate"),_=l(u,"onPostDeactivate"),E=l(u,"checkCanReturnFocus"),N=l(u,"returnFocus","returnFocusOnDeactivate");g==null||g();var F=function(){ct(function(){N&&y(x(i.nodeFocusedBeforeActivation)),_==null||_()})};return N&&E?(E(x(i.nodeFocusedBeforeActivation)).then(F,F),this):(F(),this)},pause:function(d){if(i.paused||!i.active)return this;var u=l(d,"onPause"),g=l(d,"onPostPause");return i.paused=!0,u==null||u(),me(),J(),g==null||g(),this},unpause:function(d){if(!i.paused||!i.active)return this;var u=l(d,"onUnpause"),g=l(d,"onPostUnpause");return i.paused=!1,u==null||u(),p(),$(),J(),g==null||g(),this},updateContainerElements:function(d){var u=[].concat(d).filter(Boolean);return i.containers=u.map(function(g){return typeof g=="string"?s.querySelector(g):g}),i.active&&p(),J(),this}},o.updateContainerElements(e),o};function Os(a,e={}){let t;const{immediate:s,...n}=e,r=se(!1),i=se(!1),o=p=>t&&t.activate(p),l=p=>t&&t.deactivate(p),c=()=>{t&&(t.pause(),i.value=!0)},h=()=>{t&&(t.unpause(),i.value=!1)},v=pe(()=>{const p=Xe(a);return(Array.isArray(p)?p:[p]).map(b=>{const y=Xe(b);return typeof y=="string"?y:Rt(y)}).filter(Ct)});return je(v,p=>{p.length&&(t=Fs(p,{...n,onActivate(){r.value=!0,e.onActivate&&e.onActivate()},onDeactivate(){r.value=!1,e.onDeactivate&&e.onDeactivate()}}),s&&o())},{flush:"post"}),Mt(()=>l()),{hasFocus:r,isPaused:i,activate:o,deactivate:l,pause:c,unpause:h}}class oe{constructor(e,t=!0,s=[],n=5e3){this.ctx=e,this.iframes=t,this.exclude=s,this.iframesTimeout=n}static matches(e,t){const s=typeof t=="string"?[t]:t,n=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(n){let r=!1;return s.every(i=>n.call(e,i)?(r=!0,!1):!0),r}else return!1}getContexts(){let e,t=[];return typeof this.ctx>"u"||!this.ctx?e=[]:NodeList.prototype.isPrototypeOf(this.ctx)?e=Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?e=this.ctx:typeof this.ctx=="string"?e=Array.prototype.slice.call(document.querySelectorAll(this.ctx)):e=[this.ctx],e.forEach(s=>{const n=t.filter(r=>r.contains(s)).length>0;t.indexOf(s)===-1&&!n&&t.push(s)}),t}getIframeContents(e,t,s=()=>{}){let n;try{const r=e.contentWindow;if(n=r.document,!r||!n)throw new Error("iframe inaccessible")}catch{s()}n&&t(n)}isIframeBlank(e){const t="about:blank",s=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&s!==t&&s}observeIframeLoad(e,t,s){let n=!1,r=null;const i=()=>{if(!n){n=!0,clearTimeout(r);try{this.isIframeBlank(e)||(e.removeEventListener("load",i),this.getIframeContents(e,t,s))}catch{s()}}};e.addEventListener("load",i),r=setTimeout(i,this.iframesTimeout)}onIframeReady(e,t,s){try{e.contentWindow.document.readyState==="complete"?this.isIframeBlank(e)?this.observeIframeLoad(e,t,s):this.getIframeContents(e,t,s):this.observeIframeLoad(e,t,s)}catch{s()}}waitForIframes(e,t){let s=0;this.forEachIframe(e,()=>!0,n=>{s++,this.waitForIframes(n.querySelector("html"),()=>{--s||t()})},n=>{n||t()})}forEachIframe(e,t,s,n=()=>{}){let r=e.querySelectorAll("iframe"),i=r.length,o=0;r=Array.prototype.slice.call(r);const l=()=>{--i<=0&&n(o)};i||l(),r.forEach(c=>{oe.matches(c,this.exclude)?l():this.onIframeReady(c,h=>{t(c)&&(o++,s(h)),l()},l)})}createIterator(e,t,s){return document.createNodeIterator(e,t,s,!1)}createInstanceOnIframe(e){return new oe(e.querySelector("html"),this.iframes)}compareNodeIframe(e,t,s){const n=e.compareDocumentPosition(s),r=Node.DOCUMENT_POSITION_PRECEDING;if(n&r)if(t!==null){const i=t.compareDocumentPosition(s),o=Node.DOCUMENT_POSITION_FOLLOWING;if(i&o)return!0}else return!0;return!1}getIteratorNode(e){const t=e.previousNode();let s;return t===null?s=e.nextNode():s=e.nextNode()&&e.nextNode(),{prevNode:t,node:s}}checkIframeFilter(e,t,s,n){let r=!1,i=!1;return n.forEach((o,l)=>{o.val===s&&(r=l,i=o.handled)}),this.compareNodeIframe(e,t,s)?(r===!1&&!i?n.push({val:s,handled:!0}):r!==!1&&!i&&(n[r].handled=!0),!0):(r===!1&&n.push({val:s,handled:!1}),!1)}handleOpenIframes(e,t,s,n){e.forEach(r=>{r.handled||this.getIframeContents(r.val,i=>{this.createInstanceOnIframe(i).forEachNode(t,s,n)})})}iterateThroughNodes(e,t,s,n,r){const i=this.createIterator(t,e,n);let o=[],l=[],c,h,v=()=>({prevNode:h,node:c}=this.getIteratorNode(i),c);for(;v();)this.iframes&&this.forEachIframe(t,p=>this.checkIframeFilter(c,h,p,o),p=>{this.createInstanceOnIframe(p).forEachNode(e,b=>l.push(b),n)}),l.push(c);l.forEach(p=>{s(p)}),this.iframes&&this.handleOpenIframes(o,e,s,n),r()}forEachNode(e,t,s,n=()=>{}){const r=this.getContexts();let i=r.length;i||n(),r.forEach(o=>{const l=()=>{this.iterateThroughNodes(e,o,t,s,()=>{--i<=0&&n()})};this.iframes?this.waitForIframes(o,l):l()})}}let Rs=class{constructor(e){this.ctx=e,this.ie=!1;const t=window.navigator.userAgent;(t.indexOf("MSIE")>-1||t.indexOf("Trident")>-1)&&(this.ie=!0)}set opt(e){this._opt=Object.assign({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:()=>{},noMatch:()=>{},filter:()=>!0,done:()=>{},debug:!1,log:window.console},e)}get opt(){return this._opt}get iterator(){return new oe(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}log(e,t="debug"){const s=this.opt.log;this.opt.debug&&typeof s=="object"&&typeof s[t]=="function"&&s[t](`mark.js: ${e}`)}escapeStr(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}createRegExp(e){return this.opt.wildcards!=="disabled"&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),this.opt.wildcards!=="disabled"&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),e}createSynonymsRegExp(e){const t=this.opt.synonyms,s=this.opt.caseSensitive?"":"i",n=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(let r in t)if(t.hasOwnProperty(r)){const i=t[r],o=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(r):this.escapeStr(r),l=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(i):this.escapeStr(i);o!==""&&l!==""&&(e=e.replace(new RegExp(`(${this.escapeStr(o)}|${this.escapeStr(l)})`,`gm${s}`),n+`(${this.processSynomyms(o)}|${this.processSynomyms(l)})`+n))}return e}processSynomyms(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}setupWildcardsRegExp(e){return e=e.replace(/(?:\\)*\?/g,t=>t.charAt(0)==="\\"?"?":""),e.replace(/(?:\\)*\*/g,t=>t.charAt(0)==="\\"?"*":"")}createWildcardsRegExp(e){let t=this.opt.wildcards==="withSpaces";return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}setupIgnoreJoinersRegExp(e){return e.replace(/[^(|)\\]/g,(t,s,n)=>{let r=n.charAt(s+1);return/[(|)\\]/.test(r)||r===""?t:t+"\0"})}createJoinersRegExp(e){let t=[];const s=this.opt.ignorePunctuation;return Array.isArray(s)&&s.length&&t.push(this.escapeStr(s.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join(`[${t.join("")}]*`):e}createDiacriticsRegExp(e){const t=this.opt.caseSensitive?"":"i",s=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"];let n=[];return e.split("").forEach(r=>{s.every(i=>{if(i.indexOf(r)!==-1){if(n.indexOf(i)>-1)return!1;e=e.replace(new RegExp(`[${i}]`,`gm${t}`),`[${i}]`),n.push(i)}return!0})}),e}createMergedBlanksRegExp(e){return e.replace(/[\s]+/gmi,"[\\s]+")}createAccuracyRegExp(e){const t="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";let s=this.opt.accuracy,n=typeof s=="string"?s:s.value,r=typeof s=="string"?[]:s.limiters,i="";switch(r.forEach(o=>{i+=`|${this.escapeStr(o)}`}),n){case"partially":default:return`()(${e})`;case"complementary":return i="\\s"+(i||this.escapeStr(t)),`()([^${i}]*${e}[^${i}]*)`;case"exactly":return`(^|\\s${i})(${e})(?=$|\\s${i})`}}getSeparatedKeywords(e){let t=[];return e.forEach(s=>{this.opt.separateWordSearch?s.split(" ").forEach(n=>{n.trim()&&t.indexOf(n)===-1&&t.push(n)}):s.trim()&&t.indexOf(s)===-1&&t.push(s)}),{keywords:t.sort((s,n)=>n.length-s.length),length:t.length}}isNumeric(e){return Number(parseFloat(e))==e}checkRanges(e){if(!Array.isArray(e)||Object.prototype.toString.call(e[0])!=="[object Object]")return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];const t=[];let s=0;return e.sort((n,r)=>n.start-r.start).forEach(n=>{let{start:r,end:i,valid:o}=this.callNoMatchOnInvalidRanges(n,s);o&&(n.start=r,n.length=i-r,t.push(n),s=i)}),t}callNoMatchOnInvalidRanges(e,t){let s,n,r=!1;return e&&typeof e.start<"u"?(s=parseInt(e.start,10),n=s+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&n-t>0&&n-s>0?r=!0:(this.log(`Ignoring invalid or overlapping range: ${JSON.stringify(e)}`),this.opt.noMatch(e))):(this.log(`Ignoring invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)),{start:s,end:n,valid:r}}checkWhitespaceRanges(e,t,s){let n,r=!0,i=s.length,o=t-i,l=parseInt(e.start,10)-o;return l=l>i?i:l,n=l+parseInt(e.length,10),n>i&&(n=i,this.log(`End range automatically set to the max value of ${i}`)),l<0||n-l<0||l>i||n>i?(r=!1,this.log(`Invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)):s.substring(l,n).replace(/\s+/g,"")===""&&(r=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:l,end:n,valid:r}}getTextNodes(e){let t="",s=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,n=>{s.push({start:t.length,end:(t+=n.textContent).length,node:n})},n=>this.matchesExclude(n.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT,()=>{e({value:t,nodes:s})})}matchesExclude(e){return oe.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}wrapRangeInTextNode(e,t,s){const n=this.opt.element?this.opt.element:"mark",r=e.splitText(t),i=r.splitText(s-t);let o=document.createElement(n);return o.setAttribute("data-markjs","true"),this.opt.className&&o.setAttribute("class",this.opt.className),o.textContent=r.textContent,r.parentNode.replaceChild(o,r),i}wrapRangeInMappedTextNode(e,t,s,n,r){e.nodes.every((i,o)=>{const l=e.nodes[o+1];if(typeof l>"u"||l.start>t){if(!n(i.node))return!1;const c=t-i.start,h=(s>i.end?i.end:s)-i.start,v=e.value.substr(0,i.start),p=e.value.substr(h+i.start);if(i.node=this.wrapRangeInTextNode(i.node,c,h),e.value=v+p,e.nodes.forEach((b,y)=>{y>=o&&(e.nodes[y].start>0&&y!==o&&(e.nodes[y].start-=h),e.nodes[y].end-=h)}),s-=h,r(i.node.previousSibling,i.start),s>i.end)t=i.end;else return!1}return!0})}wrapMatches(e,t,s,n,r){const i=t===0?0:t+1;this.getTextNodes(o=>{o.nodes.forEach(l=>{l=l.node;let c;for(;(c=e.exec(l.textContent))!==null&&c[i]!=="";){if(!s(c[i],l))continue;let h=c.index;if(i!==0)for(let v=1;v{let l;for(;(l=e.exec(o.value))!==null&&l[i]!=="";){let c=l.index;if(i!==0)for(let v=1;vs(l[i],v),(v,p)=>{e.lastIndex=p,n(v)})}r()})}wrapRangeFromIndex(e,t,s,n){this.getTextNodes(r=>{const i=r.value.length;e.forEach((o,l)=>{let{start:c,end:h,valid:v}=this.checkWhitespaceRanges(o,i,r.value);v&&this.wrapRangeInMappedTextNode(r,c,h,p=>t(p,o,r.value.substring(c,h),l),p=>{s(p,o)})}),n()})}unwrapMatches(e){const t=e.parentNode;let s=document.createDocumentFragment();for(;e.firstChild;)s.appendChild(e.removeChild(e.firstChild));t.replaceChild(s,e),this.ie?this.normalizeTextNode(t):t.normalize()}normalizeTextNode(e){if(e){if(e.nodeType===3)for(;e.nextSibling&&e.nextSibling.nodeType===3;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}markRegExp(e,t){this.opt=t,this.log(`Searching with expression "${e}"`);let s=0,n="wrapMatches";const r=i=>{s++,this.opt.each(i)};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),this[n](e,this.opt.ignoreGroups,(i,o)=>this.opt.filter(o,i,s),r,()=>{s===0&&this.opt.noMatch(e),this.opt.done(s)})}mark(e,t){this.opt=t;let s=0,n="wrapMatches";const{keywords:r,length:i}=this.getSeparatedKeywords(typeof e=="string"?[e]:e),o=this.opt.caseSensitive?"":"i",l=c=>{let h=new RegExp(this.createRegExp(c),`gm${o}`),v=0;this.log(`Searching with expression "${h}"`),this[n](h,1,(p,b)=>this.opt.filter(b,c,s,v),p=>{v++,s++,this.opt.each(p)},()=>{v===0&&this.opt.noMatch(c),r[i-1]===c?this.opt.done(s):l(r[r.indexOf(c)+1])})};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),i===0?this.opt.done(s):l(r[0])}markRanges(e,t){this.opt=t;let s=0,n=this.checkRanges(e);n&&n.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(n)),this.wrapRangeFromIndex(n,(r,i,o,l)=>this.opt.filter(r,i,o,l),(r,i)=>{s++,this.opt.each(r,i)},()=>{this.opt.done(s)})):this.opt.done(s)}unmark(e){this.opt=e;let t=this.opt.element?this.opt.element:"*";t+="[data-markjs]",this.opt.className&&(t+=`.${this.opt.className}`),this.log(`Removal selector "${t}"`),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,s=>{this.unwrapMatches(s)},s=>{const n=oe.matches(s,t),r=this.matchesExclude(s);return!n||r?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}};function Cs(a){const e=new Rs(a);return this.mark=(t,s)=>(e.mark(t,s),this),this.markRegExp=(t,s)=>(e.markRegExp(t,s),this),this.markRanges=(t,s)=>(e.markRanges(t,s),this),this.unmark=t=>(e.unmark(t),this),this}function Te(a,e,t,s){function n(r){return r instanceof t?r:new t(function(i){i(r)})}return new(t||(t=Promise))(function(r,i){function o(h){try{c(s.next(h))}catch(v){i(v)}}function l(h){try{c(s.throw(h))}catch(v){i(v)}}function c(h){h.done?r(h.value):n(h.value).then(o,l)}c((s=s.apply(a,[])).next())})}const Ms="ENTRIES",xt="KEYS",St="VALUES",z="";class Ae{constructor(e,t){const s=e._tree,n=Array.from(s.keys());this.set=e,this._type=t,this._path=n.length>0?[{node:s,keys:n}]:[]}next(){const e=this.dive();return this.backtrack(),e}dive(){if(this._path.length===0)return{done:!0,value:void 0};const{node:e,keys:t}=ae(this._path);if(ae(t)===z)return{done:!1,value:this.result()};const s=e.get(ae(t));return this._path.push({node:s,keys:Array.from(s.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const e=ae(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack())}key(){return this.set._prefix+this._path.map(({keys:e})=>ae(e)).filter(e=>e!==z).join("")}value(){return ae(this._path).node.get(z)}result(){switch(this._type){case St:return this.value();case xt:return this.key();default:return[this.key(),this.value()]}}[Symbol.iterator](){return this}}const ae=a=>a[a.length-1],As=(a,e,t)=>{const s=new Map;if(e===void 0)return s;const n=e.length+1,r=n+t,i=new Uint8Array(r*n).fill(t+1);for(let o=0;o{const l=r*i;e:for(const c of a.keys())if(c===z){const h=n[l-1];h<=t&&s.set(o,[a.get(c),h])}else{let h=r;for(let v=0;vt)continue e}_t(a.get(c),e,t,s,n,h,i,o+c)}};class Z{constructor(e=new Map,t=""){this._size=void 0,this._tree=e,this._prefix=t}atPrefix(e){if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");const[t,s]=Oe(this._tree,e.slice(this._prefix.length));if(t===void 0){const[n,r]=Ke(s);for(const i of n.keys())if(i!==z&&i.startsWith(r)){const o=new Map;return o.set(i.slice(r.length),n.get(i)),new Z(o,e)}}return new Z(t,e)}clear(){this._size=void 0,this._tree.clear()}delete(e){return this._size=void 0,Ls(this._tree,e)}entries(){return new Ae(this,Ms)}forEach(e){for(const[t,s]of this)e(t,s,this)}fuzzyGet(e,t){return As(this._tree,e,t)}get(e){const t=$e(this._tree,e);return t!==void 0?t.get(z):void 0}has(e){const t=$e(this._tree,e);return t!==void 0&&t.has(z)}keys(){return new Ae(this,xt)}set(e,t){if(typeof e!="string")throw new Error("key must be a string");return this._size=void 0,Le(this._tree,e).set(z,t),this}get size(){if(this._size)return this._size;this._size=0;const e=this.entries();for(;!e.next().done;)this._size+=1;return this._size}update(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=Le(this._tree,e);return s.set(z,t(s.get(z))),this}fetch(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=Le(this._tree,e);let n=s.get(z);return n===void 0&&s.set(z,n=t()),n}values(){return new Ae(this,St)}[Symbol.iterator](){return this.entries()}static from(e){const t=new Z;for(const[s,n]of e)t.set(s,n);return t}static fromObject(e){return Z.from(Object.entries(e))}}const Oe=(a,e,t=[])=>{if(e.length===0||a==null)return[a,t];for(const s of a.keys())if(s!==z&&e.startsWith(s))return t.push([a,s]),Oe(a.get(s),e.slice(s.length),t);return t.push([a,e]),Oe(void 0,"",t)},$e=(a,e)=>{if(e.length===0||a==null)return a;for(const t of a.keys())if(t!==z&&e.startsWith(t))return $e(a.get(t),e.slice(t.length))},Le=(a,e)=>{const t=e.length;e:for(let s=0;a&&s{const[t,s]=Oe(a,e);if(t!==void 0){if(t.delete(z),t.size===0)Et(s);else if(t.size===1){const[n,r]=t.entries().next().value;Tt(s,n,r)}}},Et=a=>{if(a.length===0)return;const[e,t]=Ke(a);if(e.delete(t),e.size===0)Et(a.slice(0,-1));else if(e.size===1){const[s,n]=e.entries().next().value;s!==z&&Tt(a.slice(0,-1),s,n)}},Tt=(a,e,t)=>{if(a.length===0)return;const[s,n]=Ke(a);s.set(n+e,t),s.delete(n)},Ke=a=>a[a.length-1],Je="or",It="and",Ds="and_not";class le{constructor(e){if((e==null?void 0:e.fields)==null)throw new Error('MiniSearch: option "fields" must be provided');const t=e.autoVacuum==null||e.autoVacuum===!0?Pe:e.autoVacuum;this._options=Object.assign(Object.assign(Object.assign({},ze),e),{autoVacuum:t,searchOptions:Object.assign(Object.assign({},dt),e.searchOptions||{}),autoSuggestOptions:Object.assign(Object.assign({},$s),e.autoSuggestOptions||{})}),this._index=new Z,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=We,this.addFields(this._options.fields)}add(e){const{extractField:t,tokenize:s,processTerm:n,fields:r,idField:i}=this._options,o=t(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);if(this._idToShortId.has(o))throw new Error(`MiniSearch: duplicate ID ${o}`);const l=this.addDocumentId(o);this.saveStoredFields(l,e);for(const c of r){const h=t(e,c);if(h==null)continue;const v=s(h.toString(),c),p=this._fieldIds[c],b=new Set(v).size;this.addFieldLength(l,p,this._documentCount-1,b);for(const y of v){const x=n(y,c);if(Array.isArray(x))for(const w of x)this.addTerm(p,l,w);else x&&this.addTerm(p,l,x)}}}addAll(e){for(const t of e)this.add(t)}addAllAsync(e,t={}){const{chunkSize:s=10}=t,n={chunk:[],promise:Promise.resolve()},{chunk:r,promise:i}=e.reduce(({chunk:o,promise:l},c,h)=>(o.push(c),(h+1)%s===0?{chunk:[],promise:l.then(()=>new Promise(v=>setTimeout(v,0))).then(()=>this.addAll(o))}:{chunk:o,promise:l}),n);return i.then(()=>this.addAll(r))}remove(e){const{tokenize:t,processTerm:s,extractField:n,fields:r,idField:i}=this._options,o=n(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);const l=this._idToShortId.get(o);if(l==null)throw new Error(`MiniSearch: cannot remove document with ID ${o}: it is not in the index`);for(const c of r){const h=n(e,c);if(h==null)continue;const v=t(h.toString(),c),p=this._fieldIds[c],b=new Set(v).size;this.removeFieldLength(l,p,this._documentCount,b);for(const y of v){const x=s(y,c);if(Array.isArray(x))for(const w of x)this.removeTerm(p,l,w);else x&&this.removeTerm(p,l,x)}}this._storedFields.delete(l),this._documentIds.delete(l),this._idToShortId.delete(o),this._fieldLength.delete(l),this._documentCount-=1}removeAll(e){if(e)for(const t of e)this.remove(t);else{if(arguments.length>0)throw new Error("Expected documents to be present. Omit the argument to remove all documents.");this._index=new Z,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldLength=new Map,this._avgFieldLength=[],this._storedFields=new Map,this._nextId=0}}discard(e){const t=this._idToShortId.get(e);if(t==null)throw new Error(`MiniSearch: cannot discard document with ID ${e}: it is not in the index`);this._idToShortId.delete(e),this._documentIds.delete(t),this._storedFields.delete(t),(this._fieldLength.get(t)||[]).forEach((s,n)=>{this.removeFieldLength(t,n,this._documentCount,s)}),this._fieldLength.delete(t),this._documentCount-=1,this._dirtCount+=1,this.maybeAutoVacuum()}maybeAutoVacuum(){if(this._options.autoVacuum===!1)return;const{minDirtFactor:e,minDirtCount:t,batchSize:s,batchWait:n}=this._options.autoVacuum;this.conditionalVacuum({batchSize:s,batchWait:n},{minDirtCount:t,minDirtFactor:e})}discardAll(e){const t=this._options.autoVacuum;try{this._options.autoVacuum=!1;for(const s of e)this.discard(s)}finally{this._options.autoVacuum=t}this.maybeAutoVacuum()}replace(e){const{idField:t,extractField:s}=this._options,n=s(e,t);this.discard(n),this.add(e)}vacuum(e={}){return this.conditionalVacuum(e)}conditionalVacuum(e,t){return this._currentVacuum?(this._enqueuedVacuumConditions=this._enqueuedVacuumConditions&&t,this._enqueuedVacuum!=null?this._enqueuedVacuum:(this._enqueuedVacuum=this._currentVacuum.then(()=>{const s=this._enqueuedVacuumConditions;return this._enqueuedVacuumConditions=We,this.performVacuuming(e,s)}),this._enqueuedVacuum)):this.vacuumConditionsMet(t)===!1?Promise.resolve():(this._currentVacuum=this.performVacuuming(e),this._currentVacuum)}performVacuuming(e,t){return Te(this,void 0,void 0,function*(){const s=this._dirtCount;if(this.vacuumConditionsMet(t)){const n=e.batchSize||Be.batchSize,r=e.batchWait||Be.batchWait;let i=1;for(const[o,l]of this._index){for(const[c,h]of l)for(const[v]of h)this._documentIds.has(v)||(h.size<=1?l.delete(c):h.delete(v));this._index.get(o).size===0&&this._index.delete(o),i%n===0&&(yield new Promise(c=>setTimeout(c,r))),i+=1}this._dirtCount-=s}yield null,this._currentVacuum=this._enqueuedVacuum,this._enqueuedVacuum=null})}vacuumConditionsMet(e){if(e==null)return!0;let{minDirtCount:t,minDirtFactor:s}=e;return t=t||Pe.minDirtCount,s=s||Pe.minDirtFactor,this.dirtCount>=t&&this.dirtFactor>=s}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}has(e){return this._idToShortId.has(e)}getStoredFields(e){const t=this._idToShortId.get(e);if(t!=null)return this._storedFields.get(t)}search(e,t={}){const s=this.executeQuery(e,t),n=[];for(const[r,{score:i,terms:o,match:l}]of s){const c=o.length||1,h={id:this._documentIds.get(r),score:i*c,terms:Object.keys(l),queryTerms:o,match:l};Object.assign(h,this._storedFields.get(r)),(t.filter==null||t.filter(h))&&n.push(h)}return e===le.wildcard&&t.boostDocument==null&&this._options.searchOptions.boostDocument==null||n.sort(ft),n}autoSuggest(e,t={}){t=Object.assign(Object.assign({},this._options.autoSuggestOptions),t);const s=new Map;for(const{score:r,terms:i}of this.search(e,t)){const o=i.join(" "),l=s.get(o);l!=null?(l.score+=r,l.count+=1):s.set(o,{score:r,terms:i,count:1})}const n=[];for(const[r,{score:i,terms:o,count:l}]of s)n.push({suggestion:r,terms:o,score:i/l});return n.sort(ft),n}get documentCount(){return this._documentCount}get termCount(){return this._index.size}static loadJSON(e,t){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJS(JSON.parse(e),t)}static loadJSONAsync(e,t){return Te(this,void 0,void 0,function*(){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJSAsync(JSON.parse(e),t)})}static getDefault(e){if(ze.hasOwnProperty(e))return De(ze,e);throw new Error(`MiniSearch: unknown option "${e}"`)}static loadJS(e,t){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=_e(n),l._fieldLength=_e(r),l._storedFields=_e(i);for(const[c,h]of l._documentIds)l._idToShortId.set(h,c);for(const[c,h]of s){const v=new Map;for(const p of Object.keys(h)){let b=h[p];o===1&&(b=b.ds),v.set(parseInt(p,10),_e(b))}l._index.set(c,v)}return l}static loadJSAsync(e,t){return Te(this,void 0,void 0,function*(){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=yield Ee(n),l._fieldLength=yield Ee(r),l._storedFields=yield Ee(i);for(const[h,v]of l._documentIds)l._idToShortId.set(v,h);let c=0;for(const[h,v]of s){const p=new Map;for(const b of Object.keys(v)){let y=v[b];o===1&&(y=y.ds),p.set(parseInt(b,10),yield Ee(y))}++c%1e3===0&&(yield kt(0)),l._index.set(h,p)}return l})}static instantiateMiniSearch(e,t){const{documentCount:s,nextId:n,fieldIds:r,averageFieldLength:i,dirtCount:o,serializationVersion:l}=e;if(l!==1&&l!==2)throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");const c=new le(t);return c._documentCount=s,c._nextId=n,c._idToShortId=new Map,c._fieldIds=r,c._avgFieldLength=i,c._dirtCount=o||0,c._index=new Z,c}executeQuery(e,t={}){if(e===le.wildcard)return this.executeWildcardQuery(t);if(typeof e!="string"){const p=Object.assign(Object.assign(Object.assign({},t),e),{queries:void 0}),b=e.queries.map(y=>this.executeQuery(y,p));return this.combineResults(b,p.combineWith)}const{tokenize:s,processTerm:n,searchOptions:r}=this._options,i=Object.assign(Object.assign({tokenize:s,processTerm:n},r),t),{tokenize:o,processTerm:l}=i,v=o(e).flatMap(p=>l(p)).filter(p=>!!p).map(Vs(i)).map(p=>this.executeQuerySpec(p,i));return this.combineResults(v,i.combineWith)}executeQuerySpec(e,t){const s=Object.assign(Object.assign({},this._options.searchOptions),t),n=(s.fields||this._options.fields).reduce((x,w)=>Object.assign(Object.assign({},x),{[w]:De(s.boost,w)||1}),{}),{boostDocument:r,weights:i,maxFuzzy:o,bm25:l}=s,{fuzzy:c,prefix:h}=Object.assign(Object.assign({},dt.weights),i),v=this._index.get(e.term),p=this.termResults(e.term,e.term,1,e.termBoost,v,n,r,l);let b,y;if(e.prefix&&(b=this._index.atPrefix(e.term)),e.fuzzy){const x=e.fuzzy===!0?.2:e.fuzzy,w=x<1?Math.min(o,Math.round(e.term.length*x)):x;w&&(y=this._index.fuzzyGet(e.term,w))}if(b)for(const[x,w]of b){const O=x.length-e.term.length;if(!O)continue;y==null||y.delete(x);const R=h*x.length/(x.length+.3*O);this.termResults(e.term,x,R,e.termBoost,w,n,r,l,p)}if(y)for(const x of y.keys()){const[w,O]=y.get(x);if(!O)continue;const R=c*x.length/(x.length+O);this.termResults(e.term,x,R,e.termBoost,w,n,r,l,p)}return p}executeWildcardQuery(e){const t=new Map,s=Object.assign(Object.assign({},this._options.searchOptions),e);for(const[n,r]of this._documentIds){const i=s.boostDocument?s.boostDocument(r,"",this._storedFields.get(n)):1;t.set(n,{score:i,terms:[],match:{}})}return t}combineResults(e,t=Je){if(e.length===0)return new Map;const s=t.toLowerCase(),n=zs[s];if(!n)throw new Error(`Invalid combination operator: ${t}`);return e.reduce(n)||new Map}toJSON(){const e=[];for(const[t,s]of this._index){const n={};for(const[r,i]of s)n[r]=Object.fromEntries(i);e.push([t,n])}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:e,serializationVersion:2}}termResults(e,t,s,n,r,i,o,l,c=new Map){if(r==null)return c;for(const h of Object.keys(i)){const v=i[h],p=this._fieldIds[h],b=r.get(p);if(b==null)continue;let y=b.size;const x=this._avgFieldLength[p];for(const w of b.keys()){if(!this._documentIds.has(w)){this.removeTerm(p,w,t),y-=1;continue}const O=o?o(this._documentIds.get(w),t,this._storedFields.get(w)):1;if(!O)continue;const R=b.get(w),K=this._fieldLength.get(w)[p],G=js(R,y,this._documentCount,K,x,l),W=s*n*v*O*G,V=c.get(w);if(V){V.score+=W,Bs(V.terms,e);const $=De(V.match,t);$?$.push(h):V.match[t]=[h]}else c.set(w,{score:W,terms:[e],match:{[t]:[h]}})}}return c}addTerm(e,t,s){const n=this._index.fetch(s,pt);let r=n.get(e);if(r==null)r=new Map,r.set(t,1),n.set(e,r);else{const i=r.get(t);r.set(t,(i||0)+1)}}removeTerm(e,t,s){if(!this._index.has(s)){this.warnDocumentChanged(t,e,s);return}const n=this._index.fetch(s,pt),r=n.get(e);r==null||r.get(t)==null?this.warnDocumentChanged(t,e,s):r.get(t)<=1?r.size<=1?n.delete(e):r.delete(t):r.set(t,r.get(t)-1),this._index.get(s).size===0&&this._index.delete(s)}warnDocumentChanged(e,t,s){for(const n of Object.keys(this._fieldIds))if(this._fieldIds[n]===t){this._options.logger("warn",`MiniSearch: document with ID ${this._documentIds.get(e)} has changed before removal: term "${s}" was not present in field "${n}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}}addDocumentId(e){const t=this._nextId;return this._idToShortId.set(e,t),this._documentIds.set(t,e),this._documentCount+=1,this._nextId+=1,t}addFields(e){for(let t=0;tObject.prototype.hasOwnProperty.call(a,e)?a[e]:void 0,zs={[Je]:(a,e)=>{for(const t of e.keys()){const s=a.get(t);if(s==null)a.set(t,e.get(t));else{const{score:n,terms:r,match:i}=e.get(t);s.score=s.score+n,s.match=Object.assign(s.match,i),ht(s.terms,r)}}return a},[It]:(a,e)=>{const t=new Map;for(const s of e.keys()){const n=a.get(s);if(n==null)continue;const{score:r,terms:i,match:o}=e.get(s);ht(n.terms,i),t.set(s,{score:n.score+r,terms:n.terms,match:Object.assign(n.match,o)})}return t},[Ds]:(a,e)=>{for(const t of e.keys())a.delete(t);return a}},Ps={k:1.2,b:.7,d:.5},js=(a,e,t,s,n,r)=>{const{k:i,b:o,d:l}=r;return Math.log(1+(t-e+.5)/(e+.5))*(l+a*(i+1)/(a+i*(1-o+o*s/n)))},Vs=a=>(e,t,s)=>{const n=typeof a.fuzzy=="function"?a.fuzzy(e,t,s):a.fuzzy||!1,r=typeof a.prefix=="function"?a.prefix(e,t,s):a.prefix===!0,i=typeof a.boostTerm=="function"?a.boostTerm(e,t,s):1;return{term:e,fuzzy:n,prefix:r,termBoost:i}},ze={idField:"id",extractField:(a,e)=>a[e],tokenize:a=>a.split(Ws),processTerm:a=>a.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:(a,e)=>{typeof(console==null?void 0:console[a])=="function"&&console[a](e)},autoVacuum:!0},dt={combineWith:Je,prefix:!1,fuzzy:!1,maxFuzzy:6,boost:{},weights:{fuzzy:.45,prefix:.375},bm25:Ps},$s={combineWith:It,prefix:(a,e,t)=>e===t.length-1},Be={batchSize:1e3,batchWait:10},We={minDirtFactor:.1,minDirtCount:20},Pe=Object.assign(Object.assign({},Be),We),Bs=(a,e)=>{a.includes(e)||a.push(e)},ht=(a,e)=>{for(const t of e)a.includes(t)||a.push(t)},ft=({score:a},{score:e})=>e-a,pt=()=>new Map,_e=a=>{const e=new Map;for(const t of Object.keys(a))e.set(parseInt(t,10),a[t]);return e},Ee=a=>Te(void 0,void 0,void 0,function*(){const e=new Map;let t=0;for(const s of Object.keys(a))e.set(parseInt(s,10),a[s]),++t%1e3===0&&(yield kt(0));return e}),kt=a=>new Promise(e=>setTimeout(e,a)),Ws=/[\n\r\p{Z}\p{P}]+/u;class Ks{constructor(e=10){Re(this,"max");Re(this,"cache");this.max=e,this.cache=new Map}get(e){let t=this.cache.get(e);return t!==void 0&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){this.cache.has(e)?this.cache.delete(e):this.cache.size===this.max&&this.cache.delete(this.first()),this.cache.set(e,t)}first(){return this.cache.keys().next().value}clear(){this.cache.clear()}}const Js=["aria-owns"],Us={class:"shell"},qs=["title"],Gs={class:"search-actions before"},Hs=["title"],Qs=["placeholder"],Ys={class:"search-actions"},Zs=["title"],Xs=["disabled","title"],en=["id","role","aria-labelledby"],tn=["aria-selected"],sn=["href","aria-label","onMouseenter","onFocusin"],nn={class:"titles"},rn=["innerHTML"],an={class:"title main"},on=["innerHTML"],ln={key:0,class:"excerpt-wrapper"},cn={key:0,class:"excerpt",inert:""},un=["innerHTML"],dn={key:0,class:"no-results"},hn={class:"search-keyboard-shortcuts"},fn=["aria-label"],pn=["aria-label"],vn=["aria-label"],mn=["aria-label"],gn=At({__name:"VPLocalSearchBox",emits:["close"],setup(a,{emit:e}){var N,F;const t=e,s=ye(),n=ye(),r=ye(ns),i=ts(),{activate:o}=Os(s,{immediate:!0,allowOutsideClick:!0,clickOutsideDeactivates:!0,escapeDeactivates:!0}),{localeIndex:l,theme:c}=i,h=et(async()=>{var m,f,T,A,C,M,I,L,j;return it(le.loadJSON((T=await((f=(m=r.value)[l.value])==null?void 0:f.call(m)))==null?void 0:T.default,{fields:["title","titles","text"],storeFields:["title","titles"],searchOptions:{fuzzy:.2,prefix:!0,boost:{title:4,text:2,titles:1},...((A=c.value.search)==null?void 0:A.provider)==="local"&&((M=(C=c.value.search.options)==null?void 0:C.miniSearch)==null?void 0:M.searchOptions)},...((I=c.value.search)==null?void 0:I.provider)==="local"&&((j=(L=c.value.search.options)==null?void 0:L.miniSearch)==null?void 0:j.options)}))}),p=pe(()=>{var m,f;return((m=c.value.search)==null?void 0:m.provider)==="local"&&((f=c.value.search.options)==null?void 0:f.disableQueryPersistence)===!0}).value?se(""):Lt("vitepress:local-search-filter",""),b=Dt("vitepress:local-search-detailed-list",((N=c.value.search)==null?void 0:N.provider)==="local"&&((F=c.value.search.options)==null?void 0:F.detailedView)===!0),y=pe(()=>{var m,f,T;return((m=c.value.search)==null?void 0:m.provider)==="local"&&(((f=c.value.search.options)==null?void 0:f.disableDetailedView)===!0||((T=c.value.search.options)==null?void 0:T.detailedView)===!1)}),x=pe(()=>{var f,T,A,C,M,I,L;const m=((f=c.value.search)==null?void 0:f.options)??c.value.algolia;return((M=(C=(A=(T=m==null?void 0:m.locales)==null?void 0:T[l.value])==null?void 0:A.translations)==null?void 0:C.button)==null?void 0:M.buttonText)||((L=(I=m==null?void 0:m.translations)==null?void 0:I.button)==null?void 0:L.buttonText)||"Search"});zt(()=>{y.value&&(b.value=!1)});const w=ye([]),O=se(!1);je(p,()=>{O.value=!1});const R=et(async()=>{if(n.value)return it(new Cs(n.value))},null),K=new Ks(16);Pt(()=>[h.value,p.value,b.value],async([m,f,T],A,C)=>{var ge,Ue,qe,Ge;(A==null?void 0:A[0])!==m&&K.clear();let M=!1;if(C(()=>{M=!0}),!m)return;w.value=m.search(f).slice(0,16),O.value=!0;const I=T?await Promise.all(w.value.map(B=>G(B.id))):[];if(M)return;for(const{id:B,mod:X}of I){const ee=B.slice(0,B.indexOf("#"));let Q=K.get(ee);if(Q)continue;Q=new Map,K.set(ee,Q);const U=X.default??X;if(U!=null&&U.render||U!=null&&U.setup){const te=Qt(U);te.config.warnHandler=()=>{},te.provide(Yt,i),Object.defineProperties(te.config.globalProperties,{$frontmatter:{get(){return i.frontmatter.value}},$params:{get(){return i.page.value.params}}});const He=document.createElement("div");te.mount(He),He.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(ce=>{var Ze;const be=(Ze=ce.querySelector("a"))==null?void 0:Ze.getAttribute("href"),Qe=(be==null?void 0:be.startsWith("#"))&&be.slice(1);if(!Qe)return;let Ye="";for(;(ce=ce.nextElementSibling)&&!/^h[1-6]$/i.test(ce.tagName);)Ye+=ce.outerHTML;Q.set(Qe,Ye)}),te.unmount()}if(M)return}const L=new Set;if(w.value=w.value.map(B=>{const[X,ee]=B.id.split("#"),Q=K.get(X),U=(Q==null?void 0:Q.get(ee))??"";for(const te in B.match)L.add(te);return{...B,text:U}}),await ue(),M)return;await new Promise(B=>{var X;(X=R.value)==null||X.unmark({done:()=>{var ee;(ee=R.value)==null||ee.markRegExp(E(L),{done:B})}})});const j=((ge=s.value)==null?void 0:ge.querySelectorAll(".result .excerpt"))??[];for(const B of j)(Ue=B.querySelector('mark[data-markjs="true"]'))==null||Ue.scrollIntoView({block:"center"});(Ge=(qe=n.value)==null?void 0:qe.firstElementChild)==null||Ge.scrollIntoView({block:"start"})},{debounce:200,immediate:!0});async function G(m){const f=Zt(m.slice(0,m.indexOf("#")));try{if(!f)throw new Error(`Cannot find file for id: ${m}`);return{id:m,mod:await import(f)}}catch(T){return console.error(T),{id:m,mod:{}}}}const W=se(),V=pe(()=>{var m;return((m=p.value)==null?void 0:m.length)<=0});function $(m=!0){var f,T;(f=W.value)==null||f.focus(),m&&((T=W.value)==null||T.select())}Ce(()=>{$()});function me(m){m.pointerType==="mouse"&&$()}const P=se(-1),H=se(!1);je(w,m=>{P.value=m.length?0:-1,J()});function J(){ue(()=>{const m=document.querySelector(".result.selected");m==null||m.scrollIntoView({block:"nearest"})})}we("ArrowUp",m=>{m.preventDefault(),P.value--,P.value<0&&(P.value=w.value.length-1),H.value=!0,J()}),we("ArrowDown",m=>{m.preventDefault(),P.value++,P.value>=w.value.length&&(P.value=0),H.value=!0,J()});const k=jt();we("Enter",m=>{if(m.isComposing||m.target instanceof HTMLButtonElement&&m.target.type!=="submit")return;const f=w.value[P.value];if(m.target instanceof HTMLInputElement&&!f){m.preventDefault();return}f&&(k.go(f.id),t("close"))}),we("Escape",()=>{t("close")});const u=ss({modal:{displayDetails:"Display detailed list",resetButtonTitle:"Reset search",backButtonTitle:"Close search",noResultsText:"No results for",footer:{selectText:"to select",selectKeyAriaLabel:"enter",navigateText:"to navigate",navigateUpKeyAriaLabel:"up arrow",navigateDownKeyAriaLabel:"down arrow",closeText:"to close",closeKeyAriaLabel:"escape"}}});Ce(()=>{window.history.pushState(null,"",null)}),Vt("popstate",m=>{m.preventDefault(),t("close")});const g=$t(Bt?document.body:null);Ce(()=>{ue(()=>{g.value=!0,ue().then(()=>o())})}),Wt(()=>{g.value=!1});function _(){p.value="",ue().then(()=>$(!1))}function E(m){return new RegExp([...m].sort((f,T)=>T.length-f.length).map(f=>`(${Xt(f)})`).join("|"),"gi")}return(m,f)=>{var T,A,C,M;return q(),Kt(Ht,{to:"body"},[S("div",{ref_key:"el",ref:s,role:"button","aria-owns":(T=w.value)!=null&&T.length?"localsearch-list":void 0,"aria-expanded":"true","aria-haspopup":"listbox","aria-labelledby":"localsearch-label",class:"VPLocalSearchBox"},[S("div",{class:"backdrop",onClick:f[0]||(f[0]=I=>m.$emit("close"))}),S("div",Us,[S("form",{class:"search-bar",onPointerup:f[4]||(f[4]=I=>me(I)),onSubmit:f[5]||(f[5]=Jt(()=>{},["prevent"]))},[S("label",{title:x.value,id:"localsearch-label",for:"localsearch-input"},f[8]||(f[8]=[S("span",{"aria-hidden":"true",class:"vpi-search search-icon local-search-icon"},null,-1)]),8,qs),S("div",Gs,[S("button",{class:"back-button",title:D(u)("modal.backButtonTitle"),onClick:f[1]||(f[1]=I=>m.$emit("close"))},f[9]||(f[9]=[S("span",{class:"vpi-arrow-left local-search-icon"},null,-1)]),8,Hs)]),Ut(S("input",{ref_key:"searchInput",ref:W,"onUpdate:modelValue":f[2]||(f[2]=I=>Gt(p)?p.value=I:null),placeholder:x.value,id:"localsearch-input","aria-labelledby":"localsearch-label",class:"search-input"},null,8,Qs),[[qt,D(p)]]),S("div",Ys,[y.value?xe("",!0):(q(),Y("button",{key:0,class:tt(["toggle-layout-button",{"detailed-list":D(b)}]),type:"button",title:D(u)("modal.displayDetails"),onClick:f[3]||(f[3]=I=>P.value>-1&&(b.value=!D(b)))},f[10]||(f[10]=[S("span",{class:"vpi-layout-list local-search-icon"},null,-1)]),10,Zs)),S("button",{class:"clear-button",type:"reset",disabled:V.value,title:D(u)("modal.resetButtonTitle"),onClick:_},f[11]||(f[11]=[S("span",{class:"vpi-delete local-search-icon"},null,-1)]),8,Xs)])],32),S("ul",{ref_key:"resultsEl",ref:n,id:(A=w.value)!=null&&A.length?"localsearch-list":void 0,role:(C=w.value)!=null&&C.length?"listbox":void 0,"aria-labelledby":(M=w.value)!=null&&M.length?"localsearch-label":void 0,class:"results",onMousemove:f[7]||(f[7]=I=>H.value=!1)},[(q(!0),Y(nt,null,st(w.value,(I,L)=>(q(),Y("li",{key:I.id,role:"option","aria-selected":P.value===L?"true":"false"},[S("a",{href:I.id,class:tt(["result",{selected:P.value===L}]),"aria-label":[...I.titles,I.title].join(" > "),onMouseenter:j=>!H.value&&(P.value=L),onFocusin:j=>P.value=L,onClick:f[6]||(f[6]=j=>m.$emit("close"))},[S("div",null,[S("div",nn,[f[13]||(f[13]=S("span",{class:"title-icon"},"#",-1)),(q(!0),Y(nt,null,st(I.titles,(j,ge)=>(q(),Y("span",{key:ge,class:"title"},[S("span",{class:"text",innerHTML:j},null,8,rn),f[12]||(f[12]=S("span",{class:"vpi-chevron-right local-search-icon"},null,-1))]))),128)),S("span",an,[S("span",{class:"text",innerHTML:I.title},null,8,on)])]),D(b)?(q(),Y("div",ln,[I.text?(q(),Y("div",cn,[S("div",{class:"vp-doc",innerHTML:I.text},null,8,un)])):xe("",!0),f[14]||(f[14]=S("div",{class:"excerpt-gradient-bottom"},null,-1)),f[15]||(f[15]=S("div",{class:"excerpt-gradient-top"},null,-1))])):xe("",!0)])],42,sn)],8,tn))),128)),D(p)&&!w.value.length&&O.value?(q(),Y("li",dn,[de(he(D(u)("modal.noResultsText"))+' "',1),S("strong",null,he(D(p)),1),f[16]||(f[16]=de('" '))])):xe("",!0)],40,en),S("div",hn,[S("span",null,[S("kbd",{"aria-label":D(u)("modal.footer.navigateUpKeyAriaLabel")},f[17]||(f[17]=[S("span",{class:"vpi-arrow-up navigate-icon"},null,-1)]),8,fn),S("kbd",{"aria-label":D(u)("modal.footer.navigateDownKeyAriaLabel")},f[18]||(f[18]=[S("span",{class:"vpi-arrow-down navigate-icon"},null,-1)]),8,pn),de(" "+he(D(u)("modal.footer.navigateText")),1)]),S("span",null,[S("kbd",{"aria-label":D(u)("modal.footer.selectKeyAriaLabel")},f[19]||(f[19]=[S("span",{class:"vpi-corner-down-left navigate-icon"},null,-1)]),8,vn),de(" "+he(D(u)("modal.footer.selectText")),1)]),S("span",null,[S("kbd",{"aria-label":D(u)("modal.footer.closeKeyAriaLabel")},"esc",8,mn),de(" "+he(D(u)("modal.footer.closeText")),1)])])])],8,Js)])}}}),_n=es(gn,[["__scopeId","data-v-797a7f7c"]]);export{_n as default}; diff --git a/assets/chunks/framework.CBrKbnPu.js b/assets/chunks/framework.CBrKbnPu.js new file mode 100644 index 0000000..cf6ad19 --- /dev/null +++ b/assets/chunks/framework.CBrKbnPu.js @@ -0,0 +1,18 @@ +/** +* @vue/shared v3.5.8 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function Hr(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const ee={},Tt=[],Ue=()=>{},zo=()=>!1,Zt=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),$r=e=>e.startsWith("onUpdate:"),fe=Object.assign,Dr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Jo=Object.prototype.hasOwnProperty,J=(e,t)=>Jo.call(e,t),K=Array.isArray,Ct=e=>Fn(e)==="[object Map]",fi=e=>Fn(e)==="[object Set]",q=e=>typeof e=="function",se=e=>typeof e=="string",rt=e=>typeof e=="symbol",ne=e=>e!==null&&typeof e=="object",ui=e=>(ne(e)||q(e))&&q(e.then)&&q(e.catch),di=Object.prototype.toString,Fn=e=>di.call(e),Qo=e=>Fn(e).slice(8,-1),hi=e=>Fn(e)==="[object Object]",jr=e=>se(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,At=Hr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Hn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Zo=/-(\w)/g,Ne=Hn(e=>e.replace(Zo,(t,n)=>n?n.toUpperCase():"")),el=/\B([A-Z])/g,st=Hn(e=>e.replace(el,"-$1").toLowerCase()),$n=Hn(e=>e.charAt(0).toUpperCase()+e.slice(1)),wn=Hn(e=>e?`on${$n(e)}`:""),tt=(e,t)=>!Object.is(e,t),Sn=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:r,value:n})},wr=e=>{const t=parseFloat(e);return isNaN(t)?e:t},tl=e=>{const t=se(e)?Number(e):NaN;return isNaN(t)?e:t};let hs;const gi=()=>hs||(hs=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Vr(e){if(K(e)){const t={};for(let n=0;n{if(n){const r=n.split(rl);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function Ur(e){let t="";if(se(e))t=e;else if(K(e))for(let n=0;n!!(e&&e.__v_isRef===!0),cl=e=>se(e)?e:e==null?"":K(e)||ne(e)&&(e.toString===di||!q(e.toString))?yi(e)?cl(e.value):JSON.stringify(e,vi,2):String(e),vi=(e,t)=>yi(t)?vi(e,t.value):Ct(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,s],i)=>(n[Zn(r,i)+" =>"]=s,n),{})}:fi(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>Zn(n))}:rt(t)?Zn(t):ne(t)&&!K(t)&&!hi(t)?String(t):t,Zn=(e,t="")=>{var n;return rt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.8 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let _e;class al{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=_e,!t&&_e&&(this.index=(_e.scopes||(_e.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0)return;let e;for(;Dt;){let t=Dt;for(Dt=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(r){e||(e=r)}t=n}}if(e)throw e}function Ei(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function xi(e,t=!1){let n,r=e.depsTail,s=r;for(;s;){const i=s.prevDep;s.version===-1?(s===r&&(r=i),Wr(s,t),ul(s)):n=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=i}e.deps=n,e.depsTail=r}function Sr(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Ti(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Ti(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Wt))return;e.globalVersion=Wt;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&e.deps&&!Sr(e)){e.flags&=-3;return}const n=Z,r=Le;Z=e,Le=!0;try{Ei(e);const s=e.fn(e._value);(t.version===0||tt(s,e._value))&&(e._value=s,t.version++)}catch(s){throw t.version++,s}finally{Z=n,Le=r,xi(e,!0),e.flags&=-3}}function Wr(e,t=!1){const{dep:n,prevSub:r,nextSub:s}=e;if(r&&(r.nextSub=s,e.prevSub=void 0),s&&(s.prevSub=r,e.nextSub=void 0),n.subs===e&&(n.subs=r),!n.subs)if(n.computed){n.computed.flags&=-5;for(let i=n.computed.deps;i;i=i.nextDep)Wr(i,!0)}else n.map&&!t&&(n.map.delete(n.key),n.map.size||Kt.delete(n.target))}function ul(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let Le=!0;const Ci=[];function it(){Ci.push(Le),Le=!1}function ot(){const e=Ci.pop();Le=e===void 0?!0:e}function ps(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Z;Z=void 0;try{t()}finally{Z=n}}}let Wt=0;class dl{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Dn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.target=void 0,this.map=void 0,this.key=void 0}track(t){if(!Z||!Le||Z===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Z)n=this.activeLink=new dl(Z,this),Z.deps?(n.prevDep=Z.depsTail,Z.depsTail.nextDep=n,Z.depsTail=n):Z.deps=Z.depsTail=n,Z.flags&4&&Ai(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const r=n.nextDep;r.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=r),n.prevDep=Z.depsTail,n.nextDep=void 0,Z.depsTail.nextDep=n,Z.depsTail=n,Z.deps===n&&(Z.deps=r)}return n}trigger(t){this.version++,Wt++,this.notify(t)}notify(t){kr();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Br()}}}function Ai(e){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let r=t.deps;r;r=r.nextDep)Ai(r)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}const Kt=new WeakMap,ht=Symbol(""),Er=Symbol(""),qt=Symbol("");function ve(e,t,n){if(Le&&Z){let r=Kt.get(e);r||Kt.set(e,r=new Map);let s=r.get(n);s||(r.set(n,s=new Dn),s.target=e,s.map=r,s.key=n),s.track()}}function Ge(e,t,n,r,s,i){const o=Kt.get(e);if(!o){Wt++;return}const l=c=>{c&&c.trigger()};if(kr(),t==="clear")o.forEach(l);else{const c=K(e),f=c&&jr(n);if(c&&n==="length"){const a=Number(r);o.forEach((h,g)=>{(g==="length"||g===qt||!rt(g)&&g>=a)&&l(h)})}else switch(n!==void 0&&l(o.get(n)),f&&l(o.get(qt)),t){case"add":c?f&&l(o.get("length")):(l(o.get(ht)),Ct(e)&&l(o.get(Er)));break;case"delete":c||(l(o.get(ht)),Ct(e)&&l(o.get(Er)));break;case"set":Ct(e)&&l(o.get(ht));break}}Br()}function hl(e,t){var n;return(n=Kt.get(e))==null?void 0:n.get(t)}function _t(e){const t=z(e);return t===e?t:(ve(t,"iterate",qt),Pe(e)?t:t.map(me))}function jn(e){return ve(e=z(e),"iterate",qt),e}const pl={__proto__:null,[Symbol.iterator](){return tr(this,Symbol.iterator,me)},concat(...e){return _t(this).concat(...e.map(t=>K(t)?_t(t):t))},entries(){return tr(this,"entries",e=>(e[1]=me(e[1]),e))},every(e,t){return We(this,"every",e,t,void 0,arguments)},filter(e,t){return We(this,"filter",e,t,n=>n.map(me),arguments)},find(e,t){return We(this,"find",e,t,me,arguments)},findIndex(e,t){return We(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return We(this,"findLast",e,t,me,arguments)},findLastIndex(e,t){return We(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return We(this,"forEach",e,t,void 0,arguments)},includes(...e){return nr(this,"includes",e)},indexOf(...e){return nr(this,"indexOf",e)},join(e){return _t(this).join(e)},lastIndexOf(...e){return nr(this,"lastIndexOf",e)},map(e,t){return We(this,"map",e,t,void 0,arguments)},pop(){return Ft(this,"pop")},push(...e){return Ft(this,"push",e)},reduce(e,...t){return gs(this,"reduce",e,t)},reduceRight(e,...t){return gs(this,"reduceRight",e,t)},shift(){return Ft(this,"shift")},some(e,t){return We(this,"some",e,t,void 0,arguments)},splice(...e){return Ft(this,"splice",e)},toReversed(){return _t(this).toReversed()},toSorted(e){return _t(this).toSorted(e)},toSpliced(...e){return _t(this).toSpliced(...e)},unshift(...e){return Ft(this,"unshift",e)},values(){return tr(this,"values",me)}};function tr(e,t,n){const r=jn(e),s=r[t]();return r!==e&&!Pe(e)&&(s._next=s.next,s.next=()=>{const i=s._next();return i.value&&(i.value=n(i.value)),i}),s}const gl=Array.prototype;function We(e,t,n,r,s,i){const o=jn(e),l=o!==e&&!Pe(e),c=o[t];if(c!==gl[t]){const h=c.apply(e,i);return l?me(h):h}let f=n;o!==e&&(l?f=function(h,g){return n.call(this,me(h),g,e)}:n.length>2&&(f=function(h,g){return n.call(this,h,g,e)}));const a=c.call(o,f,r);return l&&s?s(a):a}function gs(e,t,n,r){const s=jn(e);let i=n;return s!==e&&(Pe(e)?n.length>3&&(i=function(o,l,c){return n.call(this,o,l,c,e)}):i=function(o,l,c){return n.call(this,o,me(l),c,e)}),s[t](i,...r)}function nr(e,t,n){const r=z(e);ve(r,"iterate",qt);const s=r[t](...n);return(s===-1||s===!1)&&Yr(n[0])?(n[0]=z(n[0]),r[t](...n)):s}function Ft(e,t,n=[]){it(),kr();const r=z(e)[t].apply(e,n);return Br(),ot(),r}const ml=Hr("__proto__,__v_isRef,__isVue"),Ri=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(rt));function yl(e){rt(e)||(e=String(e));const t=z(this);return ve(t,"has",e),t.hasOwnProperty(e)}class Oi{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,r){const s=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return i;if(n==="__v_raw")return r===(s?i?Ml:Li:i?Ii:Pi).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(r)?t:void 0;const o=K(t);if(!s){let c;if(o&&(c=pl[n]))return c;if(n==="hasOwnProperty")return yl}const l=Reflect.get(t,n,ae(t)?t:r);return(rt(n)?Ri.has(n):ml(n))||(s||ve(t,"get",n),i)?l:ae(l)?o&&jr(n)?l:l.value:ne(l)?s?kn(l):Un(l):l}}class Mi extends Oi{constructor(t=!1){super(!1,t)}set(t,n,r,s){let i=t[n];if(!this._isShallow){const c=vt(i);if(!Pe(r)&&!vt(r)&&(i=z(i),r=z(r)),!K(t)&&ae(i)&&!ae(r))return c?!1:(i.value=r,!0)}const o=K(t)&&jr(n)?Number(n)e,Vn=e=>Reflect.getPrototypeOf(e);function cn(e,t,n=!1,r=!1){e=e.__v_raw;const s=z(e),i=z(t);n||(tt(t,i)&&ve(s,"get",t),ve(s,"get",i));const{has:o}=Vn(s),l=r?Kr:n?Xr:me;if(o.call(s,t))return l(e.get(t));if(o.call(s,i))return l(e.get(i));e!==s&&e.get(t)}function an(e,t=!1){const n=this.__v_raw,r=z(n),s=z(e);return t||(tt(e,s)&&ve(r,"has",e),ve(r,"has",s)),e===s?n.has(e):n.has(e)||n.has(s)}function fn(e,t=!1){return e=e.__v_raw,!t&&ve(z(e),"iterate",ht),Reflect.get(e,"size",e)}function ms(e,t=!1){!t&&!Pe(e)&&!vt(e)&&(e=z(e));const n=z(this);return Vn(n).has.call(n,e)||(n.add(e),Ge(n,"add",e,e)),this}function ys(e,t,n=!1){!n&&!Pe(t)&&!vt(t)&&(t=z(t));const r=z(this),{has:s,get:i}=Vn(r);let o=s.call(r,e);o||(e=z(e),o=s.call(r,e));const l=i.call(r,e);return r.set(e,t),o?tt(t,l)&&Ge(r,"set",e,t):Ge(r,"add",e,t),this}function vs(e){const t=z(this),{has:n,get:r}=Vn(t);let s=n.call(t,e);s||(e=z(e),s=n.call(t,e)),r&&r.call(t,e);const i=t.delete(e);return s&&Ge(t,"delete",e,void 0),i}function bs(){const e=z(this),t=e.size!==0,n=e.clear();return t&&Ge(e,"clear",void 0,void 0),n}function un(e,t){return function(r,s){const i=this,o=i.__v_raw,l=z(o),c=t?Kr:e?Xr:me;return!e&&ve(l,"iterate",ht),o.forEach((f,a)=>r.call(s,c(f),c(a),i))}}function dn(e,t,n){return function(...r){const s=this.__v_raw,i=z(s),o=Ct(i),l=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,f=s[e](...r),a=n?Kr:t?Xr:me;return!t&&ve(i,"iterate",c?Er:ht),{next(){const{value:h,done:g}=f.next();return g?{value:h,done:g}:{value:l?[a(h[0]),a(h[1])]:a(h),done:g}},[Symbol.iterator](){return this}}}}function Xe(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Sl(){const e={get(i){return cn(this,i)},get size(){return fn(this)},has:an,add:ms,set:ys,delete:vs,clear:bs,forEach:un(!1,!1)},t={get(i){return cn(this,i,!1,!0)},get size(){return fn(this)},has:an,add(i){return ms.call(this,i,!0)},set(i,o){return ys.call(this,i,o,!0)},delete:vs,clear:bs,forEach:un(!1,!0)},n={get(i){return cn(this,i,!0)},get size(){return fn(this,!0)},has(i){return an.call(this,i,!0)},add:Xe("add"),set:Xe("set"),delete:Xe("delete"),clear:Xe("clear"),forEach:un(!0,!1)},r={get(i){return cn(this,i,!0,!0)},get size(){return fn(this,!0)},has(i){return an.call(this,i,!0)},add:Xe("add"),set:Xe("set"),delete:Xe("delete"),clear:Xe("clear"),forEach:un(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(i=>{e[i]=dn(i,!1,!1),n[i]=dn(i,!0,!1),t[i]=dn(i,!1,!0),r[i]=dn(i,!0,!0)}),[e,n,t,r]}const[El,xl,Tl,Cl]=Sl();function qr(e,t){const n=t?e?Cl:Tl:e?xl:El;return(r,s,i)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?r:Reflect.get(J(n,s)&&s in r?n:r,s,i)}const Al={get:qr(!1,!1)},Rl={get:qr(!1,!0)},Ol={get:qr(!0,!1)};const Pi=new WeakMap,Ii=new WeakMap,Li=new WeakMap,Ml=new WeakMap;function Pl(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Il(e){return e.__v_skip||!Object.isExtensible(e)?0:Pl(Qo(e))}function Un(e){return vt(e)?e:Gr(e,!1,bl,Al,Pi)}function Ll(e){return Gr(e,!1,wl,Rl,Ii)}function kn(e){return Gr(e,!0,_l,Ol,Li)}function Gr(e,t,n,r,s){if(!ne(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=s.get(e);if(i)return i;const o=Il(e);if(o===0)return e;const l=new Proxy(e,o===2?r:n);return s.set(e,l),l}function pt(e){return vt(e)?pt(e.__v_raw):!!(e&&e.__v_isReactive)}function vt(e){return!!(e&&e.__v_isReadonly)}function Pe(e){return!!(e&&e.__v_isShallow)}function Yr(e){return e?!!e.__v_raw:!1}function z(e){const t=e&&e.__v_raw;return t?z(t):e}function En(e){return!J(e,"__v_skip")&&Object.isExtensible(e)&&pi(e,"__v_skip",!0),e}const me=e=>ne(e)?Un(e):e,Xr=e=>ne(e)?kn(e):e;function ae(e){return e?e.__v_isRef===!0:!1}function oe(e){return Ni(e,!1)}function zr(e){return Ni(e,!0)}function Ni(e,t){return ae(e)?e:new Nl(e,t)}class Nl{constructor(t,n){this.dep=new Dn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:z(t),this._value=n?t:me(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,r=this.__v_isShallow||Pe(t)||vt(t);t=r?t:z(t),tt(t,n)&&(this._rawValue=t,this._value=r?t:me(t),this.dep.trigger())}}function Fi(e){return ae(e)?e.value:e}const Fl={get:(e,t,n)=>t==="__v_raw"?e:Fi(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const s=e[t];return ae(s)&&!ae(n)?(s.value=n,!0):Reflect.set(e,t,n,r)}};function Hi(e){return pt(e)?e:new Proxy(e,Fl)}class Hl{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new Dn,{get:r,set:s}=t(n.track.bind(n),n.trigger.bind(n));this._get=r,this._set=s}get value(){return this._value=this._get()}set value(t){this._set(t)}}function $l(e){return new Hl(e)}class Dl{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0,this._value=void 0}get value(){const t=this._object[this._key];return this._value=t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return hl(z(this._object),this._key)}}class jl{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function Vl(e,t,n){return ae(e)?e:q(e)?new jl(e):ne(e)&&arguments.length>1?Ul(e,t,n):oe(e)}function Ul(e,t,n){const r=e[t];return ae(r)?r:new Dl(e,t,n)}class kl{constructor(t,n,r){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Dn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Wt-1,this.effect=this,this.__v_isReadonly=!n,this.isSSR=r}notify(){if(this.flags|=16,!(this.flags&8)&&Z!==this)return Si(this),!0}get value(){const t=this.dep.track();return Ti(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Bl(e,t,n=!1){let r,s;return q(e)?r=e:(r=e.get,s=e.set),new kl(r,s,n)}const hn={},Rn=new WeakMap;let ut;function Wl(e,t=!1,n=ut){if(n){let r=Rn.get(n);r||Rn.set(n,r=[]),r.push(e)}}function Kl(e,t,n=ee){const{immediate:r,deep:s,once:i,scheduler:o,augmentJob:l,call:c}=n,f=m=>s?m:Pe(m)||s===!1||s===0?qe(m,1):qe(m);let a,h,g,v,_=!1,S=!1;if(ae(e)?(h=()=>e.value,_=Pe(e)):pt(e)?(h=()=>f(e),_=!0):K(e)?(S=!0,_=e.some(m=>pt(m)||Pe(m)),h=()=>e.map(m=>{if(ae(m))return m.value;if(pt(m))return f(m);if(q(m))return c?c(m,2):m()})):q(e)?t?h=c?()=>c(e,2):e:h=()=>{if(g){it();try{g()}finally{ot()}}const m=ut;ut=a;try{return c?c(e,3,[v]):e(v)}finally{ut=m}}:h=Ue,t&&s){const m=h,M=s===!0?1/0:s;h=()=>qe(m(),M)}const U=bi(),N=()=>{a.stop(),U&&Dr(U.effects,a)};if(i&&t){const m=t;t=(...M)=>{m(...M),N()}}let k=S?new Array(e.length).fill(hn):hn;const p=m=>{if(!(!(a.flags&1)||!a.dirty&&!m))if(t){const M=a.run();if(s||_||(S?M.some((F,$)=>tt(F,k[$])):tt(M,k))){g&&g();const F=ut;ut=a;try{const $=[M,k===hn?void 0:S&&k[0]===hn?[]:k,v];c?c(t,3,$):t(...$),k=M}finally{ut=F}}}else a.run()};return l&&l(p),a=new _i(h),a.scheduler=o?()=>o(p,!1):p,v=m=>Wl(m,!1,a),g=a.onStop=()=>{const m=Rn.get(a);if(m){if(c)c(m,4);else for(const M of m)M();Rn.delete(a)}},t?r?p(!0):k=a.run():o?o(p.bind(null,!0),!0):a.run(),N.pause=a.pause.bind(a),N.resume=a.resume.bind(a),N.stop=N,N}function qe(e,t=1/0,n){if(t<=0||!ne(e)||e.__v_skip||(n=n||new Set,n.has(e)))return e;if(n.add(e),t--,ae(e))qe(e.value,t,n);else if(K(e))for(let r=0;r{qe(r,t,n)});else if(hi(e)){for(const r in e)qe(e[r],t,n);for(const r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&qe(e[r],t,n)}return e}/** +* @vue/runtime-core v3.5.8 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function en(e,t,n,r){try{return r?e(...r):e()}catch(s){tn(s,t,n)}}function Fe(e,t,n,r){if(q(e)){const s=en(e,t,n,r);return s&&ui(s)&&s.catch(i=>{tn(i,t,n)}),s}if(K(e)){const s=[];for(let i=0;i>>1,s=we[r],i=Yt(s);i=Yt(n)?we.push(e):we.splice(Gl(t),0,e),e.flags|=1,Di()}}function Di(){!Gt&&!xr&&(xr=!0,Jr=$i.then(ji))}function Yl(e){K(e)?Rt.push(...e):Qe&&e.id===-1?Qe.splice(St+1,0,e):e.flags&1||(Rt.push(e),e.flags|=1),Di()}function _s(e,t,n=Gt?je+1:0){for(;nYt(n)-Yt(r));if(Rt.length=0,Qe){Qe.push(...t);return}for(Qe=t,St=0;Ste.id==null?e.flags&2?-1:1/0:e.id;function ji(e){xr=!1,Gt=!0;try{for(je=0;je{r._d&&Ns(-1);const i=Mn(t);let o;try{o=e(...s)}finally{Mn(i),r._d&&Ns(1)}return o};return r._n=!0,r._c=!0,r._d=!0,r}function If(e,t){if(de===null)return e;const n=Xn(de),r=e.dirs||(e.dirs=[]);for(let s=0;se.__isTeleport,jt=e=>e&&(e.disabled||e.disabled===""),zl=e=>e&&(e.defer||e.defer===""),ws=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Ss=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Tr=(e,t)=>{const n=e&&e.to;return se(n)?t?t(n):null:n},Jl={name:"Teleport",__isTeleport:!0,process(e,t,n,r,s,i,o,l,c,f){const{mc:a,pc:h,pbc:g,o:{insert:v,querySelector:_,createText:S,createComment:U}}=f,N=jt(t.props);let{shapeFlag:k,children:p,dynamicChildren:m}=t;if(e==null){const M=t.el=S(""),F=t.anchor=S("");v(M,n,r),v(F,n,r);const $=(R,b)=>{k&16&&(s&&s.isCE&&(s.ce._teleportTarget=R),a(p,R,b,s,i,o,l,c))},j=()=>{const R=t.target=Tr(t.props,_),b=Bi(R,t,S,v);R&&(o!=="svg"&&ws(R)?o="svg":o!=="mathml"&&Ss(R)&&(o="mathml"),N||($(R,b),xn(t)))};N&&($(n,F),xn(t)),zl(t.props)?Ee(j,i):j()}else{t.el=e.el,t.targetStart=e.targetStart;const M=t.anchor=e.anchor,F=t.target=e.target,$=t.targetAnchor=e.targetAnchor,j=jt(e.props),R=j?n:F,b=j?M:$;if(o==="svg"||ws(F)?o="svg":(o==="mathml"||Ss(F))&&(o="mathml"),m?(g(e.dynamicChildren,m,R,s,i,o,l),rs(e,t,!0)):c||h(e,t,R,b,s,i,o,l,!1),N)j?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):pn(t,n,M,f,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const L=t.target=Tr(t.props,_);L&&pn(t,L,null,f,0)}else j&&pn(t,F,$,f,1);xn(t)}},remove(e,t,n,{um:r,o:{remove:s}},i){const{shapeFlag:o,children:l,anchor:c,targetStart:f,targetAnchor:a,target:h,props:g}=e;if(h&&(s(f),s(a)),i&&s(c),o&16){const v=i||!jt(g);for(let _=0;_{e.isMounted=!0}),zi(()=>{e.isUnmounting=!0}),e}const Re=[Function,Array],Wi={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Re,onEnter:Re,onAfterEnter:Re,onEnterCancelled:Re,onBeforeLeave:Re,onLeave:Re,onAfterLeave:Re,onLeaveCancelled:Re,onBeforeAppear:Re,onAppear:Re,onAfterAppear:Re,onAppearCancelled:Re},Ki=e=>{const t=e.subTree;return t.component?Ki(t.component):t},ec={name:"BaseTransition",props:Wi,setup(e,{slots:t}){const n=Yn(),r=Zl();return()=>{const s=t.default&&Yi(t.default(),!0);if(!s||!s.length)return;const i=qi(s),o=z(e),{mode:l}=o;if(r.isLeaving)return rr(i);const c=Es(i);if(!c)return rr(i);let f=Cr(c,o,r,n,g=>f=g);c.type!==ye&&Xt(c,f);const a=n.subTree,h=a&&Es(a);if(h&&h.type!==ye&&!dt(c,h)&&Ki(n).type!==ye){const g=Cr(h,o,r,n);if(Xt(h,g),l==="out-in"&&c.type!==ye)return r.isLeaving=!0,g.afterLeave=()=>{r.isLeaving=!1,n.job.flags&8||n.update(),delete g.afterLeave},rr(i);l==="in-out"&&c.type!==ye&&(g.delayLeave=(v,_,S)=>{const U=Gi(r,h);U[String(h.key)]=h,v[Ze]=()=>{_(),v[Ze]=void 0,delete f.delayedLeave},f.delayedLeave=S})}return i}}};function qi(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==ye){t=n;break}}return t}const tc=ec;function Gi(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function Cr(e,t,n,r,s){const{appear:i,mode:o,persisted:l=!1,onBeforeEnter:c,onEnter:f,onAfterEnter:a,onEnterCancelled:h,onBeforeLeave:g,onLeave:v,onAfterLeave:_,onLeaveCancelled:S,onBeforeAppear:U,onAppear:N,onAfterAppear:k,onAppearCancelled:p}=t,m=String(e.key),M=Gi(n,e),F=(R,b)=>{R&&Fe(R,r,9,b)},$=(R,b)=>{const L=b[1];F(R,b),K(R)?R.every(x=>x.length<=1)&&L():R.length<=1&&L()},j={mode:o,persisted:l,beforeEnter(R){let b=c;if(!n.isMounted)if(i)b=U||c;else return;R[Ze]&&R[Ze](!0);const L=M[m];L&&dt(e,L)&&L.el[Ze]&&L.el[Ze](),F(b,[R])},enter(R){let b=f,L=a,x=h;if(!n.isMounted)if(i)b=N||f,L=k||a,x=p||h;else return;let W=!1;const re=R[gn]=ce=>{W||(W=!0,ce?F(x,[R]):F(L,[R]),j.delayedLeave&&j.delayedLeave(),R[gn]=void 0)};b?$(b,[R,re]):re()},leave(R,b){const L=String(e.key);if(R[gn]&&R[gn](!0),n.isUnmounting)return b();F(g,[R]);let x=!1;const W=R[Ze]=re=>{x||(x=!0,b(),re?F(S,[R]):F(_,[R]),R[Ze]=void 0,M[L]===e&&delete M[L])};M[L]=e,v?$(v,[R,W]):W()},clone(R){const b=Cr(R,t,n,r,s);return s&&s(b),b}};return j}function rr(e){if(nn(e))return e=nt(e),e.children=null,e}function Es(e){if(!nn(e))return ki(e.type)&&e.children?qi(e.children):e;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&q(n.default))return n.default()}}function Xt(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Xt(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Yi(e,t=!1,n){let r=[],s=0;for(let i=0;i1)for(let i=0;iPn(_,t&&(K(t)?t[S]:t),n,r,s));return}if(gt(r)&&!s)return;const i=r.shapeFlag&4?Xn(r.component):r.el,o=s?null:i,{i:l,r:c}=e,f=t&&t.r,a=l.refs===ee?l.refs={}:l.refs,h=l.setupState,g=z(h),v=h===ee?()=>!1:_=>J(g,_);if(f!=null&&f!==c&&(se(f)?(a[f]=null,v(f)&&(h[f]=null)):ae(f)&&(f.value=null)),q(c))en(c,l,12,[o,a]);else{const _=se(c),S=ae(c);if(_||S){const U=()=>{if(e.f){const N=_?v(c)?h[c]:a[c]:c.value;s?K(N)&&Dr(N,i):K(N)?N.includes(i)||N.push(i):_?(a[c]=[i],v(c)&&(h[c]=a[c])):(c.value=[i],e.k&&(a[e.k]=c.value))}else _?(a[c]=o,v(c)&&(h[c]=o)):S&&(c.value=o,e.k&&(a[e.k]=o))};o?(U.id=-1,Ee(U,n)):U()}}}let xs=!1;const wt=()=>{xs||(console.error("Hydration completed but contains mismatches."),xs=!0)},nc=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",rc=e=>e.namespaceURI.includes("MathML"),mn=e=>{if(e.nodeType===1){if(nc(e))return"svg";if(rc(e))return"mathml"}},xt=e=>e.nodeType===8;function sc(e){const{mt:t,p:n,o:{patchProp:r,createText:s,nextSibling:i,parentNode:o,remove:l,insert:c,createComment:f}}=e,a=(p,m)=>{if(!m.hasChildNodes()){n(null,p,m),On(),m._vnode=p;return}h(m.firstChild,p,null,null,null),On(),m._vnode=p},h=(p,m,M,F,$,j=!1)=>{j=j||!!m.dynamicChildren;const R=xt(p)&&p.data==="[",b=()=>S(p,m,M,F,$,R),{type:L,ref:x,shapeFlag:W,patchFlag:re}=m;let ce=p.nodeType;m.el=p,re===-2&&(j=!1,m.dynamicChildren=null);let V=null;switch(L){case mt:ce!==3?m.children===""?(c(m.el=s(""),o(p),p),V=p):V=b():(p.data!==m.children&&(wt(),p.data=m.children),V=i(p));break;case ye:k(p)?(V=i(p),N(m.el=p.content.firstChild,p,M)):ce!==8||R?V=b():V=i(p);break;case Ut:if(R&&(p=i(p),ce=p.nodeType),ce===1||ce===3){V=p;const Y=!m.children.length;for(let D=0;D{j=j||!!m.dynamicChildren;const{type:R,props:b,patchFlag:L,shapeFlag:x,dirs:W,transition:re}=m,ce=R==="input"||R==="option";if(ce||L!==-1){W&&Ve(m,null,M,"created");let V=!1;if(k(p)){V=po(F,re)&&M&&M.vnode.props&&M.vnode.props.appear;const D=p.content.firstChild;V&&re.beforeEnter(D),N(D,p,M),m.el=p=D}if(x&16&&!(b&&(b.innerHTML||b.textContent))){let D=v(p.firstChild,m,p,M,F,$,j);for(;D;){yn(p,1)||wt();const he=D;D=D.nextSibling,l(he)}}else if(x&8){let D=m.children;D[0]===` +`&&(p.tagName==="PRE"||p.tagName==="TEXTAREA")&&(D=D.slice(1)),p.textContent!==D&&(yn(p,0)||wt(),p.textContent=m.children)}if(b){if(ce||!j||L&48){const D=p.tagName.includes("-");for(const he in b)(ce&&(he.endsWith("value")||he==="indeterminate")||Zt(he)&&!At(he)||he[0]==="."||D)&&r(p,he,null,b[he],void 0,M)}else if(b.onClick)r(p,"onClick",null,b.onClick,void 0,M);else if(L&4&&pt(b.style))for(const D in b.style)b.style[D]}let Y;(Y=b&&b.onVnodeBeforeMount)&&Oe(Y,M,m),W&&Ve(m,null,M,"beforeMount"),((Y=b&&b.onVnodeMounted)||W||V)&&bo(()=>{Y&&Oe(Y,M,m),V&&re.enter(p),W&&Ve(m,null,M,"mounted")},F)}return p.nextSibling},v=(p,m,M,F,$,j,R)=>{R=R||!!m.dynamicChildren;const b=m.children,L=b.length;for(let x=0;x{const{slotScopeIds:R}=m;R&&($=$?$.concat(R):R);const b=o(p),L=v(i(p),m,b,M,F,$,j);return L&&xt(L)&&L.data==="]"?i(m.anchor=L):(wt(),c(m.anchor=f("]"),b,L),L)},S=(p,m,M,F,$,j)=>{if(yn(p.parentElement,1)||wt(),m.el=null,j){const L=U(p);for(;;){const x=i(p);if(x&&x!==L)l(x);else break}}const R=i(p),b=o(p);return l(p),n(null,m,b,R,M,F,mn(b),$),R},U=(p,m="[",M="]")=>{let F=0;for(;p;)if(p=i(p),p&&xt(p)&&(p.data===m&&F++,p.data===M)){if(F===0)return i(p);F--}return p},N=(p,m,M)=>{const F=m.parentNode;F&&F.replaceChild(p,m);let $=M;for(;$;)$.vnode.el===m&&($.vnode.el=$.subTree.el=p),$=$.parent},k=p=>p.nodeType===1&&p.tagName==="TEMPLATE";return[a,h]}const Ts="data-allow-mismatch",ic={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function yn(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(Ts);)e=e.parentElement;const n=e&&e.getAttribute(Ts);if(n==null)return!1;if(n==="")return!0;{const r=n.split(",");return t===0&&r.includes("children")?!0:n.split(",").includes(ic[t])}}function oc(e,t){if(xt(e)&&e.data==="["){let n=1,r=e.nextSibling;for(;r;){if(r.nodeType===1){if(t(r)===!1)break}else if(xt(r))if(r.data==="]"){if(--n===0)break}else r.data==="["&&n++;r=r.nextSibling}}else t(e)}const gt=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function Nf(e){q(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:s=200,hydrate:i,timeout:o,suspensible:l=!0,onError:c}=e;let f=null,a,h=0;const g=()=>(h++,f=null,v()),v=()=>{let _;return f||(_=f=t().catch(S=>{if(S=S instanceof Error?S:new Error(String(S)),c)return new Promise((U,N)=>{c(S,()=>U(g()),()=>N(S),h+1)});throw S}).then(S=>_!==f&&f?f:(S&&(S.__esModule||S[Symbol.toStringTag]==="Module")&&(S=S.default),a=S,S)))};return Zr({name:"AsyncComponentWrapper",__asyncLoader:v,__asyncHydrate(_,S,U){const N=i?()=>{const k=i(U,p=>oc(_,p));k&&(S.bum||(S.bum=[])).push(k)}:U;a?N():v().then(()=>!S.isUnmounted&&N())},get __asyncResolved(){return a},setup(){const _=ue;if(es(_),a)return()=>sr(a,_);const S=p=>{f=null,tn(p,_,13,!r)};if(l&&_.suspense||sn)return v().then(p=>()=>sr(p,_)).catch(p=>(S(p),()=>r?le(r,{error:p}):null));const U=oe(!1),N=oe(),k=oe(!!s);return s&&setTimeout(()=>{k.value=!1},s),o!=null&&setTimeout(()=>{if(!U.value&&!N.value){const p=new Error(`Async component timed out after ${o}ms.`);S(p),N.value=p}},o),v().then(()=>{U.value=!0,_.parent&&nn(_.parent.vnode)&&_.parent.update()}).catch(p=>{S(p),N.value=p}),()=>{if(U.value&&a)return sr(a,_);if(N.value&&r)return le(r,{error:N.value});if(n&&!k.value)return le(n)}}})}function sr(e,t){const{ref:n,props:r,children:s,ce:i}=t.vnode,o=le(e,r,s);return o.ref=n,o.ce=i,delete t.vnode.ce,o}const nn=e=>e.type.__isKeepAlive;function lc(e,t){Xi(e,"a",t)}function cc(e,t){Xi(e,"da",t)}function Xi(e,t,n=ue){const r=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(Wn(t,r,n),n){let s=n.parent;for(;s&&s.parent;)nn(s.parent.vnode)&&ac(r,t,n,s),s=s.parent}}function ac(e,t,n,r){const s=Wn(t,e,r,!0);Kn(()=>{Dr(r[t],s)},n)}function Wn(e,t,n=ue,r=!1){if(n){const s=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{it();const l=rn(n),c=Fe(t,n,e,o);return l(),ot(),c});return r?s.unshift(i):s.push(i),i}}const Ye=e=>(t,n=ue)=>{(!sn||e==="sp")&&Wn(e,(...r)=>t(...r),n)},fc=Ye("bm"),It=Ye("m"),uc=Ye("bu"),dc=Ye("u"),zi=Ye("bum"),Kn=Ye("um"),hc=Ye("sp"),pc=Ye("rtg"),gc=Ye("rtc");function mc(e,t=ue){Wn("ec",e,t)}const Ji="components";function Ff(e,t){return Zi(Ji,e,!0,t)||e}const Qi=Symbol.for("v-ndc");function Hf(e){return se(e)?Zi(Ji,e,!1)||e:e||Qi}function Zi(e,t,n=!0,r=!1){const s=de||ue;if(s){const i=s.type;{const l=ta(i,!1);if(l&&(l===t||l===Ne(t)||l===$n(Ne(t))))return i}const o=Cs(s[e]||i[e],t)||Cs(s.appContext[e],t);return!o&&r?i:o}}function Cs(e,t){return e&&(e[t]||e[Ne(t)]||e[$n(Ne(t))])}function $f(e,t,n,r){let s;const i=n,o=K(e);if(o||se(e)){const l=o&&pt(e);let c=!1;l&&(c=!Pe(e),e=jn(e)),s=new Array(e.length);for(let f=0,a=e.length;ft(l,c,void 0,i));else{const l=Object.keys(e);s=new Array(l.length);for(let c=0,f=l.length;cLn(t)?!(t.type===ye||t.type===Se&&!eo(t.children)):!0)?e:null}function jf(e,t){const n={};for(const r in e)n[/[A-Z]/.test(r)?`on:${r}`:wn(r)]=e[r];return n}const Ar=e=>e?xo(e)?Xn(e):Ar(e.parent):null,Vt=fe(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Ar(e.parent),$root:e=>Ar(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>ts(e),$forceUpdate:e=>e.f||(e.f=()=>{Qr(e.update)}),$nextTick:e=>e.n||(e.n=Bn.bind(e.proxy)),$watch:e=>Dc.bind(e)}),ir=(e,t)=>e!==ee&&!e.__isScriptSetup&&J(e,t),yc={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:r,data:s,props:i,accessCache:o,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const v=o[t];if(v!==void 0)switch(v){case 1:return r[t];case 2:return s[t];case 4:return n[t];case 3:return i[t]}else{if(ir(r,t))return o[t]=1,r[t];if(s!==ee&&J(s,t))return o[t]=2,s[t];if((f=e.propsOptions[0])&&J(f,t))return o[t]=3,i[t];if(n!==ee&&J(n,t))return o[t]=4,n[t];Rr&&(o[t]=0)}}const a=Vt[t];let h,g;if(a)return t==="$attrs"&&ve(e.attrs,"get",""),a(e);if((h=l.__cssModules)&&(h=h[t]))return h;if(n!==ee&&J(n,t))return o[t]=4,n[t];if(g=c.config.globalProperties,J(g,t))return g[t]},set({_:e},t,n){const{data:r,setupState:s,ctx:i}=e;return ir(s,t)?(s[t]=n,!0):r!==ee&&J(r,t)?(r[t]=n,!0):J(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:s,propsOptions:i}},o){let l;return!!n[o]||e!==ee&&J(e,o)||ir(t,o)||(l=i[0])&&J(l,o)||J(r,o)||J(Vt,o)||J(s.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:J(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Vf(){return vc().slots}function vc(){const e=Yn();return e.setupContext||(e.setupContext=Co(e))}function As(e){return K(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Rr=!0;function bc(e){const t=ts(e),n=e.proxy,r=e.ctx;Rr=!1,t.beforeCreate&&Rs(t.beforeCreate,e,"bc");const{data:s,computed:i,methods:o,watch:l,provide:c,inject:f,created:a,beforeMount:h,mounted:g,beforeUpdate:v,updated:_,activated:S,deactivated:U,beforeDestroy:N,beforeUnmount:k,destroyed:p,unmounted:m,render:M,renderTracked:F,renderTriggered:$,errorCaptured:j,serverPrefetch:R,expose:b,inheritAttrs:L,components:x,directives:W,filters:re}=t;if(f&&_c(f,r,null),o)for(const Y in o){const D=o[Y];q(D)&&(r[Y]=D.bind(n))}if(s){const Y=s.call(n,n);ne(Y)&&(e.data=Un(Y))}if(Rr=!0,i)for(const Y in i){const D=i[Y],he=q(D)?D.bind(n,n):q(D.get)?D.get.bind(n,n):Ue,on=!q(D)&&q(D.set)?D.set.bind(n):Ue,lt=ie({get:he,set:on});Object.defineProperty(r,Y,{enumerable:!0,configurable:!0,get:()=>lt.value,set:$e=>lt.value=$e})}if(l)for(const Y in l)to(l[Y],r,n,Y);if(c){const Y=q(c)?c.call(n):c;Reflect.ownKeys(Y).forEach(D=>{Cc(D,Y[D])})}a&&Rs(a,e,"c");function V(Y,D){K(D)?D.forEach(he=>Y(he.bind(n))):D&&Y(D.bind(n))}if(V(fc,h),V(It,g),V(uc,v),V(dc,_),V(lc,S),V(cc,U),V(mc,j),V(gc,F),V(pc,$),V(zi,k),V(Kn,m),V(hc,R),K(b))if(b.length){const Y=e.exposed||(e.exposed={});b.forEach(D=>{Object.defineProperty(Y,D,{get:()=>n[D],set:he=>n[D]=he})})}else e.exposed||(e.exposed={});M&&e.render===Ue&&(e.render=M),L!=null&&(e.inheritAttrs=L),x&&(e.components=x),W&&(e.directives=W),R&&es(e)}function _c(e,t,n=Ue){K(e)&&(e=Or(e));for(const r in e){const s=e[r];let i;ne(s)?"default"in s?i=Mt(s.from||r,s.default,!0):i=Mt(s.from||r):i=Mt(s),ae(i)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[r]=i}}function Rs(e,t,n){Fe(K(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function to(e,t,n,r){let s=r.includes(".")?mo(n,r):()=>n[r];if(se(e)){const i=t[e];q(i)&&ke(s,i)}else if(q(e))ke(s,e.bind(n));else if(ne(e))if(K(e))e.forEach(i=>to(i,t,n,r));else{const i=q(e.handler)?e.handler.bind(n):t[e.handler];q(i)&&ke(s,i,e)}}function ts(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:s,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let c;return l?c=l:!s.length&&!n&&!r?c=t:(c={},s.length&&s.forEach(f=>In(c,f,o,!0)),In(c,t,o)),ne(t)&&i.set(t,c),c}function In(e,t,n,r=!1){const{mixins:s,extends:i}=t;i&&In(e,i,n,!0),s&&s.forEach(o=>In(e,o,n,!0));for(const o in t)if(!(r&&o==="expose")){const l=wc[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const wc={data:Os,props:Ms,emits:Ms,methods:$t,computed:$t,beforeCreate:be,created:be,beforeMount:be,mounted:be,beforeUpdate:be,updated:be,beforeDestroy:be,beforeUnmount:be,destroyed:be,unmounted:be,activated:be,deactivated:be,errorCaptured:be,serverPrefetch:be,components:$t,directives:$t,watch:Ec,provide:Os,inject:Sc};function Os(e,t){return t?e?function(){return fe(q(e)?e.call(this,this):e,q(t)?t.call(this,this):t)}:t:e}function Sc(e,t){return $t(Or(e),Or(t))}function Or(e){if(K(e)){const t={};for(let n=0;n1)return n&&q(t)?t.call(r&&r.proxy):t}}const ro={},so=()=>Object.create(ro),io=e=>Object.getPrototypeOf(e)===ro;function Ac(e,t,n,r=!1){const s={},i=so();e.propsDefaults=Object.create(null),oo(e,t,s,i);for(const o in e.propsOptions[0])o in s||(s[o]=void 0);n?e.props=r?s:Ll(s):e.type.props?e.props=s:e.props=i,e.attrs=i}function Rc(e,t,n,r){const{props:s,attrs:i,vnode:{patchFlag:o}}=e,l=z(s),[c]=e.propsOptions;let f=!1;if((r||o>0)&&!(o&16)){if(o&8){const a=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[g,v]=lo(h,t,!0);fe(o,g),v&&l.push(...v)};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}if(!i&&!c)return ne(e)&&r.set(e,Tt),Tt;if(K(i))for(let a=0;ae[0]==="_"||e==="$stable",ns=e=>K(e)?e.map(Me):[Me(e)],Mc=(e,t,n)=>{if(t._n)return t;const r=Xl((...s)=>ns(t(...s)),n);return r._c=!1,r},ao=(e,t,n)=>{const r=e._ctx;for(const s in e){if(co(s))continue;const i=e[s];if(q(i))t[s]=Mc(s,i,r);else if(i!=null){const o=ns(i);t[s]=()=>o}}},fo=(e,t)=>{const n=ns(t);e.slots.default=()=>n},uo=(e,t,n)=>{for(const r in t)(n||r!=="_")&&(e[r]=t[r])},Pc=(e,t,n)=>{const r=e.slots=so();if(e.vnode.shapeFlag&32){const s=t._;s?(uo(r,t,n),n&&pi(r,"_",s,!0)):ao(t,r)}else t&&fo(e,t)},Ic=(e,t,n)=>{const{vnode:r,slots:s}=e;let i=!0,o=ee;if(r.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:uo(s,t,n):(i=!t.$stable,ao(t,s)),o=t}else t&&(fo(e,t),o={default:1});if(i)for(const l in s)!co(l)&&o[l]==null&&delete s[l]},Ee=bo;function Lc(e){return ho(e)}function Nc(e){return ho(e,sc)}function ho(e,t){const n=gi();n.__VUE__=!0;const{insert:r,remove:s,patchProp:i,createElement:o,createText:l,createComment:c,setText:f,setElementText:a,parentNode:h,nextSibling:g,setScopeId:v=Ue,insertStaticContent:_}=e,S=(u,d,y,T=null,w=null,E=null,P=void 0,O=null,A=!!d.dynamicChildren)=>{if(u===d)return;u&&!dt(u,d)&&(T=ln(u),$e(u,w,E,!0),u=null),d.patchFlag===-2&&(A=!1,d.dynamicChildren=null);const{type:C,ref:B,shapeFlag:I}=d;switch(C){case mt:U(u,d,y,T);break;case ye:N(u,d,y,T);break;case Ut:u==null&&k(d,y,T,P);break;case Se:x(u,d,y,T,w,E,P,O,A);break;default:I&1?M(u,d,y,T,w,E,P,O,A):I&6?W(u,d,y,T,w,E,P,O,A):(I&64||I&128)&&C.process(u,d,y,T,w,E,P,O,A,bt)}B!=null&&w&&Pn(B,u&&u.ref,E,d||u,!d)},U=(u,d,y,T)=>{if(u==null)r(d.el=l(d.children),y,T);else{const w=d.el=u.el;d.children!==u.children&&f(w,d.children)}},N=(u,d,y,T)=>{u==null?r(d.el=c(d.children||""),y,T):d.el=u.el},k=(u,d,y,T)=>{[u.el,u.anchor]=_(u.children,d,y,T,u.el,u.anchor)},p=({el:u,anchor:d},y,T)=>{let w;for(;u&&u!==d;)w=g(u),r(u,y,T),u=w;r(d,y,T)},m=({el:u,anchor:d})=>{let y;for(;u&&u!==d;)y=g(u),s(u),u=y;s(d)},M=(u,d,y,T,w,E,P,O,A)=>{d.type==="svg"?P="svg":d.type==="math"&&(P="mathml"),u==null?F(d,y,T,w,E,P,O,A):R(u,d,w,E,P,O,A)},F=(u,d,y,T,w,E,P,O)=>{let A,C;const{props:B,shapeFlag:I,transition:H,dirs:G}=u;if(A=u.el=o(u.type,E,B&&B.is,B),I&8?a(A,u.children):I&16&&j(u.children,A,null,T,w,or(u,E),P,O),G&&Ve(u,null,T,"created"),$(A,u,u.scopeId,P,T),B){for(const te in B)te!=="value"&&!At(te)&&i(A,te,null,B[te],E,T);"value"in B&&i(A,"value",null,B.value,E),(C=B.onVnodeBeforeMount)&&Oe(C,T,u)}G&&Ve(u,null,T,"beforeMount");const X=po(w,H);X&&H.beforeEnter(A),r(A,d,y),((C=B&&B.onVnodeMounted)||X||G)&&Ee(()=>{C&&Oe(C,T,u),X&&H.enter(A),G&&Ve(u,null,T,"mounted")},w)},$=(u,d,y,T,w)=>{if(y&&v(u,y),T)for(let E=0;E{for(let C=A;C{const O=d.el=u.el;let{patchFlag:A,dynamicChildren:C,dirs:B}=d;A|=u.patchFlag&16;const I=u.props||ee,H=d.props||ee;let G;if(y&&ct(y,!1),(G=H.onVnodeBeforeUpdate)&&Oe(G,y,d,u),B&&Ve(d,u,y,"beforeUpdate"),y&&ct(y,!0),(I.innerHTML&&H.innerHTML==null||I.textContent&&H.textContent==null)&&a(O,""),C?b(u.dynamicChildren,C,O,y,T,or(d,w),E):P||D(u,d,O,null,y,T,or(d,w),E,!1),A>0){if(A&16)L(O,I,H,y,w);else if(A&2&&I.class!==H.class&&i(O,"class",null,H.class,w),A&4&&i(O,"style",I.style,H.style,w),A&8){const X=d.dynamicProps;for(let te=0;te{G&&Oe(G,y,d,u),B&&Ve(d,u,y,"updated")},T)},b=(u,d,y,T,w,E,P)=>{for(let O=0;O{if(d!==y){if(d!==ee)for(const E in d)!At(E)&&!(E in y)&&i(u,E,d[E],null,w,T);for(const E in y){if(At(E))continue;const P=y[E],O=d[E];P!==O&&E!=="value"&&i(u,E,O,P,w,T)}"value"in y&&i(u,"value",d.value,y.value,w)}},x=(u,d,y,T,w,E,P,O,A)=>{const C=d.el=u?u.el:l(""),B=d.anchor=u?u.anchor:l("");let{patchFlag:I,dynamicChildren:H,slotScopeIds:G}=d;G&&(O=O?O.concat(G):G),u==null?(r(C,y,T),r(B,y,T),j(d.children||[],y,B,w,E,P,O,A)):I>0&&I&64&&H&&u.dynamicChildren?(b(u.dynamicChildren,H,y,w,E,P,O),(d.key!=null||w&&d===w.subTree)&&rs(u,d,!0)):D(u,d,y,B,w,E,P,O,A)},W=(u,d,y,T,w,E,P,O,A)=>{d.slotScopeIds=O,u==null?d.shapeFlag&512?w.ctx.activate(d,y,T,P,A):re(d,y,T,w,E,P,A):ce(u,d,A)},re=(u,d,y,T,w,E,P)=>{const O=u.component=Jc(u,T,w);if(nn(u)&&(O.ctx.renderer=bt),Qc(O,!1,P),O.asyncDep){if(w&&w.registerDep(O,V,P),!u.el){const A=O.subTree=le(ye);N(null,A,d,y)}}else V(O,u,d,y,w,E,P)},ce=(u,d,y)=>{const T=d.component=u.component;if(Bc(u,d,y))if(T.asyncDep&&!T.asyncResolved){Y(T,d,y);return}else T.next=d,T.update();else d.el=u.el,T.vnode=d},V=(u,d,y,T,w,E,P)=>{const O=()=>{if(u.isMounted){let{next:I,bu:H,u:G,parent:X,vnode:te}=u;{const Te=go(u);if(Te){I&&(I.el=te.el,Y(u,I,P)),Te.asyncDep.then(()=>{u.isUnmounted||O()});return}}let Q=I,xe;ct(u,!1),I?(I.el=te.el,Y(u,I,P)):I=te,H&&Sn(H),(xe=I.props&&I.props.onVnodeBeforeUpdate)&&Oe(xe,X,I,te),ct(u,!0);const pe=lr(u),Ie=u.subTree;u.subTree=pe,S(Ie,pe,h(Ie.el),ln(Ie),u,w,E),I.el=pe.el,Q===null&&Wc(u,pe.el),G&&Ee(G,w),(xe=I.props&&I.props.onVnodeUpdated)&&Ee(()=>Oe(xe,X,I,te),w)}else{let I;const{el:H,props:G}=d,{bm:X,m:te,parent:Q,root:xe,type:pe}=u,Ie=gt(d);if(ct(u,!1),X&&Sn(X),!Ie&&(I=G&&G.onVnodeBeforeMount)&&Oe(I,Q,d),ct(u,!0),H&&Qn){const Te=()=>{u.subTree=lr(u),Qn(H,u.subTree,u,w,null)};Ie&&pe.__asyncHydrate?pe.__asyncHydrate(H,u,Te):Te()}else{xe.ce&&xe.ce._injectChildStyle(pe);const Te=u.subTree=lr(u);S(null,Te,y,T,u,w,E),d.el=Te.el}if(te&&Ee(te,w),!Ie&&(I=G&&G.onVnodeMounted)){const Te=d;Ee(()=>Oe(I,Q,Te),w)}(d.shapeFlag&256||Q&>(Q.vnode)&&Q.vnode.shapeFlag&256)&&u.a&&Ee(u.a,w),u.isMounted=!0,d=y=T=null}};u.scope.on();const A=u.effect=new _i(O);u.scope.off();const C=u.update=A.run.bind(A),B=u.job=A.runIfDirty.bind(A);B.i=u,B.id=u.uid,A.scheduler=()=>Qr(B),ct(u,!0),C()},Y=(u,d,y)=>{d.component=u;const T=u.vnode.props;u.vnode=d,u.next=null,Rc(u,d.props,T,y),Ic(u,d.children,y),it(),_s(u),ot()},D=(u,d,y,T,w,E,P,O,A=!1)=>{const C=u&&u.children,B=u?u.shapeFlag:0,I=d.children,{patchFlag:H,shapeFlag:G}=d;if(H>0){if(H&128){on(C,I,y,T,w,E,P,O,A);return}else if(H&256){he(C,I,y,T,w,E,P,O,A);return}}G&8?(B&16&&Lt(C,w,E),I!==C&&a(y,I)):B&16?G&16?on(C,I,y,T,w,E,P,O,A):Lt(C,w,E,!0):(B&8&&a(y,""),G&16&&j(I,y,T,w,E,P,O,A))},he=(u,d,y,T,w,E,P,O,A)=>{u=u||Tt,d=d||Tt;const C=u.length,B=d.length,I=Math.min(C,B);let H;for(H=0;HB?Lt(u,w,E,!0,!1,I):j(d,y,T,w,E,P,O,A,I)},on=(u,d,y,T,w,E,P,O,A)=>{let C=0;const B=d.length;let I=u.length-1,H=B-1;for(;C<=I&&C<=H;){const G=u[C],X=d[C]=A?et(d[C]):Me(d[C]);if(dt(G,X))S(G,X,y,null,w,E,P,O,A);else break;C++}for(;C<=I&&C<=H;){const G=u[I],X=d[H]=A?et(d[H]):Me(d[H]);if(dt(G,X))S(G,X,y,null,w,E,P,O,A);else break;I--,H--}if(C>I){if(C<=H){const G=H+1,X=GH)for(;C<=I;)$e(u[C],w,E,!0),C++;else{const G=C,X=C,te=new Map;for(C=X;C<=H;C++){const Ce=d[C]=A?et(d[C]):Me(d[C]);Ce.key!=null&&te.set(Ce.key,C)}let Q,xe=0;const pe=H-X+1;let Ie=!1,Te=0;const Nt=new Array(pe);for(C=0;C=pe){$e(Ce,w,E,!0);continue}let De;if(Ce.key!=null)De=te.get(Ce.key);else for(Q=X;Q<=H;Q++)if(Nt[Q-X]===0&&dt(Ce,d[Q])){De=Q;break}De===void 0?$e(Ce,w,E,!0):(Nt[De-X]=C+1,De>=Te?Te=De:Ie=!0,S(Ce,d[De],y,null,w,E,P,O,A),xe++)}const us=Ie?Fc(Nt):Tt;for(Q=us.length-1,C=pe-1;C>=0;C--){const Ce=X+C,De=d[Ce],ds=Ce+1{const{el:E,type:P,transition:O,children:A,shapeFlag:C}=u;if(C&6){lt(u.component.subTree,d,y,T);return}if(C&128){u.suspense.move(d,y,T);return}if(C&64){P.move(u,d,y,bt);return}if(P===Se){r(E,d,y);for(let I=0;IO.enter(E),w);else{const{leave:I,delayLeave:H,afterLeave:G}=O,X=()=>r(E,d,y),te=()=>{I(E,()=>{X(),G&&G()})};H?H(E,X,te):te()}else r(E,d,y)},$e=(u,d,y,T=!1,w=!1)=>{const{type:E,props:P,ref:O,children:A,dynamicChildren:C,shapeFlag:B,patchFlag:I,dirs:H,cacheIndex:G}=u;if(I===-2&&(w=!1),O!=null&&Pn(O,null,y,u,!0),G!=null&&(d.renderCache[G]=void 0),B&256){d.ctx.deactivate(u);return}const X=B&1&&H,te=!gt(u);let Q;if(te&&(Q=P&&P.onVnodeBeforeUnmount)&&Oe(Q,d,u),B&6)Xo(u.component,y,T);else{if(B&128){u.suspense.unmount(y,T);return}X&&Ve(u,null,d,"beforeUnmount"),B&64?u.type.remove(u,d,y,bt,T):C&&!C.hasOnce&&(E!==Se||I>0&&I&64)?Lt(C,d,y,!1,!0):(E===Se&&I&384||!w&&B&16)&&Lt(A,d,y),T&&as(u)}(te&&(Q=P&&P.onVnodeUnmounted)||X)&&Ee(()=>{Q&&Oe(Q,d,u),X&&Ve(u,null,d,"unmounted")},y)},as=u=>{const{type:d,el:y,anchor:T,transition:w}=u;if(d===Se){Yo(y,T);return}if(d===Ut){m(u);return}const E=()=>{s(y),w&&!w.persisted&&w.afterLeave&&w.afterLeave()};if(u.shapeFlag&1&&w&&!w.persisted){const{leave:P,delayLeave:O}=w,A=()=>P(y,E);O?O(u.el,E,A):A()}else E()},Yo=(u,d)=>{let y;for(;u!==d;)y=g(u),s(u),u=y;s(d)},Xo=(u,d,y)=>{const{bum:T,scope:w,job:E,subTree:P,um:O,m:A,a:C}=u;Is(A),Is(C),T&&Sn(T),w.stop(),E&&(E.flags|=8,$e(P,u,d,y)),O&&Ee(O,d),Ee(()=>{u.isUnmounted=!0},d),d&&d.pendingBranch&&!d.isUnmounted&&u.asyncDep&&!u.asyncResolved&&u.suspenseId===d.pendingId&&(d.deps--,d.deps===0&&d.resolve())},Lt=(u,d,y,T=!1,w=!1,E=0)=>{for(let P=E;P{if(u.shapeFlag&6)return ln(u.component.subTree);if(u.shapeFlag&128)return u.suspense.next();const d=g(u.anchor||u.el),y=d&&d[Ui];return y?g(y):d};let zn=!1;const fs=(u,d,y)=>{u==null?d._vnode&&$e(d._vnode,null,null,!0):S(d._vnode||null,u,d,null,null,null,y),d._vnode=u,zn||(zn=!0,_s(),On(),zn=!1)},bt={p:S,um:$e,m:lt,r:as,mt:re,mc:j,pc:D,pbc:b,n:ln,o:e};let Jn,Qn;return t&&([Jn,Qn]=t(bt)),{render:fs,hydrate:Jn,createApp:Tc(fs,Jn)}}function or({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function ct({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function po(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function rs(e,t,n=!1){const r=e.children,s=t.children;if(K(r)&&K(s))for(let i=0;i>1,e[n[l]]0&&(t[r]=n[i-1]),n[i]=r)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function go(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:go(t)}function Is(e){if(e)for(let t=0;tMt(Hc);function ss(e,t){return qn(e,null,t)}function Uf(e,t){return qn(e,null,{flush:"post"})}function ke(e,t,n){return qn(e,t,n)}function qn(e,t,n=ee){const{immediate:r,deep:s,flush:i,once:o}=n,l=fe({},n);let c;if(sn)if(i==="sync"){const g=$c();c=g.__watcherHandles||(g.__watcherHandles=[])}else if(!t||r)l.once=!0;else{const g=()=>{};return g.stop=Ue,g.resume=Ue,g.pause=Ue,g}const f=ue;l.call=(g,v,_)=>Fe(g,f,v,_);let a=!1;i==="post"?l.scheduler=g=>{Ee(g,f&&f.suspense)}:i!=="sync"&&(a=!0,l.scheduler=(g,v)=>{v?g():Qr(g)}),l.augmentJob=g=>{t&&(g.flags|=4),a&&(g.flags|=2,f&&(g.id=f.uid,g.i=f))};const h=Kl(e,t,l);return c&&c.push(h),h}function Dc(e,t,n){const r=this.proxy,s=se(e)?e.includes(".")?mo(r,e):()=>r[e]:e.bind(r,r);let i;q(t)?i=t:(i=t.handler,n=t);const o=rn(this),l=qn(s,i.bind(r),n);return o(),l}function mo(e,t){const n=t.split(".");return()=>{let r=e;for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Ne(t)}Modifiers`]||e[`${st(t)}Modifiers`];function Vc(e,t,...n){if(e.isUnmounted)return;const r=e.vnode.props||ee;let s=n;const i=t.startsWith("update:"),o=i&&jc(r,t.slice(7));o&&(o.trim&&(s=n.map(a=>se(a)?a.trim():a)),o.number&&(s=n.map(wr)));let l,c=r[l=wn(t)]||r[l=wn(Ne(t))];!c&&i&&(c=r[l=wn(st(t))]),c&&Fe(c,e,6,s);const f=r[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Fe(f,e,6,s)}}function yo(e,t,n=!1){const r=t.emitsCache,s=r.get(e);if(s!==void 0)return s;const i=e.emits;let o={},l=!1;if(!q(e)){const c=f=>{const a=yo(f,t,!0);a&&(l=!0,fe(o,a))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!l?(ne(e)&&r.set(e,null),null):(K(i)?i.forEach(c=>o[c]=null):fe(o,i),ne(e)&&r.set(e,o),o)}function Gn(e,t){return!e||!Zt(t)?!1:(t=t.slice(2).replace(/Once$/,""),J(e,t[0].toLowerCase()+t.slice(1))||J(e,st(t))||J(e,t))}function lr(e){const{type:t,vnode:n,proxy:r,withProxy:s,propsOptions:[i],slots:o,attrs:l,emit:c,render:f,renderCache:a,props:h,data:g,setupState:v,ctx:_,inheritAttrs:S}=e,U=Mn(e);let N,k;try{if(n.shapeFlag&4){const m=s||r,M=m;N=Me(f.call(M,m,a,h,v,g,_)),k=l}else{const m=t;N=Me(m.length>1?m(h,{attrs:l,slots:o,emit:c}):m(h,null)),k=t.props?l:Uc(l)}}catch(m){kt.length=0,tn(m,e,1),N=le(ye)}let p=N;if(k&&S!==!1){const m=Object.keys(k),{shapeFlag:M}=p;m.length&&M&7&&(i&&m.some($r)&&(k=kc(k,i)),p=nt(p,k,!1,!0))}return n.dirs&&(p=nt(p,null,!1,!0),p.dirs=p.dirs?p.dirs.concat(n.dirs):n.dirs),n.transition&&Xt(p,n.transition),N=p,Mn(U),N}const Uc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Zt(n))&&((t||(t={}))[n]=e[n]);return t},kc=(e,t)=>{const n={};for(const r in e)(!$r(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Bc(e,t,n){const{props:r,children:s,component:i}=e,{props:o,children:l,patchFlag:c}=t,f=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return r?Ls(r,o,f):!!o;if(c&8){const a=t.dynamicProps;for(let h=0;he.__isSuspense;function bo(e,t){t&&t.pendingBranch?K(e)?t.effects.push(...e):t.effects.push(e):Yl(e)}const Se=Symbol.for("v-fgt"),mt=Symbol.for("v-txt"),ye=Symbol.for("v-cmt"),Ut=Symbol.for("v-stc"),kt=[];let Ae=null;function Pr(e=!1){kt.push(Ae=e?null:[])}function Kc(){kt.pop(),Ae=kt[kt.length-1]||null}let zt=1;function Ns(e){zt+=e,e<0&&Ae&&(Ae.hasOnce=!0)}function _o(e){return e.dynamicChildren=zt>0?Ae||Tt:null,Kc(),zt>0&&Ae&&Ae.push(e),e}function kf(e,t,n,r,s,i){return _o(So(e,t,n,r,s,i,!0))}function Ir(e,t,n,r,s){return _o(le(e,t,n,r,s,!0))}function Ln(e){return e?e.__v_isVNode===!0:!1}function dt(e,t){return e.type===t.type&&e.key===t.key}const wo=({key:e})=>e??null,Tn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?se(e)||ae(e)||q(e)?{i:de,r:e,k:t,f:!!n}:e:null);function So(e,t=null,n=null,r=0,s=null,i=e===Se?0:1,o=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&wo(t),ref:t&&Tn(t),scopeId:Vi,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:r,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:de};return l?(is(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=se(n)?8:16),zt>0&&!o&&Ae&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&Ae.push(c),c}const le=qc;function qc(e,t=null,n=null,r=0,s=null,i=!1){if((!e||e===Qi)&&(e=ye),Ln(e)){const l=nt(e,t,!0);return n&&is(l,n),zt>0&&!i&&Ae&&(l.shapeFlag&6?Ae[Ae.indexOf(e)]=l:Ae.push(l)),l.patchFlag=-2,l}if(na(e)&&(e=e.__vccOpts),t){t=Gc(t);let{class:l,style:c}=t;l&&!se(l)&&(t.class=Ur(l)),ne(c)&&(Yr(c)&&!K(c)&&(c=fe({},c)),t.style=Vr(c))}const o=se(e)?1:vo(e)?128:ki(e)?64:ne(e)?4:q(e)?2:0;return So(e,t,n,r,s,o,i,!0)}function Gc(e){return e?Yr(e)||io(e)?fe({},e):e:null}function nt(e,t,n=!1,r=!1){const{props:s,ref:i,patchFlag:o,children:l,transition:c}=e,f=t?Yc(s||{},t):s,a={__v_isVNode:!0,__v_skip:!0,type:e.type,props:f,key:f&&wo(f),ref:t&&t.ref?n&&i?K(i)?i.concat(Tn(t)):[i,Tn(t)]:Tn(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Se?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&nt(e.ssContent),ssFallback:e.ssFallback&&nt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&r&&Xt(a,c.clone(a)),a}function Eo(e=" ",t=0){return le(mt,null,e,t)}function Bf(e,t){const n=le(Ut,null,e);return n.staticCount=t,n}function Wf(e="",t=!1){return t?(Pr(),Ir(ye,null,e)):le(ye,null,e)}function Me(e){return e==null||typeof e=="boolean"?le(ye):K(e)?le(Se,null,e.slice()):typeof e=="object"?et(e):le(mt,null,String(e))}function et(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:nt(e)}function is(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(K(t))n=16;else if(typeof t=="object")if(r&65){const s=t.default;s&&(s._c&&(s._d=!1),is(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!io(t)?t._ctx=de:s===3&&de&&(de.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else q(t)?(t={default:t,_ctx:de},n=32):(t=String(t),r&64?(n=16,t=[Eo(t)]):n=8);e.children=t,e.shapeFlag|=n}function Yc(...e){const t={};for(let n=0;nue||de;let Nn,Lr;{const e=gi(),t=(n,r)=>{let s;return(s=e[n])||(s=e[n]=[]),s.push(r),i=>{s.length>1?s.forEach(o=>o(i)):s[0](i)}};Nn=t("__VUE_INSTANCE_SETTERS__",n=>ue=n),Lr=t("__VUE_SSR_SETTERS__",n=>sn=n)}const rn=e=>{const t=ue;return Nn(e),e.scope.on(),()=>{e.scope.off(),Nn(t)}},Fs=()=>{ue&&ue.scope.off(),Nn(null)};function xo(e){return e.vnode.shapeFlag&4}let sn=!1;function Qc(e,t=!1,n=!1){t&&Lr(t);const{props:r,children:s}=e.vnode,i=xo(e);Ac(e,r,i,t),Pc(e,s,n);const o=i?Zc(e,t):void 0;return t&&Lr(!1),o}function Zc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,yc);const{setup:r}=n;if(r){const s=e.setupContext=r.length>1?Co(e):null,i=rn(e);it();const o=en(r,e,0,[e.props,s]);if(ot(),i(),ui(o)){if(gt(e)||es(e),o.then(Fs,Fs),t)return o.then(l=>{Hs(e,l,t)}).catch(l=>{tn(l,e,0)});e.asyncDep=o}else Hs(e,o,t)}else To(e,t)}function Hs(e,t,n){q(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ne(t)&&(e.setupState=Hi(t)),To(e,n)}let $s;function To(e,t,n){const r=e.type;if(!e.render){if(!t&&$s&&!r.render){const s=r.template||ts(e).template;if(s){const{isCustomElement:i,compilerOptions:o}=e.appContext.config,{delimiters:l,compilerOptions:c}=r,f=fe(fe({isCustomElement:i,delimiters:l},o),c);r.render=$s(s,f)}}e.render=r.render||Ue}{const s=rn(e);it();try{bc(e)}finally{ot(),s()}}}const ea={get(e,t){return ve(e,"get",""),e[t]}};function Co(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,ea),slots:e.slots,emit:e.emit,expose:t}}function Xn(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Hi(En(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Vt)return Vt[n](e)},has(t,n){return n in t||n in Vt}})):e.proxy}function ta(e,t=!0){return q(e)?e.displayName||e.name:e.name||t&&e.__name}function na(e){return q(e)&&"__vccOpts"in e}const ie=(e,t)=>Bl(e,t,sn);function Nr(e,t,n){const r=arguments.length;return r===2?ne(t)&&!K(t)?Ln(t)?le(e,null,[t]):le(e,t):le(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Ln(n)&&(n=[n]),le(e,t,n))}const ra="3.5.8";/** +* @vue/runtime-dom v3.5.8 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Fr;const Ds=typeof window<"u"&&window.trustedTypes;if(Ds)try{Fr=Ds.createPolicy("vue",{createHTML:e=>e})}catch{}const Ao=Fr?e=>Fr.createHTML(e):e=>e,sa="http://www.w3.org/2000/svg",ia="http://www.w3.org/1998/Math/MathML",Ke=typeof document<"u"?document:null,js=Ke&&Ke.createElement("template"),oa={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const s=t==="svg"?Ke.createElementNS(sa,e):t==="mathml"?Ke.createElementNS(ia,e):n?Ke.createElement(e,{is:n}):Ke.createElement(e);return e==="select"&&r&&r.multiple!=null&&s.setAttribute("multiple",r.multiple),s},createText:e=>Ke.createTextNode(e),createComment:e=>Ke.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ke.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,s,i){const o=n?n.previousSibling:t.lastChild;if(s&&(s===i||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===i||!(s=s.nextSibling)););else{js.innerHTML=Ao(r==="svg"?`${e}`:r==="mathml"?`${e}`:e);const l=js.content;if(r==="svg"||r==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ze="transition",Ht="animation",Jt=Symbol("_vtc"),Ro={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},la=fe({},Wi,Ro),ca=e=>(e.displayName="Transition",e.props=la,e),Kf=ca((e,{slots:t})=>Nr(tc,aa(e),t)),at=(e,t=[])=>{K(e)?e.forEach(n=>n(...t)):e&&e(...t)},Vs=e=>e?K(e)?e.some(t=>t.length>1):e.length>1:!1;function aa(e){const t={};for(const x in e)x in Ro||(t[x]=e[x]);if(e.css===!1)return t;const{name:n="v",type:r,duration:s,enterFromClass:i=`${n}-enter-from`,enterActiveClass:o=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:f=o,appearToClass:a=l,leaveFromClass:h=`${n}-leave-from`,leaveActiveClass:g=`${n}-leave-active`,leaveToClass:v=`${n}-leave-to`}=e,_=fa(s),S=_&&_[0],U=_&&_[1],{onBeforeEnter:N,onEnter:k,onEnterCancelled:p,onLeave:m,onLeaveCancelled:M,onBeforeAppear:F=N,onAppear:$=k,onAppearCancelled:j=p}=t,R=(x,W,re)=>{ft(x,W?a:l),ft(x,W?f:o),re&&re()},b=(x,W)=>{x._isLeaving=!1,ft(x,h),ft(x,v),ft(x,g),W&&W()},L=x=>(W,re)=>{const ce=x?$:k,V=()=>R(W,x,re);at(ce,[W,V]),Us(()=>{ft(W,x?c:i),Je(W,x?a:l),Vs(ce)||ks(W,r,S,V)})};return fe(t,{onBeforeEnter(x){at(N,[x]),Je(x,i),Je(x,o)},onBeforeAppear(x){at(F,[x]),Je(x,c),Je(x,f)},onEnter:L(!1),onAppear:L(!0),onLeave(x,W){x._isLeaving=!0;const re=()=>b(x,W);Je(x,h),Je(x,g),ha(),Us(()=>{x._isLeaving&&(ft(x,h),Je(x,v),Vs(m)||ks(x,r,U,re))}),at(m,[x,re])},onEnterCancelled(x){R(x,!1),at(p,[x])},onAppearCancelled(x){R(x,!0),at(j,[x])},onLeaveCancelled(x){b(x),at(M,[x])}})}function fa(e){if(e==null)return null;if(ne(e))return[cr(e.enter),cr(e.leave)];{const t=cr(e);return[t,t]}}function cr(e){return tl(e)}function Je(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Jt]||(e[Jt]=new Set)).add(t)}function ft(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[Jt];n&&(n.delete(t),n.size||(e[Jt]=void 0))}function Us(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let ua=0;function ks(e,t,n,r){const s=e._endId=++ua,i=()=>{s===e._endId&&r()};if(n!=null)return setTimeout(i,n);const{type:o,timeout:l,propCount:c}=da(e,t);if(!o)return r();const f=o+"end";let a=0;const h=()=>{e.removeEventListener(f,g),i()},g=v=>{v.target===e&&++a>=c&&h()};setTimeout(()=>{a(n[_]||"").split(", "),s=r(`${ze}Delay`),i=r(`${ze}Duration`),o=Bs(s,i),l=r(`${Ht}Delay`),c=r(`${Ht}Duration`),f=Bs(l,c);let a=null,h=0,g=0;t===ze?o>0&&(a=ze,h=o,g=i.length):t===Ht?f>0&&(a=Ht,h=f,g=c.length):(h=Math.max(o,f),a=h>0?o>f?ze:Ht:null,g=a?a===ze?i.length:c.length:0);const v=a===ze&&/\b(transform|all)(,|$)/.test(r(`${ze}Property`).toString());return{type:a,timeout:h,propCount:g,hasTransform:v}}function Bs(e,t){for(;e.lengthWs(n)+Ws(e[r])))}function Ws(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function ha(){return document.body.offsetHeight}function pa(e,t,n){const r=e[Jt];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Ks=Symbol("_vod"),ga=Symbol("_vsh"),ma=Symbol(""),ya=/(^|;)\s*display\s*:/;function va(e,t,n){const r=e.style,s=se(n);let i=!1;if(n&&!s){if(t)if(se(t))for(const o of t.split(";")){const l=o.slice(0,o.indexOf(":")).trim();n[l]==null&&Cn(r,l,"")}else for(const o in t)n[o]==null&&Cn(r,o,"");for(const o in n)o==="display"&&(i=!0),Cn(r,o,n[o])}else if(s){if(t!==n){const o=r[ma];o&&(n+=";"+o),r.cssText=n,i=ya.test(n)}}else t&&e.removeAttribute("style");Ks in e&&(e[Ks]=i?r.display:"",e[ga]&&(r.display="none"))}const qs=/\s*!important$/;function Cn(e,t,n){if(K(n))n.forEach(r=>Cn(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=ba(e,t);qs.test(n)?e.setProperty(st(r),n.replace(qs,""),"important"):e[r]=n}}const Gs=["Webkit","Moz","ms"],ar={};function ba(e,t){const n=ar[t];if(n)return n;let r=Ne(t);if(r!=="filter"&&r in e)return ar[t]=r;r=$n(r);for(let s=0;sfr||(xa.then(()=>fr=0),fr=Date.now());function Ca(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;Fe(Aa(r,n.value),t,5,[r])};return n.value=e,n.attached=Ta(),n}function Aa(e,t){if(K(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>s=>!s._stopped&&r&&r(s))}else return t}const Qs=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ra=(e,t,n,r,s,i)=>{const o=s==="svg";t==="class"?pa(e,r,o):t==="style"?va(e,n,r):Zt(t)?$r(t)||Sa(e,t,n,r,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Oa(e,t,r,o))?(_a(e,t,r),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Xs(e,t,r,o,i,t!=="value")):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Xs(e,t,r,o))};function Oa(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&Qs(t)&&q(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return Qs(t)&&se(n)?!1:!!(t in e||e._isVueCE&&(/[A-Z]/.test(t)||!se(n)))}const Zs=e=>{const t=e.props["onUpdate:modelValue"]||!1;return K(t)?n=>Sn(t,n):t};function Ma(e){e.target.composing=!0}function ei(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const ur=Symbol("_assign"),qf={created(e,{modifiers:{lazy:t,trim:n,number:r}},s){e[ur]=Zs(s);const i=r||s.props&&s.props.type==="number";Et(e,t?"change":"input",o=>{if(o.target.composing)return;let l=e.value;n&&(l=l.trim()),i&&(l=wr(l)),e[ur](l)}),n&&Et(e,"change",()=>{e.value=e.value.trim()}),t||(Et(e,"compositionstart",Ma),Et(e,"compositionend",ei),Et(e,"change",ei))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:r,trim:s,number:i}},o){if(e[ur]=Zs(o),e.composing)return;const l=(i||e.type==="number")&&!/^0\d/.test(e.value)?wr(e.value):e.value,c=t??"";l!==c&&(document.activeElement===e&&e.type!=="range"&&(r&&t===n||s&&e.value.trim()===c)||(e.value=c))}},Pa=["ctrl","shift","alt","meta"],Ia={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Pa.some(n=>e[`${n}Key`]&&!t.includes(n))},Gf=(e,t)=>{const n=e._withMods||(e._withMods={}),r=t.join(".");return n[r]||(n[r]=(s,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),r=t.join(".");return n[r]||(n[r]=s=>{if(!("key"in s))return;const i=st(s.key);if(t.some(o=>o===i||La[o]===i))return e(s)})},Oo=fe({patchProp:Ra},oa);let Bt,ti=!1;function Na(){return Bt||(Bt=Lc(Oo))}function Fa(){return Bt=ti?Bt:Nc(Oo),ti=!0,Bt}const Xf=(...e)=>{const t=Na().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Po(r);if(!s)return;const i=t._component;!q(i)&&!i.render&&!i.template&&(i.template=s.innerHTML),s.nodeType===1&&(s.textContent="");const o=n(s,!1,Mo(s));return s instanceof Element&&(s.removeAttribute("v-cloak"),s.setAttribute("data-v-app","")),o},t},zf=(...e)=>{const t=Fa().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Po(r);if(s)return n(s,!0,Mo(s))},t};function Mo(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Po(e){return se(e)?document.querySelector(e):e}const Jf=(e,t)=>{const n=e.__vccOpts||e;for(const[r,s]of t)n[r]=s;return n},Ha=window.__VP_SITE_DATA__;function os(e){return bi()?(fl(e),!0):!1}function Be(e){return typeof e=="function"?e():Fi(e)}const Io=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Qf=e=>e!=null,$a=Object.prototype.toString,Da=e=>$a.call(e)==="[object Object]",Qt=()=>{},ni=ja();function ja(){var e,t;return Io&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function Va(e,t){function n(...r){return new Promise((s,i)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(s).catch(i)})}return n}const Lo=e=>e();function Ua(e,t={}){let n,r,s=Qt;const i=l=>{clearTimeout(l),s(),s=Qt};return l=>{const c=Be(e),f=Be(t.maxWait);return n&&i(n),c<=0||f!==void 0&&f<=0?(r&&(i(r),r=null),Promise.resolve(l())):new Promise((a,h)=>{s=t.rejectOnCancel?h:a,f&&!r&&(r=setTimeout(()=>{n&&i(n),r=null,a(l())},f)),n=setTimeout(()=>{r&&i(r),r=null,a(l())},c)})}}function ka(e=Lo){const t=oe(!0);function n(){t.value=!1}function r(){t.value=!0}const s=(...i)=>{t.value&&e(...i)};return{isActive:kn(t),pause:n,resume:r,eventFilter:s}}function Ba(e){return Yn()}function No(...e){if(e.length!==1)return Vl(...e);const t=e[0];return typeof t=="function"?kn($l(()=>({get:t,set:Qt}))):oe(t)}function Fo(e,t,n={}){const{eventFilter:r=Lo,...s}=n;return ke(e,Va(r,t),s)}function Wa(e,t,n={}){const{eventFilter:r,...s}=n,{eventFilter:i,pause:o,resume:l,isActive:c}=ka(r);return{stop:Fo(e,t,{...s,eventFilter:i}),pause:o,resume:l,isActive:c}}function ls(e,t=!0,n){Ba()?It(e,n):t?e():Bn(e)}function Zf(e,t,n={}){const{debounce:r=0,maxWait:s=void 0,...i}=n;return Fo(e,t,{...i,eventFilter:Ua(r,{maxWait:s})})}function eu(e,t,n){let r;ae(n)?r={evaluating:n}:r={};const{lazy:s=!1,evaluating:i=void 0,shallow:o=!0,onError:l=Qt}=r,c=oe(!s),f=o?zr(t):oe(t);let a=0;return ss(async h=>{if(!c.value)return;a++;const g=a;let v=!1;i&&Promise.resolve().then(()=>{i.value=!0});try{const _=await e(S=>{h(()=>{i&&(i.value=!1),v||S()})});g===a&&(f.value=_)}catch(_){l(_)}finally{i&&g===a&&(i.value=!1),v=!0}}),s?ie(()=>(c.value=!0,f.value)):f}const He=Io?window:void 0;function Ho(e){var t;const n=Be(e);return(t=n==null?void 0:n.$el)!=null?t:n}function Pt(...e){let t,n,r,s;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,s]=e,t=He):[t,n,r,s]=e,!t)return Qt;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const i=[],o=()=>{i.forEach(a=>a()),i.length=0},l=(a,h,g,v)=>(a.addEventListener(h,g,v),()=>a.removeEventListener(h,g,v)),c=ke(()=>[Ho(t),Be(s)],([a,h])=>{if(o(),!a)return;const g=Da(h)?{...h}:h;i.push(...n.flatMap(v=>r.map(_=>l(a,v,_,g))))},{immediate:!0,flush:"post"}),f=()=>{c(),o()};return os(f),f}function Ka(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function tu(...e){let t,n,r={};e.length===3?(t=e[0],n=e[1],r=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],r=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:s=He,eventName:i="keydown",passive:o=!1,dedupe:l=!1}=r,c=Ka(t);return Pt(s,i,a=>{a.repeat&&Be(l)||c(a)&&n(a)},o)}function qa(){const e=oe(!1),t=Yn();return t&&It(()=>{e.value=!0},t),e}function Ga(e){const t=qa();return ie(()=>(t.value,!!e()))}function $o(e,t={}){const{window:n=He}=t,r=Ga(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let s;const i=oe(!1),o=f=>{i.value=f.matches},l=()=>{s&&("removeEventListener"in s?s.removeEventListener("change",o):s.removeListener(o))},c=ss(()=>{r.value&&(l(),s=n.matchMedia(Be(e)),"addEventListener"in s?s.addEventListener("change",o):s.addListener(o),i.value=s.matches)});return os(()=>{c(),l(),s=void 0}),i}const vn=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},bn="__vueuse_ssr_handlers__",Ya=Xa();function Xa(){return bn in vn||(vn[bn]=vn[bn]||{}),vn[bn]}function Do(e,t){return Ya[e]||t}function jo(e){return $o("(prefers-color-scheme: dark)",e)}function za(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Ja={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},ri="vueuse-storage";function cs(e,t,n,r={}){var s;const{flush:i="pre",deep:o=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,mergeDefaults:f=!1,shallow:a,window:h=He,eventFilter:g,onError:v=b=>{console.error(b)},initOnMounted:_}=r,S=(a?zr:oe)(typeof t=="function"?t():t);if(!n)try{n=Do("getDefaultStorage",()=>{var b;return(b=He)==null?void 0:b.localStorage})()}catch(b){v(b)}if(!n)return S;const U=Be(t),N=za(U),k=(s=r.serializer)!=null?s:Ja[N],{pause:p,resume:m}=Wa(S,()=>F(S.value),{flush:i,deep:o,eventFilter:g});h&&l&&ls(()=>{n instanceof Storage?Pt(h,"storage",j):Pt(h,ri,R),_&&j()}),_||j();function M(b,L){if(h){const x={key:e,oldValue:b,newValue:L,storageArea:n};h.dispatchEvent(n instanceof Storage?new StorageEvent("storage",x):new CustomEvent(ri,{detail:x}))}}function F(b){try{const L=n.getItem(e);if(b==null)M(L,null),n.removeItem(e);else{const x=k.write(b);L!==x&&(n.setItem(e,x),M(L,x))}}catch(L){v(L)}}function $(b){const L=b?b.newValue:n.getItem(e);if(L==null)return c&&U!=null&&n.setItem(e,k.write(U)),U;if(!b&&f){const x=k.read(L);return typeof f=="function"?f(x,U):N==="object"&&!Array.isArray(x)?{...U,...x}:x}else return typeof L!="string"?L:k.read(L)}function j(b){if(!(b&&b.storageArea!==n)){if(b&&b.key==null){S.value=U;return}if(!(b&&b.key!==e)){p();try{(b==null?void 0:b.newValue)!==k.write(S.value)&&(S.value=$(b))}catch(L){v(L)}finally{b?Bn(m):m()}}}}function R(b){j(b.detail)}return S}const Qa="*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";function Za(e={}){const{selector:t="html",attribute:n="class",initialValue:r="auto",window:s=He,storage:i,storageKey:o="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:c,emitAuto:f,disableTransition:a=!0}=e,h={auto:"",light:"light",dark:"dark",...e.modes||{}},g=jo({window:s}),v=ie(()=>g.value?"dark":"light"),_=c||(o==null?No(r):cs(o,r,i,{window:s,listenToStorageChanges:l})),S=ie(()=>_.value==="auto"?v.value:_.value),U=Do("updateHTMLAttrs",(m,M,F)=>{const $=typeof m=="string"?s==null?void 0:s.document.querySelector(m):Ho(m);if(!$)return;const j=new Set,R=new Set;let b=null;if(M==="class"){const x=F.split(/\s/g);Object.values(h).flatMap(W=>(W||"").split(/\s/g)).filter(Boolean).forEach(W=>{x.includes(W)?j.add(W):R.add(W)})}else b={key:M,value:F};if(j.size===0&&R.size===0&&b===null)return;let L;a&&(L=s.document.createElement("style"),L.appendChild(document.createTextNode(Qa)),s.document.head.appendChild(L));for(const x of j)$.classList.add(x);for(const x of R)$.classList.remove(x);b&&$.setAttribute(b.key,b.value),a&&(s.getComputedStyle(L).opacity,document.head.removeChild(L))});function N(m){var M;U(t,n,(M=h[m])!=null?M:m)}function k(m){e.onChanged?e.onChanged(m,N):N(m)}ke(S,k,{flush:"post",immediate:!0}),ls(()=>k(S.value));const p=ie({get(){return f?_.value:S.value},set(m){_.value=m}});try{return Object.assign(p,{store:_,system:v,state:S})}catch{return p}}function ef(e={}){const{valueDark:t="dark",valueLight:n="",window:r=He}=e,s=Za({...e,onChanged:(l,c)=>{var f;e.onChanged?(f=e.onChanged)==null||f.call(e,l==="dark",c,l):c(l)},modes:{dark:t,light:n}}),i=ie(()=>s.system?s.system.value:jo({window:r}).value?"dark":"light");return ie({get(){return s.value==="dark"},set(l){const c=l?"dark":"light";i.value===c?s.value="auto":s.value=c}})}function dr(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function nu(e,t,n={}){const{window:r=He}=n;return cs(e,t,r==null?void 0:r.localStorage,n)}function Vo(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const hr=new WeakMap;function ru(e,t=!1){const n=oe(t);let r=null,s="";ke(No(e),l=>{const c=dr(Be(l));if(c){const f=c;if(hr.get(f)||hr.set(f,f.style.overflow),f.style.overflow!=="hidden"&&(s=f.style.overflow),f.style.overflow==="hidden")return n.value=!0;if(n.value)return f.style.overflow="hidden"}},{immediate:!0});const i=()=>{const l=dr(Be(e));!l||n.value||(ni&&(r=Pt(l,"touchmove",c=>{tf(c)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},o=()=>{const l=dr(Be(e));!l||!n.value||(ni&&(r==null||r()),l.style.overflow=s,hr.delete(l),n.value=!1)};return os(o),ie({get(){return n.value},set(l){l?i():o()}})}function su(e,t,n={}){const{window:r=He}=n;return cs(e,t,r==null?void 0:r.sessionStorage,n)}function iu(e={}){const{window:t=He,behavior:n="auto"}=e;if(!t)return{x:oe(0),y:oe(0)};const r=oe(t.scrollX),s=oe(t.scrollY),i=ie({get(){return r.value},set(l){scrollTo({left:l,behavior:n})}}),o=ie({get(){return s.value},set(l){scrollTo({top:l,behavior:n})}});return Pt(t,"scroll",()=>{r.value=t.scrollX,s.value=t.scrollY},{capture:!1,passive:!0}),{x:i,y:o}}function ou(e={}){const{window:t=He,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:r=Number.POSITIVE_INFINITY,listenOrientation:s=!0,includeScrollbar:i=!0,type:o="inner"}=e,l=oe(n),c=oe(r),f=()=>{t&&(o==="outer"?(l.value=t.outerWidth,c.value=t.outerHeight):i?(l.value=t.innerWidth,c.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,c.value=t.document.documentElement.clientHeight))};if(f(),ls(f),Pt("resize",f,{passive:!0}),s){const a=$o("(orientation: portrait)");ke(a,()=>f())}return{width:l,height:c}}const pr={BASE_URL:"/nuxt-i18n-micro/",DEV:!1,MODE:"production",PROD:!0,SSR:!1};var gr={};const Uo=/^(?:[a-z]+:|\/\/)/i,nf="vitepress-theme-appearance",rf=/#.*$/,sf=/[?#].*$/,of=/(?:(^|\/)index)?\.(?:md|html)$/,ge=typeof document<"u",ko={relativePath:"404.md",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function lf(e,t,n=!1){if(t===void 0)return!1;if(e=si(`/${e}`),n)return new RegExp(t).test(e);if(si(t)!==e)return!1;const r=t.match(rf);return r?(ge?location.hash:"")===r[0]:!0}function si(e){return decodeURI(e).replace(sf,"").replace(of,"$1")}function cf(e){return Uo.test(e)}function af(e,t){return Object.keys((e==null?void 0:e.locales)||{}).find(n=>n!=="root"&&!cf(n)&&lf(t,`/${n}/`,!0))||"root"}function ff(e,t){var r,s,i,o,l,c,f;const n=af(e,t);return Object.assign({},e,{localeIndex:n,lang:((r=e.locales[n])==null?void 0:r.lang)??e.lang,dir:((s=e.locales[n])==null?void 0:s.dir)??e.dir,title:((i=e.locales[n])==null?void 0:i.title)??e.title,titleTemplate:((o=e.locales[n])==null?void 0:o.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:Wo(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(f=e.locales[n])==null?void 0:f.themeConfig}})}function Bo(e,t){const n=t.title||e.title,r=t.titleTemplate??e.titleTemplate;if(typeof r=="string"&&r.includes(":title"))return r.replace(/:title/g,n);const s=uf(e.title,r);return n===s.slice(3)?n:`${n}${s}`}function uf(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function df(e,t){const[n,r]=t;if(n!=="meta")return!1;const s=Object.entries(r)[0];return s==null?!1:e.some(([i,o])=>i===n&&o[s[0]]===s[1])}function Wo(e,t){return[...e.filter(n=>!df(t,n)),...t]}const hf=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,pf=/^[a-z]:/i;function ii(e){const t=pf.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(hf,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const mr=new Set;function gf(e){if(mr.size===0){const n=typeof process=="object"&&(gr==null?void 0:gr.VITE_EXTRA_EXTENSIONS)||(pr==null?void 0:pr.VITE_EXTRA_EXTENSIONS)||"";("3g2,3gp,aac,ai,apng,au,avif,bin,bmp,cer,class,conf,crl,css,csv,dll,doc,eps,epub,exe,gif,gz,ics,ief,jar,jpe,jpeg,jpg,js,json,jsonld,m4a,man,mid,midi,mjs,mov,mp2,mp3,mp4,mpe,mpeg,mpg,mpp,oga,ogg,ogv,ogx,opus,otf,p10,p7c,p7m,p7s,pdf,png,ps,qt,roff,rtf,rtx,ser,svg,t,tif,tiff,tr,ts,tsv,ttf,txt,vtt,wav,weba,webm,webp,woff,woff2,xhtml,xml,yaml,yml,zip"+(n&&typeof n=="string"?","+n:"")).split(",").forEach(r=>mr.add(r))}const t=e.split(".").pop();return t==null||!mr.has(t.toLowerCase())}function lu(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}const mf=Symbol(),yt=zr(Ha);function cu(e){const t=ie(()=>ff(yt.value,e.data.relativePath)),n=t.value.appearance,r=n==="force-dark"?oe(!0):n?ef({storageKey:nf,initialValue:()=>n==="dark"?"dark":"auto",...typeof n=="object"?n:{}}):oe(!1),s=oe(ge?location.hash:"");return ge&&window.addEventListener("hashchange",()=>{s.value=location.hash}),ke(()=>e.data,()=>{s.value=ge?location.hash:""}),{site:t,theme:ie(()=>t.value.themeConfig),page:ie(()=>e.data),frontmatter:ie(()=>e.data.frontmatter),params:ie(()=>e.data.params),lang:ie(()=>t.value.lang),dir:ie(()=>e.data.frontmatter.dir||t.value.dir),localeIndex:ie(()=>t.value.localeIndex||"root"),title:ie(()=>Bo(t.value,e.data)),description:ie(()=>e.data.description||t.value.description),isDark:r,hash:ie(()=>s.value)}}function yf(){const e=Mt(mf);if(!e)throw new Error("vitepress data not properly injected in app");return e}function vf(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function oi(e){return Uo.test(e)||!e.startsWith("/")?e:vf(yt.value.base,e)}function bf(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),ge){const n="/nuxt-i18n-micro/";t=ii(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let r=__VP_HASH_MAP__[t.toLowerCase()];if(r||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",r=__VP_HASH_MAP__[t.toLowerCase()]),!r)return null;t=`${n}assets/${t}.${r}.js`}else t=`./${ii(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let An=[];function au(e){An.push(e),Kn(()=>{An=An.filter(t=>t!==e)})}function _f(){let e=yt.value.scrollOffset,t=0,n=24;if(typeof e=="object"&&"padding"in e&&(n=e.padding,e=e.selector),typeof e=="number")t=e;else if(typeof e=="string")t=li(e,n);else if(Array.isArray(e))for(const r of e){const s=li(r,n);if(s){t=s;break}}return t}function li(e,t){const n=document.querySelector(e);if(!n)return 0;const r=n.getBoundingClientRect().bottom;return r<0?0:r+t}const wf=Symbol(),Ko="http://a.com",Sf=()=>({path:"/",component:null,data:ko});function fu(e,t){const n=Un(Sf()),r={route:n,go:s};async function s(l=ge?location.href:"/"){var c,f;l=yr(l),await((c=r.onBeforeRouteChange)==null?void 0:c.call(r,l))!==!1&&(ge&&l!==yr(location.href)&&(history.replaceState({scrollPosition:window.scrollY},""),history.pushState({},"",l)),await o(l),await((f=r.onAfterRouteChanged)==null?void 0:f.call(r,l)))}let i=null;async function o(l,c=0,f=!1){var g;if(await((g=r.onBeforePageLoad)==null?void 0:g.call(r,l))===!1)return;const a=new URL(l,Ko),h=i=a.pathname;try{let v=await e(h);if(!v)throw new Error(`Page not found: ${h}`);if(i===h){i=null;const{default:_,__pageData:S}=v;if(!_)throw new Error(`Invalid route component: ${_}`);n.path=ge?h:oi(h),n.component=En(_),n.data=En(S),ge&&Bn(()=>{let U=yt.value.base+S.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!yt.value.cleanUrls&&!U.endsWith("/")&&(U+=".html"),U!==a.pathname&&(a.pathname=U,l=U+a.search+a.hash,history.replaceState({},"",l)),a.hash&&!c){let N=null;try{N=document.getElementById(decodeURIComponent(a.hash).slice(1))}catch(k){console.warn(k)}if(N){ci(N,a.hash);return}}window.scrollTo(0,c)})}}catch(v){if(!/fetch|Page not found/.test(v.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(v),!f)try{const _=await fetch(yt.value.base+"hashmap.json");window.__VP_HASH_MAP__=await _.json(),await o(l,c,!0);return}catch{}if(i===h){i=null,n.path=ge?h:oi(h),n.component=t?En(t):null;const _=ge?h.replace(/(^|\/)$/,"$1index").replace(/(\.html)?$/,".md").replace(/^\//,""):"404.md";n.data={...ko,relativePath:_}}}}return ge&&(history.state===null&&history.replaceState({},""),window.addEventListener("click",l=>{if(l.defaultPrevented||!(l.target instanceof Element)||l.target.closest("button")||l.button!==0||l.ctrlKey||l.shiftKey||l.altKey||l.metaKey)return;const c=l.target.closest("a");if(!c||c.closest(".vp-raw")||c.hasAttribute("download")||c.hasAttribute("target"))return;const f=c.getAttribute("href")??(c instanceof SVGAElement?c.getAttribute("xlink:href"):null);if(f==null)return;const{href:a,origin:h,pathname:g,hash:v,search:_}=new URL(f,c.baseURI),S=new URL(location.href);h===S.origin&&gf(g)&&(l.preventDefault(),g===S.pathname&&_===S.search?(v!==S.hash&&(history.pushState({},"",a),window.dispatchEvent(new HashChangeEvent("hashchange",{oldURL:S.href,newURL:a}))),v?ci(c,v,c.classList.contains("header-anchor")):window.scrollTo(0,0)):s(a))},{capture:!0}),window.addEventListener("popstate",async l=>{var c;l.state!==null&&(await o(yr(location.href),l.state&&l.state.scrollPosition||0),(c=r.onAfterRouteChanged)==null||c.call(r,location.href))}),window.addEventListener("hashchange",l=>{l.preventDefault()})),r}function Ef(){const e=Mt(wf);if(!e)throw new Error("useRouter() is called without provider.");return e}function qo(){return Ef().route}function ci(e,t,n=!1){let r=null;try{r=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(s){console.warn(s)}if(r){let s=function(){!n||Math.abs(o-window.scrollY)>window.innerHeight?window.scrollTo(0,o):window.scrollTo({left:0,top:o,behavior:"smooth"})};const i=parseInt(window.getComputedStyle(r).paddingTop,10),o=window.scrollY+r.getBoundingClientRect().top-_f()+i;requestAnimationFrame(s)}}function yr(e){const t=new URL(e,Ko);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),yt.value.cleanUrls?t.pathname=t.pathname.replace(/\.html$/,""):!t.pathname.endsWith("/")&&!t.pathname.endsWith(".html")&&(t.pathname+=".html"),t.pathname+t.search+t.hash}const vr=()=>An.forEach(e=>e()),uu=Zr({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=qo(),{site:n}=yf();return()=>Nr(e.as,n.value.contentProps??{style:{position:"relative"}},[t.component?Nr(t.component,{onVnodeMounted:vr,onVnodeUpdated:vr,onVnodeUnmounted:vr}):"404 Page Not Found"])}}),xf="modulepreload",Tf=function(e){return"/nuxt-i18n-micro/"+e},ai={},du=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));s=Promise.allSettled(n.map(c=>{if(c=Tf(c),c in ai)return;ai[c]=!0;const f=c.endsWith(".css"),a=f?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${a}`))return;const h=document.createElement("link");if(h.rel=f?"stylesheet":xf,f||(h.as="script"),h.crossOrigin="",h.href=c,l&&h.setAttribute("nonce",l),document.head.appendChild(h),f)return new Promise((g,v)=>{h.addEventListener("load",g),h.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${c}`)))})}))}function i(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return s.then(o=>{for(const l of o||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},hu=Zr({setup(e,{slots:t}){const n=oe(!1);return It(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function pu(){ge&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const r=(n=t.parentElement)==null?void 0:n.parentElement;if(!r)return;const s=Array.from(r.querySelectorAll("input")).indexOf(t);if(s<0)return;const i=r.querySelector(".blocks");if(!i)return;const o=Array.from(i.children).find(f=>f.classList.contains("active"));if(!o)return;const l=i.children[s];if(!l||o===l)return;o.classList.remove("active"),l.classList.add("active");const c=r==null?void 0:r.querySelector(`label[for="${t.id}"]`);c==null||c.scrollIntoView({block:"nearest"})}})}function gu(){if(ge){const e=new WeakMap;window.addEventListener("click",t=>{var r;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const s=n.parentElement,i=(r=n.nextElementSibling)==null?void 0:r.nextElementSibling;if(!s||!i)return;const o=/language-(shellscript|shell|bash|sh|zsh)/.test(s.className),l=[".vp-copy-ignore",".diff.remove"],c=i.cloneNode(!0);c.querySelectorAll(l.join(",")).forEach(a=>a.remove());let f=c.textContent||"";o&&(f=f.replace(/^ *(\$|>) /gm,"").trim()),Cf(f).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const a=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,a)})}})}}async function Cf(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const r=document.getSelection(),s=r?r.rangeCount>0&&r.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),s&&(r.removeAllRanges(),r.addRange(s)),n&&n.focus()}}function mu(e,t){let n=!0,r=[];const s=i=>{if(n){n=!1,i.forEach(l=>{const c=br(l);for(const f of document.head.children)if(f.isEqualNode(c)){r.push(f);return}});return}const o=i.map(br);r.forEach((l,c)=>{const f=o.findIndex(a=>a==null?void 0:a.isEqualNode(l??null));f!==-1?delete o[f]:(l==null||l.remove(),delete r[c])}),o.forEach(l=>l&&document.head.appendChild(l)),r=[...r,...o].filter(Boolean)};ss(()=>{const i=e.data,o=t.value,l=i&&i.description,c=i&&i.frontmatter.head||[],f=Bo(o,i);f!==document.title&&(document.title=f);const a=l||o.description;let h=document.querySelector("meta[name=description]");h?h.getAttribute("content")!==a&&h.setAttribute("content",a):br(["meta",{name:"description",content:a}]),s(Wo(o.head,Rf(c)))})}function br([e,t,n]){const r=document.createElement(e);for(const s in t)r.setAttribute(s,t[s]);return n&&(r.innerHTML=n),e==="script"&&!t.async&&(r.async=!1),r}function Af(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function Rf(e){return e.filter(t=>!Af(t))}const _r=new Set,Go=()=>document.createElement("link"),Of=e=>{const t=Go();t.rel="prefetch",t.href=e,document.head.appendChild(t)},Mf=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let _n;const Pf=ge&&(_n=Go())&&_n.relList&&_n.relList.supports&&_n.relList.supports("prefetch")?Of:Mf;function yu(){if(!ge||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const r=()=>{n&&n.disconnect(),n=new IntersectionObserver(i=>{i.forEach(o=>{if(o.isIntersecting){const l=o.target;n.unobserve(l);const{pathname:c}=l;if(!_r.has(c)){_r.add(c);const f=bf(c);f&&Pf(f)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(i=>{const{hostname:o,pathname:l}=new URL(i.href instanceof SVGAnimatedString?i.href.animVal:i.href,i.baseURI),c=l.match(/\.\w+$/);c&&c[0]!==".html"||i.target!=="_blank"&&o===location.hostname&&(l!==location.pathname?n.observe(i):_r.add(l))})})};It(r);const s=qo();ke(()=>s.path,r),Kn(()=>{n&&n.disconnect()})}export{zi as $,_f as A,Ff as B,$f as C,zr as D,au as E,Se as F,le as G,Hf as H,Uo as I,qo as J,Yc as K,Mt as L,ou as M,Vr as N,tu as O,Bn as P,iu as Q,ge as R,kn as S,Kf as T,Nf as U,du as V,ru as W,Cc as X,Yf as Y,jf as Z,Jf as _,Eo as a,Gf as a0,Vf as a1,Bf as a2,mu as a3,wf as a4,cu as a5,mf as a6,uu as a7,hu as a8,yt as a9,zf as aa,fu as ab,bf as ac,yu as ad,gu as ae,pu as af,Nr as ag,Be as ah,Ho as ai,Qf as aj,os as ak,eu as al,su as am,nu as an,Zf as ao,Ef as ap,Pt as aq,If as ar,qf as as,ae as at,Lf as au,En as av,Xf as aw,lu as ax,Ir as b,kf as c,Zr as d,Wf as e,gf as f,oi as g,ie as h,cf as i,So as j,Fi as k,lf as l,$o as m,Ur as n,Pr as o,oe as p,ke as q,Df as r,ss as s,cl as t,yf as u,It as v,Xl as w,Kn as x,Uf as y,dc as z}; diff --git a/assets/chunks/theme.DDdXCRuz.js b/assets/chunks/theme.DDdXCRuz.js new file mode 100644 index 0000000..28a4631 --- /dev/null +++ b/assets/chunks/theme.DDdXCRuz.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/chunks/VPLocalSearchBox.D0OKQOhX.js","assets/chunks/framework.CBrKbnPu.js"])))=>i.map(i=>d[i]); +import{d as m,o as a,c as u,r as c,n as w,a as D,t as N,b as k,w as v,e as h,T as ue,_ as g,u as Be,i as Ce,f as He,g as de,h as y,j as p,k as r,l as z,m as ae,p as M,q as O,s as Y,v as K,x as ve,y as pe,z as Ee,A as Fe,B as q,F as I,C,D as $e,E as Q,G as _,H as E,I as ye,J as Z,K as j,L as x,M as De,N as Pe,O as re,P as Oe,Q as Ve,R as ee,S as Ge,U as Ue,V as je,W as Le,X as Se,Y as ze,Z as Ke,$ as qe,a0 as Re,a1 as We}from"./framework.CBrKbnPu.js";const Je=m({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(e,t)=>(a(),u("span",{class:w(["VPBadge",e.type])},[c(e.$slots,"default",{},()=>[D(N(e.text),1)])],2))}}),Xe={key:0,class:"VPBackdrop"},Ye=m({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(e,t)=>(a(),k(ue,{name:"fade"},{default:v(()=>[e.show?(a(),u("div",Xe)):h("",!0)]),_:1}))}}),Qe=g(Ye,[["__scopeId","data-v-c79a1216"]]),V=Be;function Ze(s,e){let t,o=!1;return()=>{t&&clearTimeout(t),o?t=setTimeout(s,e):(s(),(o=!0)&&setTimeout(()=>o=!1,e))}}function ie(s){return/^\//.test(s)?s:`/${s}`}function fe(s){const{pathname:e,search:t,hash:o,protocol:n}=new URL(s,"http://a.com");if(Ce(s)||s.startsWith("#")||!n.startsWith("http")||!He(e))return s;const{site:i}=V(),l=e.endsWith("/")||e.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,i.value.cleanUrls?"":".html")}${t}${o}`);return de(l)}function W({correspondingLink:s=!1}={}){const{site:e,localeIndex:t,page:o,theme:n,hash:i}=V(),l=y(()=>{var d,$;return{label:(d=e.value.locales[t.value])==null?void 0:d.label,link:(($=e.value.locales[t.value])==null?void 0:$.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:y(()=>Object.entries(e.value.locales).flatMap(([d,$])=>l.value.label===$.label?[]:{text:$.label,link:xe($.link||(d==="root"?"/":`/${d}/`),n.value.i18nRouting!==!1&&s,o.value.relativePath.slice(l.value.link.length-1),!e.value.cleanUrls)+i.value})),currentLang:l}}function xe(s,e,t,o){return e?s.replace(/\/$/,"")+ie(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,o?".html":"")):s}const et={class:"NotFound"},tt={class:"code"},nt={class:"title"},ot={class:"quote"},st={class:"action"},at=["href","aria-label"],rt=m({__name:"NotFound",setup(s){const{theme:e}=V(),{currentLang:t}=W();return(o,n)=>{var i,l,f,d,$;return a(),u("div",et,[p("p",tt,N(((i=r(e).notFound)==null?void 0:i.code)??"404"),1),p("h1",nt,N(((l=r(e).notFound)==null?void 0:l.title)??"PAGE NOT FOUND"),1),n[0]||(n[0]=p("div",{class:"divider"},null,-1)),p("blockquote",ot,N(((f=r(e).notFound)==null?void 0:f.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),p("div",st,[p("a",{class:"link",href:r(de)(r(t).link),"aria-label":((d=r(e).notFound)==null?void 0:d.linkLabel)??"go to home"},N((($=r(e).notFound)==null?void 0:$.linkText)??"Take me home"),9,at)])])}}}),it=g(rt,[["__scopeId","data-v-d6be1790"]]);function Te(s,e){if(Array.isArray(s))return J(s);if(s==null)return[];e=ie(e);const t=Object.keys(s).sort((n,i)=>i.split("/").length-n.split("/").length).find(n=>e.startsWith(ie(n))),o=t?s[t]:[];return Array.isArray(o)?J(o):J(o.items,o.base)}function lt(s){const e=[];let t=0;for(const o in s){const n=s[o];if(n.items){t=e.push(n);continue}e[t]||e.push({items:[]}),e[t].items.push(n)}return e}function ct(s){const e=[];function t(o){for(const n of o)n.text&&n.link&&e.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&t(n.items)}return t(s),e}function le(s,e){return Array.isArray(e)?e.some(t=>le(s,t)):z(s,e.link)?!0:e.items?le(s,e.items):!1}function J(s,e){return[...s].map(t=>{const o={...t},n=o.base||e;return n&&o.link&&(o.link=n+o.link),o.items&&(o.items=J(o.items,n)),o})}function G(){const{frontmatter:s,page:e,theme:t}=V(),o=ae("(min-width: 960px)"),n=M(!1),i=y(()=>{const B=t.value.sidebar,S=e.value.relativePath;return B?Te(B,S):[]}),l=M(i.value);O(i,(B,S)=>{JSON.stringify(B)!==JSON.stringify(S)&&(l.value=i.value)});const f=y(()=>s.value.sidebar!==!1&&l.value.length>0&&s.value.layout!=="home"),d=y(()=>$?s.value.aside==null?t.value.aside==="left":s.value.aside==="left":!1),$=y(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:t.value.aside!==!1),L=y(()=>f.value&&o.value),b=y(()=>f.value?lt(l.value):[]);function P(){n.value=!0}function T(){n.value=!1}function A(){n.value?T():P()}return{isOpen:n,sidebar:l,sidebarGroups:b,hasSidebar:f,hasAside:$,leftAside:d,isSidebarEnabled:L,open:P,close:T,toggle:A}}function ut(s,e){let t;Y(()=>{t=s.value?document.activeElement:void 0}),K(()=>{window.addEventListener("keyup",o)}),ve(()=>{window.removeEventListener("keyup",o)});function o(n){n.key==="Escape"&&s.value&&(e(),t==null||t.focus())}}function dt(s){const{page:e,hash:t}=V(),o=M(!1),n=y(()=>s.value.collapsed!=null),i=y(()=>!!s.value.link),l=M(!1),f=()=>{l.value=z(e.value.relativePath,s.value.link)};O([e,s,t],f),K(f);const d=y(()=>l.value?!0:s.value.items?le(e.value.relativePath,s.value.items):!1),$=y(()=>!!(s.value.items&&s.value.items.length));Y(()=>{o.value=!!(n.value&&s.value.collapsed)}),pe(()=>{(l.value||d.value)&&(o.value=!1)});function L(){n.value&&(o.value=!o.value)}return{collapsed:o,collapsible:n,isLink:i,isActiveLink:l,hasActiveLink:d,hasChildren:$,toggle:L}}function vt(){const{hasSidebar:s}=G(),e=ae("(min-width: 960px)"),t=ae("(min-width: 1280px)");return{isAsideEnabled:y(()=>!t.value&&!e.value?!1:s.value?t.value:e.value)}}const ce=[];function Ne(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function he(s){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const o=Number(t.tagName[1]);return{element:t,title:pt(t),link:"#"+t.id,level:o}});return ft(e,s)}function pt(s){let e="";for(const t of s.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function ft(s,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[o,n]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;s=s.filter(l=>l.level>=o&&l.level<=n),ce.length=0;for(const{element:l,link:f}of s)ce.push({element:l,link:f});const i=[];e:for(let l=0;l=0;d--){const $=s[d];if($.level{requestAnimationFrame(i),window.addEventListener("scroll",o)}),Ee(()=>{l(location.hash)}),ve(()=>{window.removeEventListener("scroll",o)});function i(){if(!t.value)return;const f=window.scrollY,d=window.innerHeight,$=document.body.offsetHeight,L=Math.abs(f+d-$)<1,b=ce.map(({element:T,link:A})=>({link:A,top:mt(T)})).filter(({top:T})=>!Number.isNaN(T)).sort((T,A)=>T.top-A.top);if(!b.length){l(null);return}if(f<1){l(null);return}if(L){l(b[b.length-1].link);return}let P=null;for(const{link:T,top:A}of b){if(A>f+Fe()+4)break;P=T}l(P)}function l(f){n&&n.classList.remove("active"),f==null?n=null:n=s.value.querySelector(`a[href="${decodeURIComponent(f)}"]`);const d=n;d?(d.classList.add("active"),e.value.style.top=d.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function mt(s){let e=0;for(;s!==document.body;){if(s===null)return NaN;e+=s.offsetTop,s=s.offsetParent}return e}const _t=["href","title"],kt=m({__name:"VPDocOutlineItem",props:{headers:{},root:{type:Boolean}},setup(s){function e({target:t}){const o=t.href.split("#")[1],n=document.getElementById(decodeURIComponent(o));n==null||n.focus({preventScroll:!0})}return(t,o)=>{const n=q("VPDocOutlineItem",!0);return a(),u("ul",{class:w(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),u(I,null,C(t.headers,({children:i,link:l,title:f})=>(a(),u("li",null,[p("a",{class:"outline-link",href:l,onClick:e,title:f},N(f),9,_t),i!=null&&i.length?(a(),k(n,{key:0,headers:i},null,8,["headers"])):h("",!0)]))),256))],2)}}}),Me=g(kt,[["__scopeId","data-v-b933a997"]]),bt={class:"content"},gt={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},$t=m({__name:"VPDocAsideOutline",setup(s){const{frontmatter:e,theme:t}=V(),o=$e([]);Q(()=>{o.value=he(e.value.outline??t.value.outline)});const n=M(),i=M();return ht(n,i),(l,f)=>(a(),u("nav",{"aria-labelledby":"doc-outline-aria-label",class:w(["VPDocAsideOutline",{"has-outline":o.value.length>0}]),ref_key:"container",ref:n},[p("div",bt,[p("div",{class:"outline-marker",ref_key:"marker",ref:i},null,512),p("div",gt,N(r(Ne)(r(t))),1),_(Me,{headers:o.value,root:!0},null,8,["headers"])])],2))}}),yt=g($t,[["__scopeId","data-v-a5bbad30"]]),Pt={class:"VPDocAsideCarbonAds"},Vt=m({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const e=()=>null;return(t,o)=>(a(),u("div",Pt,[_(r(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Lt={class:"VPDocAside"},St=m({__name:"VPDocAside",setup(s){const{theme:e}=V();return(t,o)=>(a(),u("div",Lt,[c(t.$slots,"aside-top",{},void 0,!0),c(t.$slots,"aside-outline-before",{},void 0,!0),_(yt),c(t.$slots,"aside-outline-after",{},void 0,!0),o[0]||(o[0]=p("div",{class:"spacer"},null,-1)),c(t.$slots,"aside-ads-before",{},void 0,!0),r(e).carbonAds?(a(),k(Vt,{key:0,"carbon-ads":r(e).carbonAds},null,8,["carbon-ads"])):h("",!0),c(t.$slots,"aside-ads-after",{},void 0,!0),c(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Tt=g(St,[["__scopeId","data-v-3f215769"]]);function Nt(){const{theme:s,page:e}=V();return y(()=>{const{text:t="Edit this page",pattern:o=""}=s.value.editLink||{};let n;return typeof o=="function"?n=o(e.value):n=o.replace(/:path/g,e.value.filePath),{url:n,text:t}})}function Mt(){const{page:s,theme:e,frontmatter:t}=V();return y(()=>{var $,L,b,P,T,A,B,S;const o=Te(e.value.sidebar,s.value.relativePath),n=ct(o),i=wt(n,H=>H.link.replace(/[?#].*$/,"")),l=i.findIndex(H=>z(s.value.relativePath,H.link)),f=(($=e.value.docFooter)==null?void 0:$.prev)===!1&&!t.value.prev||t.value.prev===!1,d=((L=e.value.docFooter)==null?void 0:L.next)===!1&&!t.value.next||t.value.next===!1;return{prev:f?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((b=i[l-1])==null?void 0:b.docFooterText)??((P=i[l-1])==null?void 0:P.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((T=i[l-1])==null?void 0:T.link)},next:d?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((A=i[l+1])==null?void 0:A.docFooterText)??((B=i[l+1])==null?void 0:B.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((S=i[l+1])==null?void 0:S.link)}}})}function wt(s,e){const t=new Set;return s.filter(o=>{const n=e(o);return t.has(n)?!1:t.add(n)})}const F=m({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const e=s,t=y(()=>e.tag??(e.href?"a":"span")),o=y(()=>e.href&&ye.test(e.href)||e.target==="_blank");return(n,i)=>(a(),k(E(t.value),{class:w(["VPLink",{link:n.href,"vp-external-link-icon":o.value,"no-icon":n.noIcon}]),href:n.href?r(fe)(n.href):void 0,target:n.target??(o.value?"_blank":void 0),rel:n.rel??(o.value?"noreferrer":void 0)},{default:v(()=>[c(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),It={class:"VPLastUpdated"},At=["datetime"],Bt=m({__name:"VPDocFooterLastUpdated",setup(s){const{theme:e,page:t,lang:o}=V(),n=y(()=>new Date(t.value.lastUpdated)),i=y(()=>n.value.toISOString()),l=M("");return K(()=>{Y(()=>{var f,d,$;l.value=new Intl.DateTimeFormat((d=(f=e.value.lastUpdated)==null?void 0:f.formatOptions)!=null&&d.forceLocale?o.value:void 0,(($=e.value.lastUpdated)==null?void 0:$.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(n.value)})}),(f,d)=>{var $;return a(),u("p",It,[D(N((($=r(e).lastUpdated)==null?void 0:$.text)||r(e).lastUpdatedText||"Last updated")+": ",1),p("time",{datetime:i.value},N(l.value),9,At)])}}}),Ct=g(Bt,[["__scopeId","data-v-e98dd255"]]),Ht={key:0,class:"VPDocFooter"},Et={key:0,class:"edit-info"},Ft={key:0,class:"edit-link"},Dt={key:1,class:"last-updated"},Ot={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},Gt={class:"pager"},Ut=["innerHTML"],jt=["innerHTML"],zt={class:"pager"},Kt=["innerHTML"],qt=["innerHTML"],Rt=m({__name:"VPDocFooter",setup(s){const{theme:e,page:t,frontmatter:o}=V(),n=Nt(),i=Mt(),l=y(()=>e.value.editLink&&o.value.editLink!==!1),f=y(()=>t.value.lastUpdated),d=y(()=>l.value||f.value||i.value.prev||i.value.next);return($,L)=>{var b,P,T,A;return d.value?(a(),u("footer",Ht,[c($.$slots,"doc-footer-before",{},void 0,!0),l.value||f.value?(a(),u("div",Et,[l.value?(a(),u("div",Ft,[_(F,{class:"edit-link-button",href:r(n).url,"no-icon":!0},{default:v(()=>[L[0]||(L[0]=p("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),D(" "+N(r(n).text),1)]),_:1},8,["href"])])):h("",!0),f.value?(a(),u("div",Dt,[_(Ct)])):h("",!0)])):h("",!0),(b=r(i).prev)!=null&&b.link||(P=r(i).next)!=null&&P.link?(a(),u("nav",Ot,[L[1]||(L[1]=p("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),p("div",Gt,[(T=r(i).prev)!=null&&T.link?(a(),k(F,{key:0,class:"pager-link prev",href:r(i).prev.link},{default:v(()=>{var B;return[p("span",{class:"desc",innerHTML:((B=r(e).docFooter)==null?void 0:B.prev)||"Previous page"},null,8,Ut),p("span",{class:"title",innerHTML:r(i).prev.text},null,8,jt)]}),_:1},8,["href"])):h("",!0)]),p("div",zt,[(A=r(i).next)!=null&&A.link?(a(),k(F,{key:0,class:"pager-link next",href:r(i).next.link},{default:v(()=>{var B;return[p("span",{class:"desc",innerHTML:((B=r(e).docFooter)==null?void 0:B.next)||"Next page"},null,8,Kt),p("span",{class:"title",innerHTML:r(i).next.text},null,8,qt)]}),_:1},8,["href"])):h("",!0)])])):h("",!0)])):h("",!0)}}}),Wt=g(Rt,[["__scopeId","data-v-e257564d"]]),Jt={class:"container"},Xt={class:"aside-container"},Yt={class:"aside-content"},Qt={class:"content"},Zt={class:"content-container"},xt={class:"main"},en=m({__name:"VPDoc",setup(s){const{theme:e}=V(),t=Z(),{hasSidebar:o,hasAside:n,leftAside:i}=G(),l=y(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(f,d)=>{const $=q("Content");return a(),u("div",{class:w(["VPDoc",{"has-sidebar":r(o),"has-aside":r(n)}])},[c(f.$slots,"doc-top",{},void 0,!0),p("div",Jt,[r(n)?(a(),u("div",{key:0,class:w(["aside",{"left-aside":r(i)}])},[d[0]||(d[0]=p("div",{class:"aside-curtain"},null,-1)),p("div",Xt,[p("div",Yt,[_(Tt,null,{"aside-top":v(()=>[c(f.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":v(()=>[c(f.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":v(()=>[c(f.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":v(()=>[c(f.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":v(()=>[c(f.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":v(()=>[c(f.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):h("",!0),p("div",Qt,[p("div",Zt,[c(f.$slots,"doc-before",{},void 0,!0),p("main",xt,[_($,{class:w(["vp-doc",[l.value,r(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),_(Wt,null,{"doc-footer-before":v(()=>[c(f.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),c(f.$slots,"doc-after",{},void 0,!0)])])]),c(f.$slots,"doc-bottom",{},void 0,!0)],2)}}}),tn=g(en,[["__scopeId","data-v-39a288b8"]]),nn=m({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(s){const e=s,t=y(()=>e.href&&ye.test(e.href)),o=y(()=>e.tag||e.href?"a":"button");return(n,i)=>(a(),k(E(o.value),{class:w(["VPButton",[n.size,n.theme]]),href:n.href?r(fe)(n.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:v(()=>[D(N(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),on=g(nn,[["__scopeId","data-v-cad61b99"]]),sn=["src","alt"],an=m({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(e,t)=>{const o=q("VPImage",!0);return e.image?(a(),u(I,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),u("img",j({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:r(de)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,sn)):(a(),u(I,{key:1},[_(o,j({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),_(o,j({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):h("",!0)}}}),X=g(an,[["__scopeId","data-v-8426fc1a"]]),rn={class:"container"},ln={class:"main"},cn={key:0,class:"name"},un=["innerHTML"],dn=["innerHTML"],vn=["innerHTML"],pn={key:0,class:"actions"},fn={key:0,class:"image"},hn={class:"image-container"},mn=m({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const e=x("hero-image-slot-exists");return(t,o)=>(a(),u("div",{class:w(["VPHero",{"has-image":t.image||r(e)}])},[p("div",rn,[p("div",ln,[c(t.$slots,"home-hero-info-before",{},void 0,!0),c(t.$slots,"home-hero-info",{},()=>[t.name?(a(),u("h1",cn,[p("span",{innerHTML:t.name,class:"clip"},null,8,un)])):h("",!0),t.text?(a(),u("p",{key:1,innerHTML:t.text,class:"text"},null,8,dn)):h("",!0),t.tagline?(a(),u("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,vn)):h("",!0)],!0),c(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(a(),u("div",pn,[(a(!0),u(I,null,C(t.actions,n=>(a(),u("div",{key:n.link,class:"action"},[_(on,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):h("",!0),c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||r(e)?(a(),u("div",fn,[p("div",hn,[o[0]||(o[0]=p("div",{class:"image-bg"},null,-1)),c(t.$slots,"home-hero-image",{},()=>[t.image?(a(),k(X,{key:0,class:"image-src",image:t.image},null,8,["image"])):h("",!0)],!0)])])):h("",!0)])],2))}}),_n=g(mn,[["__scopeId","data-v-303bb580"]]),kn=m({__name:"VPHomeHero",setup(s){const{frontmatter:e}=V();return(t,o)=>r(e).hero?(a(),k(_n,{key:0,class:"VPHomeHero",name:r(e).hero.name,text:r(e).hero.text,tagline:r(e).hero.tagline,image:r(e).hero.image,actions:r(e).hero.actions},{"home-hero-info-before":v(()=>[c(t.$slots,"home-hero-info-before")]),"home-hero-info":v(()=>[c(t.$slots,"home-hero-info")]),"home-hero-info-after":v(()=>[c(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":v(()=>[c(t.$slots,"home-hero-actions-after")]),"home-hero-image":v(()=>[c(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):h("",!0)}}),bn={class:"box"},gn={key:0,class:"icon"},$n=["innerHTML"],yn=["innerHTML"],Pn=["innerHTML"],Vn={key:4,class:"link-text"},Ln={class:"link-text-value"},Sn=m({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(e,t)=>(a(),k(F,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:v(()=>[p("article",bn,[typeof e.icon=="object"&&e.icon.wrap?(a(),u("div",gn,[_(X,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(a(),k(X,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(a(),u("div",{key:2,class:"icon",innerHTML:e.icon},null,8,$n)):h("",!0),p("h2",{class:"title",innerHTML:e.title},null,8,yn),e.details?(a(),u("p",{key:3,class:"details",innerHTML:e.details},null,8,Pn)):h("",!0),e.linkText?(a(),u("div",Vn,[p("p",Ln,[D(N(e.linkText)+" ",1),t[0]||(t[0]=p("span",{class:"vpi-arrow-right link-text-icon"},null,-1))])])):h("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),Tn=g(Sn,[["__scopeId","data-v-a3976bdc"]]),Nn={key:0,class:"VPFeatures"},Mn={class:"container"},wn={class:"items"},In=m({__name:"VPFeatures",props:{features:{}},setup(s){const e=s,t=y(()=>{const o=e.features.length;if(o){if(o===2)return"grid-2";if(o===3)return"grid-3";if(o%3===0)return"grid-6";if(o>3)return"grid-4"}else return});return(o,n)=>o.features?(a(),u("div",Nn,[p("div",Mn,[p("div",wn,[(a(!0),u(I,null,C(o.features,i=>(a(),u("div",{key:i.title,class:w(["item",[t.value]])},[_(Tn,{icon:i.icon,title:i.title,details:i.details,link:i.link,"link-text":i.linkText,rel:i.rel,target:i.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):h("",!0)}}),An=g(In,[["__scopeId","data-v-a6181336"]]),Bn=m({__name:"VPHomeFeatures",setup(s){const{frontmatter:e}=V();return(t,o)=>r(e).features?(a(),k(An,{key:0,class:"VPHomeFeatures",features:r(e).features},null,8,["features"])):h("",!0)}}),Cn=m({__name:"VPHomeContent",setup(s){const{width:e}=De({initialWidth:0,includeScrollbar:!1});return(t,o)=>(a(),u("div",{class:"vp-doc container",style:Pe(r(e)?{"--vp-offset":`calc(50% - ${r(e)/2}px)`}:{})},[c(t.$slots,"default",{},void 0,!0)],4))}}),Hn=g(Cn,[["__scopeId","data-v-8e2d4988"]]),En={class:"VPHome"},Fn=m({__name:"VPHome",setup(s){const{frontmatter:e}=V();return(t,o)=>{const n=q("Content");return a(),u("div",En,[c(t.$slots,"home-hero-before",{},void 0,!0),_(kn,null,{"home-hero-info-before":v(()=>[c(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":v(()=>[c(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":v(()=>[c(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":v(()=>[c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":v(()=>[c(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),c(t.$slots,"home-hero-after",{},void 0,!0),c(t.$slots,"home-features-before",{},void 0,!0),_(Bn),c(t.$slots,"home-features-after",{},void 0,!0),r(e).markdownStyles!==!1?(a(),k(Hn,{key:0},{default:v(()=>[_(n)]),_:1})):(a(),k(n,{key:1}))])}}}),Dn=g(Fn,[["__scopeId","data-v-686f80a6"]]),On={},Gn={class:"VPPage"};function Un(s,e){const t=q("Content");return a(),u("div",Gn,[c(s.$slots,"page-top"),_(t),c(s.$slots,"page-bottom")])}const jn=g(On,[["render",Un]]),zn=m({__name:"VPContent",setup(s){const{page:e,frontmatter:t}=V(),{hasSidebar:o}=G();return(n,i)=>(a(),u("div",{class:w(["VPContent",{"has-sidebar":r(o),"is-home":r(t).layout==="home"}]),id:"VPContent"},[r(e).isNotFound?c(n.$slots,"not-found",{key:0},()=>[_(it)],!0):r(t).layout==="page"?(a(),k(jn,{key:1},{"page-top":v(()=>[c(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":v(()=>[c(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):r(t).layout==="home"?(a(),k(Dn,{key:2},{"home-hero-before":v(()=>[c(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":v(()=>[c(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":v(()=>[c(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":v(()=>[c(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":v(()=>[c(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":v(()=>[c(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":v(()=>[c(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":v(()=>[c(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":v(()=>[c(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):r(t).layout&&r(t).layout!=="doc"?(a(),k(E(r(t).layout),{key:3})):(a(),k(tn,{key:4},{"doc-top":v(()=>[c(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":v(()=>[c(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":v(()=>[c(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":v(()=>[c(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":v(()=>[c(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":v(()=>[c(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":v(()=>[c(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":v(()=>[c(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":v(()=>[c(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":v(()=>[c(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":v(()=>[c(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),Kn=g(zn,[["__scopeId","data-v-1428d186"]]),qn={class:"container"},Rn=["innerHTML"],Wn=["innerHTML"],Jn=m({__name:"VPFooter",setup(s){const{theme:e,frontmatter:t}=V(),{hasSidebar:o}=G();return(n,i)=>r(e).footer&&r(t).footer!==!1?(a(),u("footer",{key:0,class:w(["VPFooter",{"has-sidebar":r(o)}])},[p("div",qn,[r(e).footer.message?(a(),u("p",{key:0,class:"message",innerHTML:r(e).footer.message},null,8,Rn)):h("",!0),r(e).footer.copyright?(a(),u("p",{key:1,class:"copyright",innerHTML:r(e).footer.copyright},null,8,Wn)):h("",!0)])],2)):h("",!0)}}),Xn=g(Jn,[["__scopeId","data-v-e315a0ad"]]);function Yn(){const{theme:s,frontmatter:e}=V(),t=$e([]),o=y(()=>t.value.length>0);return Q(()=>{t.value=he(e.value.outline??s.value.outline)}),{headers:t,hasLocalNav:o}}const Qn={class:"menu-text"},Zn={class:"header"},xn={class:"outline"},eo=m({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const e=s,{theme:t}=V(),o=M(!1),n=M(0),i=M(),l=M();function f(b){var P;(P=i.value)!=null&&P.contains(b.target)||(o.value=!1)}O(o,b=>{if(b){document.addEventListener("click",f);return}document.removeEventListener("click",f)}),re("Escape",()=>{o.value=!1}),Q(()=>{o.value=!1});function d(){o.value=!o.value,n.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function $(b){b.target.classList.contains("outline-link")&&(l.value&&(l.value.style.transition="none"),Oe(()=>{o.value=!1}))}function L(){o.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(b,P)=>(a(),u("div",{class:"VPLocalNavOutlineDropdown",style:Pe({"--vp-vh":n.value+"px"}),ref_key:"main",ref:i},[b.headers.length>0?(a(),u("button",{key:0,onClick:d,class:w({open:o.value})},[p("span",Qn,N(r(Ne)(r(t))),1),P[0]||(P[0]=p("span",{class:"vpi-chevron-right icon"},null,-1))],2)):(a(),u("button",{key:1,onClick:L},N(r(t).returnToTopLabel||"Return to top"),1)),_(ue,{name:"flyout"},{default:v(()=>[o.value?(a(),u("div",{key:0,ref_key:"items",ref:l,class:"items",onClick:$},[p("div",Zn,[p("a",{class:"top-link",href:"#",onClick:L},N(r(t).returnToTopLabel||"Return to top"),1)]),p("div",xn,[_(Me,{headers:b.headers},null,8,["headers"])])],512)):h("",!0)]),_:1})],4))}}),to=g(eo,[["__scopeId","data-v-17a5e62e"]]),no={class:"container"},oo=["aria-expanded"],so={class:"menu-text"},ao=m({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:e,frontmatter:t}=V(),{hasSidebar:o}=G(),{headers:n}=Yn(),{y:i}=Ve(),l=M(0);K(()=>{l.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),Q(()=>{n.value=he(t.value.outline??e.value.outline)});const f=y(()=>n.value.length===0),d=y(()=>f.value&&!o.value),$=y(()=>({VPLocalNav:!0,"has-sidebar":o.value,empty:f.value,fixed:d.value}));return(L,b)=>r(t).layout!=="home"&&(!d.value||r(i)>=l.value)?(a(),u("div",{key:0,class:w($.value)},[p("div",no,[r(o)?(a(),u("button",{key:0,class:"menu","aria-expanded":L.open,"aria-controls":"VPSidebarNav",onClick:b[0]||(b[0]=P=>L.$emit("open-menu"))},[b[1]||(b[1]=p("span",{class:"vpi-align-left menu-icon"},null,-1)),p("span",so,N(r(e).sidebarMenuLabel||"Menu"),1)],8,oo)):h("",!0),_(to,{headers:r(n),navHeight:l.value},null,8,["headers","navHeight"])])],2)):h("",!0)}}),ro=g(ao,[["__scopeId","data-v-a6f0e41e"]]);function io(){const s=M(!1);function e(){s.value=!0,window.addEventListener("resize",n)}function t(){s.value=!1,window.removeEventListener("resize",n)}function o(){s.value?t():e()}function n(){window.outerWidth>=768&&t()}const i=Z();return O(()=>i.path,t),{isScreenOpen:s,openScreen:e,closeScreen:t,toggleScreen:o}}const lo={},co={class:"VPSwitch",type:"button",role:"switch"},uo={class:"check"},vo={key:0,class:"icon"};function po(s,e){return a(),u("button",co,[p("span",uo,[s.$slots.default?(a(),u("span",vo,[c(s.$slots,"default",{},void 0,!0)])):h("",!0)])])}const fo=g(lo,[["render",po],["__scopeId","data-v-1d5665e3"]]),ho=m({__name:"VPSwitchAppearance",setup(s){const{isDark:e,theme:t}=V(),o=x("toggle-appearance",()=>{e.value=!e.value}),n=M("");return pe(()=>{n.value=e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme"}),(i,l)=>(a(),k(fo,{title:n.value,class:"VPSwitchAppearance","aria-checked":r(e),onClick:r(o)},{default:v(()=>l[0]||(l[0]=[p("span",{class:"vpi-sun sun"},null,-1),p("span",{class:"vpi-moon moon"},null,-1)])),_:1},8,["title","aria-checked","onClick"]))}}),me=g(ho,[["__scopeId","data-v-5337faa4"]]),mo={key:0,class:"VPNavBarAppearance"},_o=m({__name:"VPNavBarAppearance",setup(s){const{site:e}=V();return(t,o)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",mo,[_(me)])):h("",!0)}}),ko=g(_o,[["__scopeId","data-v-6c893767"]]),_e=M();let we=!1,se=0;function bo(s){const e=M(!1);if(ee){!we&&go(),se++;const t=O(_e,o=>{var n,i,l;o===s.el.value||(n=s.el.value)!=null&&n.contains(o)?(e.value=!0,(i=s.onFocus)==null||i.call(s)):(e.value=!1,(l=s.onBlur)==null||l.call(s))});ve(()=>{t(),se--,se||$o()})}return Ge(e)}function go(){document.addEventListener("focusin",Ie),we=!0,_e.value=document.activeElement}function $o(){document.removeEventListener("focusin",Ie)}function Ie(){_e.value=document.activeElement}const yo={class:"VPMenuLink"},Po=m({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:e}=V();return(t,o)=>(a(),u("div",yo,[_(F,{class:w({active:r(z)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel},{default:v(()=>[D(N(t.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),te=g(Po,[["__scopeId","data-v-43f1e123"]]),Vo={class:"VPMenuGroup"},Lo={key:0,class:"title"},So=m({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",Vo,[e.text?(a(),u("p",Lo,N(e.text),1)):h("",!0),(a(!0),u(I,null,C(e.items,o=>(a(),u(I,null,["link"in o?(a(),k(te,{key:0,item:o},null,8,["item"])):h("",!0)],64))),256))]))}}),To=g(So,[["__scopeId","data-v-69e747b5"]]),No={class:"VPMenu"},Mo={key:0,class:"items"},wo=m({__name:"VPMenu",props:{items:{}},setup(s){return(e,t)=>(a(),u("div",No,[e.items?(a(),u("div",Mo,[(a(!0),u(I,null,C(e.items,o=>(a(),u(I,{key:JSON.stringify(o)},["link"in o?(a(),k(te,{key:0,item:o},null,8,["item"])):"component"in o?(a(),k(E(o.component),j({key:1,ref_for:!0},o.props),null,16)):(a(),k(To,{key:2,text:o.text,items:o.items},null,8,["text","items"]))],64))),128))])):h("",!0),c(e.$slots,"default",{},void 0,!0)]))}}),Io=g(wo,[["__scopeId","data-v-b98bc113"]]),Ao=["aria-expanded","aria-label"],Bo={key:0,class:"text"},Co=["innerHTML"],Ho={key:1,class:"vpi-more-horizontal icon"},Eo={class:"menu"},Fo=m({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const e=M(!1),t=M();bo({el:t,onBlur:o});function o(){e.value=!1}return(n,i)=>(a(),u("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:i[1]||(i[1]=l=>e.value=!0),onMouseleave:i[2]||(i[2]=l=>e.value=!1)},[p("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":n.label,onClick:i[0]||(i[0]=l=>e.value=!e.value)},[n.button||n.icon?(a(),u("span",Bo,[n.icon?(a(),u("span",{key:0,class:w([n.icon,"option-icon"])},null,2)):h("",!0),n.button?(a(),u("span",{key:1,innerHTML:n.button},null,8,Co)):h("",!0),i[3]||(i[3]=p("span",{class:"vpi-chevron-down text-icon"},null,-1))])):(a(),u("span",Ho))],8,Ao),p("div",Eo,[_(Io,{items:n.items},{default:v(()=>[c(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),ke=g(Fo,[["__scopeId","data-v-b6c34ac9"]]),Do=["href","aria-label","innerHTML"],Oo=m({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const e=s,t=y(()=>typeof e.icon=="object"?e.icon.svg:``);return(o,n)=>(a(),u("a",{class:"VPSocialLink no-icon",href:o.link,"aria-label":o.ariaLabel??(typeof o.icon=="string"?o.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,Do))}}),Go=g(Oo,[["__scopeId","data-v-eee4e7cb"]]),Uo={class:"VPSocialLinks"},jo=m({__name:"VPSocialLinks",props:{links:{}},setup(s){return(e,t)=>(a(),u("div",Uo,[(a(!0),u(I,null,C(e.links,({link:o,icon:n,ariaLabel:i})=>(a(),k(Go,{key:o,icon:n,link:o,ariaLabel:i},null,8,["icon","link","ariaLabel"]))),128))]))}}),be=g(jo,[["__scopeId","data-v-7bc22406"]]),zo={key:0,class:"group translations"},Ko={class:"trans-title"},qo={key:1,class:"group"},Ro={class:"item appearance"},Wo={class:"label"},Jo={class:"appearance-action"},Xo={key:2,class:"group"},Yo={class:"item social-links"},Qo=m({__name:"VPNavBarExtra",setup(s){const{site:e,theme:t}=V(),{localeLinks:o,currentLang:n}=W({correspondingLink:!0}),i=y(()=>o.value.length&&n.value.label||e.value.appearance||t.value.socialLinks);return(l,f)=>i.value?(a(),k(ke,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:v(()=>[r(o).length&&r(n).label?(a(),u("div",zo,[p("p",Ko,N(r(n).label),1),(a(!0),u(I,null,C(r(o),d=>(a(),k(te,{key:d.link,item:d},null,8,["item"]))),128))])):h("",!0),r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",qo,[p("div",Ro,[p("p",Wo,N(r(t).darkModeSwitchLabel||"Appearance"),1),p("div",Jo,[_(me)])])])):h("",!0),r(t).socialLinks?(a(),u("div",Xo,[p("div",Yo,[_(be,{class:"social-links-list",links:r(t).socialLinks},null,8,["links"])])])):h("",!0)]),_:1})):h("",!0)}}),Zo=g(Qo,[["__scopeId","data-v-bb2aa2f0"]]),xo=["aria-expanded"],es=m({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(e,t)=>(a(),u("button",{type:"button",class:w(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=o=>e.$emit("click"))},t[1]||(t[1]=[p("span",{class:"container"},[p("span",{class:"top"}),p("span",{class:"middle"}),p("span",{class:"bottom"})],-1)]),10,xo))}}),ts=g(es,[["__scopeId","data-v-e5dd9c1c"]]),ns=["innerHTML"],os=m({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:e}=V();return(t,o)=>(a(),k(F,{class:w({VPNavBarMenuLink:!0,active:r(z)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,noIcon:t.item.noIcon,target:t.item.target,rel:t.item.rel,tabindex:"0"},{default:v(()=>[p("span",{innerHTML:t.item.text},null,8,ns)]),_:1},8,["class","href","noIcon","target","rel"]))}}),ss=g(os,[["__scopeId","data-v-9c663999"]]),as=m({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const e=s,{page:t}=V(),o=i=>"component"in i?!1:"link"in i?z(t.value.relativePath,i.link,!!e.item.activeMatch):i.items.some(o),n=y(()=>o(e.item));return(i,l)=>(a(),k(ke,{class:w({VPNavBarMenuGroup:!0,active:r(z)(r(t).relativePath,i.item.activeMatch,!!i.item.activeMatch)||n.value}),button:i.item.text,items:i.item.items},null,8,["class","button","items"]))}}),rs={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},is=m({__name:"VPNavBarMenu",setup(s){const{theme:e}=V();return(t,o)=>r(e).nav?(a(),u("nav",rs,[o[0]||(o[0]=p("span",{id:"main-nav-aria-label",class:"visually-hidden"}," Main Navigation ",-1)),(a(!0),u(I,null,C(r(e).nav,n=>(a(),u(I,{key:JSON.stringify(n)},["link"in n?(a(),k(ss,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),j({key:1,ref_for:!0},n.props),null,16)):(a(),k(as,{key:2,item:n},null,8,["item"]))],64))),128))])):h("",!0)}}),ls=g(is,[["__scopeId","data-v-dc692963"]]);function cs(s){const{localeIndex:e,theme:t}=V();function o(n){var A,B,S;const i=n.split("."),l=(A=t.value.search)==null?void 0:A.options,f=l&&typeof l=="object",d=f&&((S=(B=l.locales)==null?void 0:B[e.value])==null?void 0:S.translations)||null,$=f&&l.translations||null;let L=d,b=$,P=s;const T=i.pop();for(const H of i){let U=null;const R=P==null?void 0:P[H];R&&(U=P=R);const ne=b==null?void 0:b[H];ne&&(U=b=ne);const oe=L==null?void 0:L[H];oe&&(U=L=oe),R||(P=U),ne||(b=U),oe||(L=U)}return(L==null?void 0:L[T])??(b==null?void 0:b[T])??(P==null?void 0:P[T])??""}return o}const us=["aria-label"],ds={class:"DocSearch-Button-Container"},vs={class:"DocSearch-Button-Placeholder"},ge=m({__name:"VPNavBarSearchButton",setup(s){const t=cs({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(o,n)=>(a(),u("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":r(t)("button.buttonAriaLabel")},[p("span",ds,[n[0]||(n[0]=p("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1)),p("span",vs,N(r(t)("button.buttonText")),1)]),n[1]||(n[1]=p("span",{class:"DocSearch-Button-Keys"},[p("kbd",{class:"DocSearch-Button-Key"}),p("kbd",{class:"DocSearch-Button-Key"},"K")],-1))],8,us))}}),ps={class:"VPNavBarSearch"},fs={id:"local-search"},hs={key:1,id:"docsearch"},ms=m({__name:"VPNavBarSearch",setup(s){const e=Ue(()=>je(()=>import("./VPLocalSearchBox.D0OKQOhX.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:o}=V(),n=M(!1),i=M(!1);K(()=>{});function l(){n.value||(n.value=!0,setTimeout(f,16))}function f(){const b=new Event("keydown");b.key="k",b.metaKey=!0,window.dispatchEvent(b),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||f()},16)}function d(b){const P=b.target,T=P.tagName;return P.isContentEditable||T==="INPUT"||T==="SELECT"||T==="TEXTAREA"}const $=M(!1);re("k",b=>{(b.ctrlKey||b.metaKey)&&(b.preventDefault(),$.value=!0)}),re("/",b=>{d(b)||(b.preventDefault(),$.value=!0)});const L="local";return(b,P)=>{var T;return a(),u("div",ps,[r(L)==="local"?(a(),u(I,{key:0},[$.value?(a(),k(r(e),{key:0,onClose:P[0]||(P[0]=A=>$.value=!1)})):h("",!0),p("div",fs,[_(ge,{onClick:P[1]||(P[1]=A=>$.value=!0)})])],64)):r(L)==="algolia"?(a(),u(I,{key:1},[n.value?(a(),k(r(t),{key:0,algolia:((T=r(o).search)==null?void 0:T.options)??r(o).algolia,onVnodeBeforeMount:P[2]||(P[2]=A=>i.value=!0)},null,8,["algolia"])):h("",!0),i.value?h("",!0):(a(),u("div",hs,[_(ge,{onClick:l})]))],64)):h("",!0)])}}}),_s=m({__name:"VPNavBarSocialLinks",setup(s){const{theme:e}=V();return(t,o)=>r(e).socialLinks?(a(),k(be,{key:0,class:"VPNavBarSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),ks=g(_s,[["__scopeId","data-v-0394ad82"]]),bs=["href","rel","target"],gs={key:1},$s={key:2},ys=m({__name:"VPNavBarTitle",setup(s){const{site:e,theme:t}=V(),{hasSidebar:o}=G(),{currentLang:n}=W(),i=y(()=>{var d;return typeof t.value.logoLink=="string"?t.value.logoLink:(d=t.value.logoLink)==null?void 0:d.link}),l=y(()=>{var d;return typeof t.value.logoLink=="string"||(d=t.value.logoLink)==null?void 0:d.rel}),f=y(()=>{var d;return typeof t.value.logoLink=="string"||(d=t.value.logoLink)==null?void 0:d.target});return(d,$)=>(a(),u("div",{class:w(["VPNavBarTitle",{"has-sidebar":r(o)}])},[p("a",{class:"title",href:i.value??r(fe)(r(n).link),rel:l.value,target:f.value},[c(d.$slots,"nav-bar-title-before",{},void 0,!0),r(t).logo?(a(),k(X,{key:0,class:"logo",image:r(t).logo},null,8,["image"])):h("",!0),r(t).siteTitle?(a(),u("span",gs,N(r(t).siteTitle),1)):r(t).siteTitle===void 0?(a(),u("span",$s,N(r(e).title),1)):h("",!0),c(d.$slots,"nav-bar-title-after",{},void 0,!0)],8,bs)],2))}}),Ps=g(ys,[["__scopeId","data-v-ab179fa1"]]),Vs={class:"items"},Ls={class:"title"},Ss=m({__name:"VPNavBarTranslations",setup(s){const{theme:e}=V(),{localeLinks:t,currentLang:o}=W({correspondingLink:!0});return(n,i)=>r(t).length&&r(o).label?(a(),k(ke,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:r(e).langMenuLabel||"Change language"},{default:v(()=>[p("div",Vs,[p("p",Ls,N(r(o).label),1),(a(!0),u(I,null,C(r(t),l=>(a(),k(te,{key:l.link,item:l},null,8,["item"]))),128))])]),_:1},8,["label"])):h("",!0)}}),Ts=g(Ss,[["__scopeId","data-v-88af2de4"]]),Ns={class:"wrapper"},Ms={class:"container"},ws={class:"title"},Is={class:"content"},As={class:"content-body"},Bs=m({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const e=s,{y:t}=Ve(),{hasSidebar:o}=G(),{frontmatter:n}=V(),i=M({});return pe(()=>{i.value={"has-sidebar":o.value,home:n.value.layout==="home",top:t.value===0,"screen-open":e.isScreenOpen}}),(l,f)=>(a(),u("div",{class:w(["VPNavBar",i.value])},[p("div",Ns,[p("div",Ms,[p("div",ws,[_(Ps,null,{"nav-bar-title-before":v(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":v(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),p("div",Is,[p("div",As,[c(l.$slots,"nav-bar-content-before",{},void 0,!0),_(ms,{class:"search"}),_(ls,{class:"menu"}),_(Ts,{class:"translations"}),_(ko,{class:"appearance"}),_(ks,{class:"social-links"}),_(Zo,{class:"extra"}),c(l.$slots,"nav-bar-content-after",{},void 0,!0),_(ts,{class:"hamburger",active:l.isScreenOpen,onClick:f[0]||(f[0]=d=>l.$emit("toggle-screen"))},null,8,["active"])])])])]),f[1]||(f[1]=p("div",{class:"divider"},[p("div",{class:"divider-line"})],-1))],2))}}),Cs=g(Bs,[["__scopeId","data-v-6aa21345"]]),Hs={key:0,class:"VPNavScreenAppearance"},Es={class:"text"},Fs=m({__name:"VPNavScreenAppearance",setup(s){const{site:e,theme:t}=V();return(o,n)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",Hs,[p("p",Es,N(r(t).darkModeSwitchLabel||"Appearance"),1),_(me)])):h("",!0)}}),Ds=g(Fs,[["__scopeId","data-v-b44890b2"]]),Os=m({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const e=x("close-screen");return(t,o)=>(a(),k(F,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:r(e),innerHTML:t.item.text},null,8,["href","target","rel","onClick","innerHTML"]))}}),Gs=g(Os,[["__scopeId","data-v-7f31e1f6"]]),Us=m({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const e=x("close-screen");return(t,o)=>(a(),k(F,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:r(e)},{default:v(()=>[D(N(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Ae=g(Us,[["__scopeId","data-v-19976ae1"]]),js={class:"VPNavScreenMenuGroupSection"},zs={key:0,class:"title"},Ks=m({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",js,[e.text?(a(),u("p",zs,N(e.text),1)):h("",!0),(a(!0),u(I,null,C(e.items,o=>(a(),k(Ae,{key:o.text,item:o},null,8,["item"]))),128))]))}}),qs=g(Ks,[["__scopeId","data-v-8133b170"]]),Rs=["aria-controls","aria-expanded"],Ws=["innerHTML"],Js=["id"],Xs={key:0,class:"item"},Ys={key:1,class:"item"},Qs={key:2,class:"group"},Zs=m({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const e=s,t=M(!1),o=y(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function n(){t.value=!t.value}return(i,l)=>(a(),u("div",{class:w(["VPNavScreenMenuGroup",{open:t.value}])},[p("button",{class:"button","aria-controls":o.value,"aria-expanded":t.value,onClick:n},[p("span",{class:"button-text",innerHTML:i.text},null,8,Ws),l[0]||(l[0]=p("span",{class:"vpi-plus button-icon"},null,-1))],8,Rs),p("div",{id:o.value,class:"items"},[(a(!0),u(I,null,C(i.items,f=>(a(),u(I,{key:JSON.stringify(f)},["link"in f?(a(),u("div",Xs,[_(Ae,{item:f},null,8,["item"])])):"component"in f?(a(),u("div",Ys,[(a(),k(E(f.component),j({ref_for:!0},f.props,{"screen-menu":""}),null,16))])):(a(),u("div",Qs,[_(qs,{text:f.text,items:f.items},null,8,["text","items"])]))],64))),128))],8,Js)],2))}}),xs=g(Zs,[["__scopeId","data-v-b9ab8c58"]]),ea={key:0,class:"VPNavScreenMenu"},ta=m({__name:"VPNavScreenMenu",setup(s){const{theme:e}=V();return(t,o)=>r(e).nav?(a(),u("nav",ea,[(a(!0),u(I,null,C(r(e).nav,n=>(a(),u(I,{key:JSON.stringify(n)},["link"in n?(a(),k(Gs,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),j({key:1,ref_for:!0},n.props,{"screen-menu":""}),null,16)):(a(),k(xs,{key:2,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):h("",!0)}}),na=m({__name:"VPNavScreenSocialLinks",setup(s){const{theme:e}=V();return(t,o)=>r(e).socialLinks?(a(),k(be,{key:0,class:"VPNavScreenSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),oa={class:"list"},sa=m({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:e,currentLang:t}=W({correspondingLink:!0}),o=M(!1);function n(){o.value=!o.value}return(i,l)=>r(e).length&&r(t).label?(a(),u("div",{key:0,class:w(["VPNavScreenTranslations",{open:o.value}])},[p("button",{class:"title",onClick:n},[l[0]||(l[0]=p("span",{class:"vpi-languages icon lang"},null,-1)),D(" "+N(r(t).label)+" ",1),l[1]||(l[1]=p("span",{class:"vpi-chevron-down icon chevron"},null,-1))]),p("ul",oa,[(a(!0),u(I,null,C(r(e),f=>(a(),u("li",{key:f.link,class:"item"},[_(F,{class:"link",href:f.link},{default:v(()=>[D(N(f.text),1)]),_:2},1032,["href"])]))),128))])],2)):h("",!0)}}),aa=g(sa,[["__scopeId","data-v-858fe1a4"]]),ra={class:"container"},ia=m({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const e=M(null),t=Le(ee?document.body:null);return(o,n)=>(a(),k(ue,{name:"fade",onEnter:n[0]||(n[0]=i=>t.value=!0),onAfterLeave:n[1]||(n[1]=i=>t.value=!1)},{default:v(()=>[o.open?(a(),u("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[p("div",ra,[c(o.$slots,"nav-screen-content-before",{},void 0,!0),_(ta,{class:"menu"}),_(aa,{class:"translations"}),_(Ds,{class:"appearance"}),_(na,{class:"social-links"}),c(o.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):h("",!0)]),_:3}))}}),la=g(ia,[["__scopeId","data-v-f2779853"]]),ca={key:0,class:"VPNav"},ua=m({__name:"VPNav",setup(s){const{isScreenOpen:e,closeScreen:t,toggleScreen:o}=io(),{frontmatter:n}=V(),i=y(()=>n.value.navbar!==!1);return Se("close-screen",t),Y(()=>{ee&&document.documentElement.classList.toggle("hide-nav",!i.value)}),(l,f)=>i.value?(a(),u("header",ca,[_(Cs,{"is-screen-open":r(e),onToggleScreen:r(o)},{"nav-bar-title-before":v(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":v(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":v(()=>[c(l.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":v(()=>[c(l.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),_(la,{open:r(e)},{"nav-screen-content-before":v(()=>[c(l.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":v(()=>[c(l.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):h("",!0)}}),da=g(ua,[["__scopeId","data-v-ae24b3ad"]]),va=["role","tabindex"],pa={key:1,class:"items"},fa=m({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const e=s,{collapsed:t,collapsible:o,isLink:n,isActiveLink:i,hasActiveLink:l,hasChildren:f,toggle:d}=dt(y(()=>e.item)),$=y(()=>f.value?"section":"div"),L=y(()=>n.value?"a":"div"),b=y(()=>f.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),P=y(()=>n.value?void 0:"button"),T=y(()=>[[`level-${e.depth}`],{collapsible:o.value},{collapsed:t.value},{"is-link":n.value},{"is-active":i.value},{"has-active":l.value}]);function A(S){"key"in S&&S.key!=="Enter"||!e.item.link&&d()}function B(){e.item.link&&d()}return(S,H)=>{const U=q("VPSidebarItem",!0);return a(),k(E($.value),{class:w(["VPSidebarItem",T.value])},{default:v(()=>[S.item.text?(a(),u("div",j({key:0,class:"item",role:P.value},Ke(S.item.items?{click:A,keydown:A}:{},!0),{tabindex:S.item.items&&0}),[H[1]||(H[1]=p("div",{class:"indicator"},null,-1)),S.item.link?(a(),k(F,{key:0,tag:L.value,class:"link",href:S.item.link,rel:S.item.rel,target:S.item.target},{default:v(()=>[(a(),k(E(b.value),{class:"text",innerHTML:S.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),k(E(b.value),{key:1,class:"text",innerHTML:S.item.text},null,8,["innerHTML"])),S.item.collapsed!=null&&S.item.items&&S.item.items.length?(a(),u("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:B,onKeydown:ze(B,["enter"]),tabindex:"0"},H[0]||(H[0]=[p("span",{class:"vpi-chevron-right caret-icon"},null,-1)]),32)):h("",!0)],16,va)):h("",!0),S.item.items&&S.item.items.length?(a(),u("div",pa,[S.depth<5?(a(!0),u(I,{key:0},C(S.item.items,R=>(a(),k(U,{key:R.text,item:R,depth:S.depth+1},null,8,["item","depth"]))),128)):h("",!0)])):h("",!0)]),_:1},8,["class"])}}}),ha=g(fa,[["__scopeId","data-v-b7550ba0"]]),ma=m({__name:"VPSidebarGroup",props:{items:{}},setup(s){const e=M(!0);let t=null;return K(()=>{t=setTimeout(()=>{t=null,e.value=!1},300)}),qe(()=>{t!=null&&(clearTimeout(t),t=null)}),(o,n)=>(a(!0),u(I,null,C(o.items,i=>(a(),u("div",{key:i.text,class:w(["group",{"no-transition":e.value}])},[_(ha,{item:i,depth:0},null,8,["item"])],2))),128))}}),_a=g(ma,[["__scopeId","data-v-c40bc020"]]),ka={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},ba=m({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const{sidebarGroups:e,hasSidebar:t}=G(),o=s,n=M(null),i=Le(ee?document.body:null);O([o,n],()=>{var f;o.open?(i.value=!0,(f=n.value)==null||f.focus()):i.value=!1},{immediate:!0,flush:"post"});const l=M(0);return O(e,()=>{l.value+=1},{deep:!0}),(f,d)=>r(t)?(a(),u("aside",{key:0,class:w(["VPSidebar",{open:f.open}]),ref_key:"navEl",ref:n,onClick:d[0]||(d[0]=Re(()=>{},["stop"]))},[d[2]||(d[2]=p("div",{class:"curtain"},null,-1)),p("nav",ka,[d[1]||(d[1]=p("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),c(f.$slots,"sidebar-nav-before",{},void 0,!0),(a(),k(_a,{items:r(e),key:l.value},null,8,["items"])),c(f.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):h("",!0)}}),ga=g(ba,[["__scopeId","data-v-319d5ca6"]]),$a=m({__name:"VPSkipLink",setup(s){const e=Z(),t=M();O(()=>e.path,()=>t.value.focus());function o({target:n}){const i=document.getElementById(decodeURIComponent(n.hash).slice(1));if(i){const l=()=>{i.removeAttribute("tabindex"),i.removeEventListener("blur",l)};i.setAttribute("tabindex","-1"),i.addEventListener("blur",l),i.focus(),window.scrollTo(0,0)}}return(n,i)=>(a(),u(I,null,[p("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),p("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:o}," Skip to content ")],64))}}),ya=g($a,[["__scopeId","data-v-0f60ec36"]]),Pa=m({__name:"Layout",setup(s){const{isOpen:e,open:t,close:o}=G(),n=Z();O(()=>n.path,o),ut(e,o);const{frontmatter:i}=V(),l=We(),f=y(()=>!!l["home-hero-image"]);return Se("hero-image-slot-exists",f),(d,$)=>{const L=q("Content");return r(i).layout!==!1?(a(),u("div",{key:0,class:w(["Layout",r(i).pageClass])},[c(d.$slots,"layout-top",{},void 0,!0),_(ya),_(Qe,{class:"backdrop",show:r(e),onClick:r(o)},null,8,["show","onClick"]),_(da,null,{"nav-bar-title-before":v(()=>[c(d.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":v(()=>[c(d.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":v(()=>[c(d.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":v(()=>[c(d.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":v(()=>[c(d.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":v(()=>[c(d.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),_(ro,{open:r(e),onOpenMenu:r(t)},null,8,["open","onOpenMenu"]),_(ga,{open:r(e)},{"sidebar-nav-before":v(()=>[c(d.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":v(()=>[c(d.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),_(Kn,null,{"page-top":v(()=>[c(d.$slots,"page-top",{},void 0,!0)]),"page-bottom":v(()=>[c(d.$slots,"page-bottom",{},void 0,!0)]),"not-found":v(()=>[c(d.$slots,"not-found",{},void 0,!0)]),"home-hero-before":v(()=>[c(d.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":v(()=>[c(d.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":v(()=>[c(d.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":v(()=>[c(d.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":v(()=>[c(d.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":v(()=>[c(d.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":v(()=>[c(d.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":v(()=>[c(d.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":v(()=>[c(d.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":v(()=>[c(d.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":v(()=>[c(d.$slots,"doc-before",{},void 0,!0)]),"doc-after":v(()=>[c(d.$slots,"doc-after",{},void 0,!0)]),"doc-top":v(()=>[c(d.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":v(()=>[c(d.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":v(()=>[c(d.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":v(()=>[c(d.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":v(()=>[c(d.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":v(()=>[c(d.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":v(()=>[c(d.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":v(()=>[c(d.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),_(Xn),c(d.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),k(L,{key:1}))}}}),Va=g(Pa,[["__scopeId","data-v-5d98c3a5"]]),La={Layout:Va,enhanceApp:({app:s})=>{s.component("Badge",Je)}},Ta={extends:La};export{Ta as R,cs as c,V as u}; diff --git a/assets/components_i18n-link.md.Brr4ULLV.js b/assets/components_i18n-link.md.Brr4ULLV.js new file mode 100644 index 0000000..321ef1f --- /dev/null +++ b/assets/components_i18n-link.md.Brr4ULLV.js @@ -0,0 +1 @@ +import{_ as s,c as a,a2 as t,o as e}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"🌍 Component","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"components/i18n-link.md","filePath":"components/i18n-link.md","lastUpdated":1724679268000}'),n={name:"components/i18n-link.md"};function l(h,i,k,p,o,r){return e(),a("div",null,i[0]||(i[0]=[t('

🌍 <i18n-link> Component

The <i18n-link> component in Nuxt I18n Micro is a versatile link component that automatically localizes routes based on the current locale. It acts as a wrapper around the <NuxtLink> component, providing additional features such as active link styling and support for external links.

⚙️ Props

to

  • Type: NuxtLinkProps | string
  • Required: Yes
  • Description: Defines the target route or path for the link. It can be a string (for simple paths) or an object containing route information.
  • Example:
    vue
    <i18n-link to="/about">About Us</i18n-link>\n<i18n-link :to="{ name: 'index' }">Home</i18n-link>

activeStyle

  • Type: Partial<CSSStyleDeclaration>
  • Optional: Yes
  • Description: Allows you to customize the inline styles applied to the link when it matches the current route. This can be useful for highlighting the active link in navigation menus without relying on CSS classes.
  • Example:
    vue
    <i18n-link to="/about" :activeStyle="{ fontWeight: 'bold', color: 'red' }">About Us</i18n-link>

🛠️ Example Usages

Basic Usage

vue
<i18n-link to="/about">About Us</i18n-link>

This example creates a link to the /about page, localized to the current locale.

vue
<i18n-link to="/about" :activeStyle="{ fontWeight: 'bold' }">About Us</i18n-link>

The link will have bold text when the user is on the /about page, allowing you to style the active link directly with inline styles.

The component automatically detects external links and adds the necessary attributes for security.

vue
<i18n-link to="https://example.com">Visit Example</i18n-link>

This link will open https://example.com in a new tab with rel="noopener noreferrer" applied.

🎨 Styles

The component now uses inline styles for the active state instead of a class. You can customize these styles using the activeStyle prop.

Default Active Styles

  • Font Weight: bold
  • Color: Inherits the browser's default color (if no color is specified in activeStyle).

You can override these by providing custom styles through the activeStyle prop.

Custom Active Styles

vue
<i18n-link to="/about" :activeStyle="{ fontWeight: 'bold', color: '#42b983' }">About Us</i18n-link>

In this example, the link will be bold and green when active.

🚀 Additional Features

Slot for Custom Content

You can pass custom content inside the link using slots, making the component flexible for different use cases.

vue
<i18n-link to="/about">\n  <span>About Us</span>\n</i18n-link>

Accessibility Enhancements

The component supports aria-label and other accessibility attributes to ensure a more accessible experience.

vue
<i18n-link to="/about" aria-label="Learn more about us">\n  About Us\n</i18n-link>
',33)]))}const c=s(n,[["render",l]]);export{E as __pageData,c as default}; diff --git a/assets/components_i18n-link.md.Brr4ULLV.lean.js b/assets/components_i18n-link.md.Brr4ULLV.lean.js new file mode 100644 index 0000000..321ef1f --- /dev/null +++ b/assets/components_i18n-link.md.Brr4ULLV.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,a2 as t,o as e}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"🌍 Component","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"components/i18n-link.md","filePath":"components/i18n-link.md","lastUpdated":1724679268000}'),n={name:"components/i18n-link.md"};function l(h,i,k,p,o,r){return e(),a("div",null,i[0]||(i[0]=[t('

🌍 <i18n-link> Component

The <i18n-link> component in Nuxt I18n Micro is a versatile link component that automatically localizes routes based on the current locale. It acts as a wrapper around the <NuxtLink> component, providing additional features such as active link styling and support for external links.

⚙️ Props

to

  • Type: NuxtLinkProps | string
  • Required: Yes
  • Description: Defines the target route or path for the link. It can be a string (for simple paths) or an object containing route information.
  • Example:
    vue
    <i18n-link to="/about">About Us</i18n-link>\n<i18n-link :to="{ name: 'index' }">Home</i18n-link>

activeStyle

  • Type: Partial<CSSStyleDeclaration>
  • Optional: Yes
  • Description: Allows you to customize the inline styles applied to the link when it matches the current route. This can be useful for highlighting the active link in navigation menus without relying on CSS classes.
  • Example:
    vue
    <i18n-link to="/about" :activeStyle="{ fontWeight: 'bold', color: 'red' }">About Us</i18n-link>

🛠️ Example Usages

Basic Usage

vue
<i18n-link to="/about">About Us</i18n-link>

This example creates a link to the /about page, localized to the current locale.

vue
<i18n-link to="/about" :activeStyle="{ fontWeight: 'bold' }">About Us</i18n-link>

The link will have bold text when the user is on the /about page, allowing you to style the active link directly with inline styles.

The component automatically detects external links and adds the necessary attributes for security.

vue
<i18n-link to="https://example.com">Visit Example</i18n-link>

This link will open https://example.com in a new tab with rel="noopener noreferrer" applied.

🎨 Styles

The component now uses inline styles for the active state instead of a class. You can customize these styles using the activeStyle prop.

Default Active Styles

  • Font Weight: bold
  • Color: Inherits the browser's default color (if no color is specified in activeStyle).

You can override these by providing custom styles through the activeStyle prop.

Custom Active Styles

vue
<i18n-link to="/about" :activeStyle="{ fontWeight: 'bold', color: '#42b983' }">About Us</i18n-link>

In this example, the link will be bold and green when active.

🚀 Additional Features

Slot for Custom Content

You can pass custom content inside the link using slots, making the component flexible for different use cases.

vue
<i18n-link to="/about">\n  <span>About Us</span>\n</i18n-link>

Accessibility Enhancements

The component supports aria-label and other accessibility attributes to ensure a more accessible experience.

vue
<i18n-link to="/about" aria-label="Learn more about us">\n  About Us\n</i18n-link>
',33)]))}const c=s(n,[["render",l]]);export{E as __pageData,c as default}; diff --git a/assets/components_i18n-switcher.md.CZU12ZBI.js b/assets/components_i18n-switcher.md.CZU12ZBI.js new file mode 100644 index 0000000..f5506da --- /dev/null +++ b/assets/components_i18n-switcher.md.CZU12ZBI.js @@ -0,0 +1 @@ +import{_ as i,c as t,a2 as a,o as l}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"🌍 Component","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"components/i18n-switcher.md","filePath":"components/i18n-switcher.md","lastUpdated":1724679268000}'),e={name:"components/i18n-switcher.md"};function n(h,s,k,p,o,r){return l(),t("div",null,s[0]||(s[0]=[a('

Here’s the updated documentation for the <i18n-switcher> component, reflecting the transition to using inline styles with support for dynamic customization through props:


🌍 <i18n-switcher> Component

The <i18n-switcher> component in Nuxt I18n Micro provides a user-friendly dropdown interface for switching between different locales in your application. This component is highly customizable, allowing seamless integration with your application's design and layout.

⚙️ Props

customLabels

  • Type: Record<string, string>
  • Default: {}
  • Description: Allows you to define custom labels for each locale, which will be displayed instead of the locale codes.
  • Example:
    vue
    <i18n-switcher :customLabels="{ en: 'English', fr: 'Français' }"></i18n-switcher>

customWrapperStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to override the default styles applied to the wrapper <div> that contains the locale switcher.
  • Example:
    vue
    <i18n-switcher :customWrapperStyle="{ backgroundColor: '#f8f9fa', padding: '10px' }"></i18n-switcher>

customButtonStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to customize the styles applied to the button element that toggles the dropdown menu.
  • Example:
    vue
    <i18n-switcher :customButtonStyle="{ backgroundColor: '#007bff', color: '#fff', borderRadius: '4px' }"></i18n-switcher>

customDropdownStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Sets the custom styles for the <ul> element that contains the list of locales.
  • Example:
    vue
    <i18n-switcher :customDropdownStyle="{ border: '1px solid #007bff', boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }"></i18n-switcher>

customItemStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Applies custom styles to each <li> element representing a locale option.
  • Example:
    vue
    <i18n-switcher :customItemStyle="{ margin: '5px 0', padding: '5px' }"></i18n-switcher>

customLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to customize the styles applied to the <NuxtLink> elements used to switch between locales.
  • Example:
    vue
    <i18n-switcher :customLinkStyle="{ padding: '8px 16px', color: '#333', textDecoration: 'none' }"></i18n-switcher>

customActiveLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Sets the custom styles for the currently active locale, usually to highlight or indicate the selected option.
  • Example:
    vue
    <i18n-switcher :customActiveLinkStyle="{ color: 'green', fontWeight: 'bold', backgroundColor: '#f0f0f0' }"></i18n-switcher>

customDisabledLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Applies custom styles to disable the link for the current locale, preventing users from selecting it.
  • Example:
    vue
    <i18n-switcher :customDisabledLinkStyle="{ color: 'gray', cursor: 'not-allowed' }"></i18n-switcher>

customIconStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Defines custom styles for the icon that indicates the dropdown state, such as rotating the icon when the dropdown is opened or closed.
  • Example:
    vue
    <i18n-switcher :customIconStyle="{ fontSize: '20px', color: '#007bff' }"></i18n-switcher>

🛠️ Example Usages

Basic Usage

vue
<template>\n  <i18n-switcher />\n</template>

This renders a locale switcher with default styling and behavior.

Custom Labels and Inline Styles

vue
<template>\n  <i18n-switcher\n    :customLabels="{ en: 'English', fr: 'Français' }"\n    :customWrapperStyle="{ backgroundColor: '#f8f9fa', padding: '10px' }"\n    :customButtonStyle="{ backgroundColor: '#007bff', color: '#fff', borderRadius: '4px' }"\n    :customDropdownStyle="{ border: '1px solid #007bff', boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }"\n    :customItemStyle="{ margin: '5px 0', padding: '5px' }"\n    :customLinkStyle="{ padding: '8px 16px', color: '#333', textDecoration: 'none' }"\n    :customActiveLinkStyle="{ color: 'green', fontWeight: 'bold', backgroundColor: '#f0f0f0' }"\n    :customDisabledLinkStyle="{ color: 'gray', cursor: 'not-allowed' }"\n    :customIconStyle="{ fontSize: '20px', color: '#007bff' }"\n  />\n</template>

This example demonstrates a fully customized locale switcher with custom labels and inline styles.

🎨 Styles Overview

The <i18n-switcher> component comes with basic styles defined using inline styles that can easily be overridden by passing custom styles via props. Here’s a brief overview of the default styling:

  • Wrapper: Controls the positioning of the dropdown.
  • Button: Styles the dropdown toggle button.
  • Dropdown: Styles the dropdown list.
  • Items: Styles each item in the list.
  • Links: Styles the links inside each item.
  • Icon: Styles the dropdown indicator icon.

You can customize these styles by passing custom styles through the respective props, ensuring that the locale switcher integrates seamlessly into your application's UI.

',34)]))}const g=i(e,[["render",n]]);export{d as __pageData,g as default}; diff --git a/assets/components_i18n-switcher.md.CZU12ZBI.lean.js b/assets/components_i18n-switcher.md.CZU12ZBI.lean.js new file mode 100644 index 0000000..f5506da --- /dev/null +++ b/assets/components_i18n-switcher.md.CZU12ZBI.lean.js @@ -0,0 +1 @@ +import{_ as i,c as t,a2 as a,o as l}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"🌍 Component","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"components/i18n-switcher.md","filePath":"components/i18n-switcher.md","lastUpdated":1724679268000}'),e={name:"components/i18n-switcher.md"};function n(h,s,k,p,o,r){return l(),t("div",null,s[0]||(s[0]=[a('

Here’s the updated documentation for the <i18n-switcher> component, reflecting the transition to using inline styles with support for dynamic customization through props:


🌍 <i18n-switcher> Component

The <i18n-switcher> component in Nuxt I18n Micro provides a user-friendly dropdown interface for switching between different locales in your application. This component is highly customizable, allowing seamless integration with your application's design and layout.

⚙️ Props

customLabels

  • Type: Record<string, string>
  • Default: {}
  • Description: Allows you to define custom labels for each locale, which will be displayed instead of the locale codes.
  • Example:
    vue
    <i18n-switcher :customLabels="{ en: 'English', fr: 'Français' }"></i18n-switcher>

customWrapperStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to override the default styles applied to the wrapper <div> that contains the locale switcher.
  • Example:
    vue
    <i18n-switcher :customWrapperStyle="{ backgroundColor: '#f8f9fa', padding: '10px' }"></i18n-switcher>

customButtonStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to customize the styles applied to the button element that toggles the dropdown menu.
  • Example:
    vue
    <i18n-switcher :customButtonStyle="{ backgroundColor: '#007bff', color: '#fff', borderRadius: '4px' }"></i18n-switcher>

customDropdownStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Sets the custom styles for the <ul> element that contains the list of locales.
  • Example:
    vue
    <i18n-switcher :customDropdownStyle="{ border: '1px solid #007bff', boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }"></i18n-switcher>

customItemStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Applies custom styles to each <li> element representing a locale option.
  • Example:
    vue
    <i18n-switcher :customItemStyle="{ margin: '5px 0', padding: '5px' }"></i18n-switcher>

customLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to customize the styles applied to the <NuxtLink> elements used to switch between locales.
  • Example:
    vue
    <i18n-switcher :customLinkStyle="{ padding: '8px 16px', color: '#333', textDecoration: 'none' }"></i18n-switcher>

customActiveLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Sets the custom styles for the currently active locale, usually to highlight or indicate the selected option.
  • Example:
    vue
    <i18n-switcher :customActiveLinkStyle="{ color: 'green', fontWeight: 'bold', backgroundColor: '#f0f0f0' }"></i18n-switcher>

customDisabledLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Applies custom styles to disable the link for the current locale, preventing users from selecting it.
  • Example:
    vue
    <i18n-switcher :customDisabledLinkStyle="{ color: 'gray', cursor: 'not-allowed' }"></i18n-switcher>

customIconStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Defines custom styles for the icon that indicates the dropdown state, such as rotating the icon when the dropdown is opened or closed.
  • Example:
    vue
    <i18n-switcher :customIconStyle="{ fontSize: '20px', color: '#007bff' }"></i18n-switcher>

🛠️ Example Usages

Basic Usage

vue
<template>\n  <i18n-switcher />\n</template>

This renders a locale switcher with default styling and behavior.

Custom Labels and Inline Styles

vue
<template>\n  <i18n-switcher\n    :customLabels="{ en: 'English', fr: 'Français' }"\n    :customWrapperStyle="{ backgroundColor: '#f8f9fa', padding: '10px' }"\n    :customButtonStyle="{ backgroundColor: '#007bff', color: '#fff', borderRadius: '4px' }"\n    :customDropdownStyle="{ border: '1px solid #007bff', boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }"\n    :customItemStyle="{ margin: '5px 0', padding: '5px' }"\n    :customLinkStyle="{ padding: '8px 16px', color: '#333', textDecoration: 'none' }"\n    :customActiveLinkStyle="{ color: 'green', fontWeight: 'bold', backgroundColor: '#f0f0f0' }"\n    :customDisabledLinkStyle="{ color: 'gray', cursor: 'not-allowed' }"\n    :customIconStyle="{ fontSize: '20px', color: '#007bff' }"\n  />\n</template>

This example demonstrates a fully customized locale switcher with custom labels and inline styles.

🎨 Styles Overview

The <i18n-switcher> component comes with basic styles defined using inline styles that can easily be overridden by passing custom styles via props. Here’s a brief overview of the default styling:

  • Wrapper: Controls the positioning of the dropdown.
  • Button: Styles the dropdown toggle button.
  • Dropdown: Styles the dropdown list.
  • Items: Styles each item in the list.
  • Links: Styles the links inside each item.
  • Icon: Styles the dropdown indicator icon.

You can customize these styles by passing custom styles through the respective props, ensuring that the locale switcher integrates seamlessly into your application's UI.

',34)]))}const g=i(e,[["render",n]]);export{d as __pageData,g as default}; diff --git a/assets/components_i18n-t.md.Dn3NUPHA.js b/assets/components_i18n-t.md.Dn3NUPHA.js new file mode 100644 index 0000000..9f64e8d --- /dev/null +++ b/assets/components_i18n-t.md.Dn3NUPHA.js @@ -0,0 +1,31 @@ +import{_ as i,c as a,a2 as t,o as n}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"🌍 Component","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"components/i18n-t.md","filePath":"components/i18n-t.md","lastUpdated":1726488664000}'),l={name:"components/i18n-t.md"};function e(h,s,p,k,o,r){return n(),a("div",null,s[0]||(s[0]=[t(`

🌍 <i18n-t> Component

The <i18n-t> component in Nuxt I18n Micro is a flexible translation component that supports dynamic content insertion via slots. It allows you to interpolate translations with custom Vue components or HTML content, enabling advanced localization scenarios.

⚙️ Props

keypath

  • Type: string
  • Required: Yes
  • Description: Defines the key path to the translation string in your localization files.
  • Example:
    vue
    <i18n-t keypath="feedback.text" />

plural

  • Type: number | string
  • Optional: Yes
  • Description: Specifies a number for pluralization rules.
  • Example:
    vue
    <i18n-t keypath="items" :plural="itemCount" />

tag

  • Type: string
  • Optional: Yes
  • Default: 'span'
  • Description: Specifies the HTML tag to wrap the translated content.
  • Example:
    vue
    <i18n-t keypath="feedback.text" tag="div" />

params

  • Type: Record<string, string | number | boolean>
  • Optional: Yes
  • Description: Provides parameters for interpolating dynamic values in the translation.
  • Example:
    vue
    <i18n-t keypath="user.greeting" :params="{ name: userName }" />

defaultValue

  • Type: string
  • Optional: Yes
  • Description: The default value to use if the translation key is not found.
  • Example:
    vue
    <i18n-t keypath="nonExistentKey" defaultValue="Fallback text"></i18n-t>

html

  • Type: boolean
  • Optional: Yes
  • Default: false
  • Description: Enables the rendering of the translation as raw HTML.
  • Example:
    vue
    <i18n-t keypath="feedback.text" html />

hideIfEmpty

  • Type: boolean
  • Optional: Yes
  • Default: false
  • Description: If true, the component will not render anything if the translation is empty.
  • Example:
    vue
    <i18n-t keypath="optionalMessage" :hideIfEmpty="true"></i18n-t>

customPluralRule

  • Type: (value: string, count: number, locale: string) => string
  • Optional: Yes
  • Description: A function that allows you to define custom pluralization logic. Useful if the default pluralization rules do not fit your specific needs.
  • Example:
    vue
    <i18n-t
    +  keypath="items"
    +  :plural="itemCount"
    +  :customPluralRule="(key, count, locale, getTranslation) => {
    +    const translation = getTranslation(key, {})
    +    if (!translation) {
    +      return null
    +    }
    +    return count === 1 ? 'no items' : \`\${count} \${translation}\`;
    +  }"
    +></i18n-t>

🛠️ Example Usages

Basic Usage

vue
<i18n-t keypath="feedback.text" />

This renders the translation for feedback.text within a <span> tag.

Using Slots for Dynamic Content

The <i18n-t> component supports the use of slots to dynamically insert Vue components or other content into specific parts of the translation.

vue
<i18n-t keypath="feedback.text">
+  <template #link>
+    <nuxt-link :to="{ name: 'index' }">
+      <i18n-t keypath="feedback.link" />
+    </nuxt-link>
+  </template>
+</i18n-t>

In this example, the {link} placeholder in the feedback.text translation string is replaced by the <nuxt-link> component, which itself contains another translation component.

Pluralization

vue
<i18n-t keypath="items.count" :plural="itemCount" />

This automatically applies pluralization rules based on the itemCount value.

🚀 Additional Features

Default Slot

If no specific slot is provided, the translation can be customized via the default slot, which provides the entire translated string:

vue
<i18n-t keypath="welcome.message">
+  <template #default="{ translation }">
+    {{ translation.replace('Nuxt', 'Vue') }}
+  </template>
+</i18n-t>

Conditional Rendering

Render nothing if the translation string is empty by using the hideIfEmpty prop.

vue
<i18n-t keypath="optionalMessage" :hideIfEmpty="true"></i18n-t>

Custom Pluralization Rule

Use a custom function to handle pluralization.

vue
<i18n-t
+  keypath="items"
+  :plural="itemCount"
+  :customPluralRule="(key, value, count, locale) => {
+    return count === 1 ? 'One item' : \`\${count} items\`;
+  }}"
+></i18n-t>

Advanced Example with Slots

Utilize slots to customize how the translation content is rendered.

vue
<i18n-t keypath="welcomeMessage">
+  <template #default="{ translation }">
+    <strong>{{ translation }}</strong>
+  </template>
+</i18n-t>
`,43)]))}const g=i(l,[["render",e]]);export{E as __pageData,g as default}; diff --git a/assets/components_i18n-t.md.Dn3NUPHA.lean.js b/assets/components_i18n-t.md.Dn3NUPHA.lean.js new file mode 100644 index 0000000..9f64e8d --- /dev/null +++ b/assets/components_i18n-t.md.Dn3NUPHA.lean.js @@ -0,0 +1,31 @@ +import{_ as i,c as a,a2 as t,o as n}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"🌍 Component","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"components/i18n-t.md","filePath":"components/i18n-t.md","lastUpdated":1726488664000}'),l={name:"components/i18n-t.md"};function e(h,s,p,k,o,r){return n(),a("div",null,s[0]||(s[0]=[t(`

🌍 <i18n-t> Component

The <i18n-t> component in Nuxt I18n Micro is a flexible translation component that supports dynamic content insertion via slots. It allows you to interpolate translations with custom Vue components or HTML content, enabling advanced localization scenarios.

⚙️ Props

keypath

  • Type: string
  • Required: Yes
  • Description: Defines the key path to the translation string in your localization files.
  • Example:
    vue
    <i18n-t keypath="feedback.text" />

plural

  • Type: number | string
  • Optional: Yes
  • Description: Specifies a number for pluralization rules.
  • Example:
    vue
    <i18n-t keypath="items" :plural="itemCount" />

tag

  • Type: string
  • Optional: Yes
  • Default: 'span'
  • Description: Specifies the HTML tag to wrap the translated content.
  • Example:
    vue
    <i18n-t keypath="feedback.text" tag="div" />

params

  • Type: Record<string, string | number | boolean>
  • Optional: Yes
  • Description: Provides parameters for interpolating dynamic values in the translation.
  • Example:
    vue
    <i18n-t keypath="user.greeting" :params="{ name: userName }" />

defaultValue

  • Type: string
  • Optional: Yes
  • Description: The default value to use if the translation key is not found.
  • Example:
    vue
    <i18n-t keypath="nonExistentKey" defaultValue="Fallback text"></i18n-t>

html

  • Type: boolean
  • Optional: Yes
  • Default: false
  • Description: Enables the rendering of the translation as raw HTML.
  • Example:
    vue
    <i18n-t keypath="feedback.text" html />

hideIfEmpty

  • Type: boolean
  • Optional: Yes
  • Default: false
  • Description: If true, the component will not render anything if the translation is empty.
  • Example:
    vue
    <i18n-t keypath="optionalMessage" :hideIfEmpty="true"></i18n-t>

customPluralRule

  • Type: (value: string, count: number, locale: string) => string
  • Optional: Yes
  • Description: A function that allows you to define custom pluralization logic. Useful if the default pluralization rules do not fit your specific needs.
  • Example:
    vue
    <i18n-t
    +  keypath="items"
    +  :plural="itemCount"
    +  :customPluralRule="(key, count, locale, getTranslation) => {
    +    const translation = getTranslation(key, {})
    +    if (!translation) {
    +      return null
    +    }
    +    return count === 1 ? 'no items' : \`\${count} \${translation}\`;
    +  }"
    +></i18n-t>

🛠️ Example Usages

Basic Usage

vue
<i18n-t keypath="feedback.text" />

This renders the translation for feedback.text within a <span> tag.

Using Slots for Dynamic Content

The <i18n-t> component supports the use of slots to dynamically insert Vue components or other content into specific parts of the translation.

vue
<i18n-t keypath="feedback.text">
+  <template #link>
+    <nuxt-link :to="{ name: 'index' }">
+      <i18n-t keypath="feedback.link" />
+    </nuxt-link>
+  </template>
+</i18n-t>

In this example, the {link} placeholder in the feedback.text translation string is replaced by the <nuxt-link> component, which itself contains another translation component.

Pluralization

vue
<i18n-t keypath="items.count" :plural="itemCount" />

This automatically applies pluralization rules based on the itemCount value.

🚀 Additional Features

Default Slot

If no specific slot is provided, the translation can be customized via the default slot, which provides the entire translated string:

vue
<i18n-t keypath="welcome.message">
+  <template #default="{ translation }">
+    {{ translation.replace('Nuxt', 'Vue') }}
+  </template>
+</i18n-t>

Conditional Rendering

Render nothing if the translation string is empty by using the hideIfEmpty prop.

vue
<i18n-t keypath="optionalMessage" :hideIfEmpty="true"></i18n-t>

Custom Pluralization Rule

Use a custom function to handle pluralization.

vue
<i18n-t
+  keypath="items"
+  :plural="itemCount"
+  :customPluralRule="(key, value, count, locale) => {
+    return count === 1 ? 'One item' : \`\${count} items\`;
+  }}"
+></i18n-t>

Advanced Example with Slots

Utilize slots to customize how the translation content is rendered.

vue
<i18n-t keypath="welcomeMessage">
+  <template #default="{ translation }">
+    <strong>{{ translation }}</strong>
+  </template>
+</i18n-t>
`,43)]))}const g=i(l,[["render",e]]);export{E as __pageData,g as default}; diff --git a/assets/composables_useI18n.md.7DLszJoL.js b/assets/composables_useI18n.md.7DLszJoL.js new file mode 100644 index 0000000..ae1b88c --- /dev/null +++ b/assets/composables_useI18n.md.7DLszJoL.js @@ -0,0 +1 @@ +import{_ as i,c as a,a2 as t,o as e}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🛠️ useI18n Composable","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"composables/useI18n.md","filePath":"composables/useI18n.md","lastUpdated":1729326320000}'),n={name:"composables/useI18n.md"};function l(h,s,p,k,o,r){return e(),a("div",null,s[0]||(s[0]=[t('

🛠️ useI18n Composable

The useI18n composable in Nuxt I18n Micro is designed to provide an easy and efficient way to access internationalization functionalities within your Nuxt application. It offers a variety of methods to handle localization, translation, and route management based on the current locale.

All methods can be accessed both with and without the $ prefix for convenience.

⚙️ Return Values

The useI18n composable returns an object containing several key methods and properties for managing internationalization:

$getLocale

  • Type: () => string
  • Description: Returns the current locale of the application.
  • Example:
    js
    const { $getLocale } = useI18n()\nconst locale = $getLocale()\nconsole.log(locale) // e.g., 'en'

🌍 $getLocaleName

Version introduced: v1.28.0

  • Type: () => string | null
  • Description: Returns the current locale name from displayName config.
  • Example:
typescript
const locale = $getLocaleName()\n// Output: 'English'

$getLocales

  • Type: () => Locale[]
  • Description: Returns an array of all available locales in the application.
  • Example:
    js
    const { $getLocales } = useI18n()\nconst locales = $getLocales()\nconsole.log(locales) // e.g., [{ code: 'en', iso: 'en-US' }, { code: 'fr', iso: 'fr-FR' }]

$t

  • Type: <T extends Record<string, string | number | boolean>>(key: string, params?: T, defaultValue?: string) => string | number | boolean | Translations | PluralTranslations | unknown[] | unknown | null
  • Description: Translates a given key to the corresponding localized string, optionally replacing placeholders with provided parameters and falling back to a default value if the key is not found.
  • Example:
    js
    const { $t } = useI18n()\nconst greeting = $t('hello', { name: 'John' }, 'Hello!')\nconsole.log(greeting) // e.g., 'Hello, John'

$tc

  • Type: (key: string, count: number, defaultValue?: string) => string
  • Description: Translates a given key with pluralization based on the provided count, optionally falling back to a default value if the key is not found.
  • Example:
    js
    const { $tc } = useI18n()\nconst message = $tc('apples', 3, '3 apples')\nconsole.log(message) // e.g., '3 apples'

$has

  • Type: (key: string) => boolean
  • Description: Checks if a translation key exists for the current locale.
  • Example:
    js
    const { $has } = useI18n()\nconst exists = $has('hello')\nconsole.log(exists) // e.g., true

$mergeTranslations

  • Type: (newTranslations: Translations) => void
  • Description: Merges additional translations into the existing ones for the current locale.
  • Example:
    js
    const { $mergeTranslations } = useI18n()\n$mergeTranslations({\n  hello: 'Hello World',\n})

$switchLocale

  • Type: (locale: string) => void
  • Description: Switches the application's locale to the specified locale.
  • Example:
    js
    const { $switchLocale } = useI18n()\n$switchLocale('fr')

$localeRoute

  • Type: (to: RouteLocationRaw, locale?: string) => RouteLocationRaw
  • Description: Generates a localized route based on the specified route and optionally the specified locale.
  • Example:
    js
    const { $localeRoute } = useI18n()\nconst route = $localeRoute('/about', 'fr')

$loadPageTranslations

  • Type: (locale: string, routeName: string) => Promise<void>
  • Description: Loads translations for the specified page and locale, enabling lazy-loading of translations.
  • Example:
    js
    const { $loadPageTranslations } = useI18n()\nawait $loadPageTranslations('fr', 'home')

🛠️ Example Usages

Basic Locale Retrieval

Retrieve the current locale of the application.

js
const { $getLocale } = useI18n()\nconst locale = $getLocale()

Translation with Parameters

Translate a string with dynamic parameters, with a fallback default value.

js
const { $t } = useI18n()\nconst welcomeMessage = $t('welcome', { name: 'Jane' }, 'Welcome!')

Switching Locales

Switch the application to a different locale.

js
const { $switchLocale } = useI18n()\n$switchLocale('de')

Generating a Localized Route

Generate a route localized to the current or specified locale.

js
const { $localeRoute } = useI18n()\nconst route = $localeRoute('/about', 'fr')

Loading Page-Specific Translations

Lazy-load translations for a specific page and locale.

js
const { $loadPageTranslations } = useI18n()\nawait $loadPageTranslations('de', 'dashboard')
',43)]))}const c=i(n,[["render",l]]);export{g as __pageData,c as default}; diff --git a/assets/composables_useI18n.md.7DLszJoL.lean.js b/assets/composables_useI18n.md.7DLszJoL.lean.js new file mode 100644 index 0000000..ae1b88c --- /dev/null +++ b/assets/composables_useI18n.md.7DLszJoL.lean.js @@ -0,0 +1 @@ +import{_ as i,c as a,a2 as t,o as e}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🛠️ useI18n Composable","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"composables/useI18n.md","filePath":"composables/useI18n.md","lastUpdated":1729326320000}'),n={name:"composables/useI18n.md"};function l(h,s,p,k,o,r){return e(),a("div",null,s[0]||(s[0]=[t('

🛠️ useI18n Composable

The useI18n composable in Nuxt I18n Micro is designed to provide an easy and efficient way to access internationalization functionalities within your Nuxt application. It offers a variety of methods to handle localization, translation, and route management based on the current locale.

All methods can be accessed both with and without the $ prefix for convenience.

⚙️ Return Values

The useI18n composable returns an object containing several key methods and properties for managing internationalization:

$getLocale

  • Type: () => string
  • Description: Returns the current locale of the application.
  • Example:
    js
    const { $getLocale } = useI18n()\nconst locale = $getLocale()\nconsole.log(locale) // e.g., 'en'

🌍 $getLocaleName

Version introduced: v1.28.0

  • Type: () => string | null
  • Description: Returns the current locale name from displayName config.
  • Example:
typescript
const locale = $getLocaleName()\n// Output: 'English'

$getLocales

  • Type: () => Locale[]
  • Description: Returns an array of all available locales in the application.
  • Example:
    js
    const { $getLocales } = useI18n()\nconst locales = $getLocales()\nconsole.log(locales) // e.g., [{ code: 'en', iso: 'en-US' }, { code: 'fr', iso: 'fr-FR' }]

$t

  • Type: <T extends Record<string, string | number | boolean>>(key: string, params?: T, defaultValue?: string) => string | number | boolean | Translations | PluralTranslations | unknown[] | unknown | null
  • Description: Translates a given key to the corresponding localized string, optionally replacing placeholders with provided parameters and falling back to a default value if the key is not found.
  • Example:
    js
    const { $t } = useI18n()\nconst greeting = $t('hello', { name: 'John' }, 'Hello!')\nconsole.log(greeting) // e.g., 'Hello, John'

$tc

  • Type: (key: string, count: number, defaultValue?: string) => string
  • Description: Translates a given key with pluralization based on the provided count, optionally falling back to a default value if the key is not found.
  • Example:
    js
    const { $tc } = useI18n()\nconst message = $tc('apples', 3, '3 apples')\nconsole.log(message) // e.g., '3 apples'

$has

  • Type: (key: string) => boolean
  • Description: Checks if a translation key exists for the current locale.
  • Example:
    js
    const { $has } = useI18n()\nconst exists = $has('hello')\nconsole.log(exists) // e.g., true

$mergeTranslations

  • Type: (newTranslations: Translations) => void
  • Description: Merges additional translations into the existing ones for the current locale.
  • Example:
    js
    const { $mergeTranslations } = useI18n()\n$mergeTranslations({\n  hello: 'Hello World',\n})

$switchLocale

  • Type: (locale: string) => void
  • Description: Switches the application's locale to the specified locale.
  • Example:
    js
    const { $switchLocale } = useI18n()\n$switchLocale('fr')

$localeRoute

  • Type: (to: RouteLocationRaw, locale?: string) => RouteLocationRaw
  • Description: Generates a localized route based on the specified route and optionally the specified locale.
  • Example:
    js
    const { $localeRoute } = useI18n()\nconst route = $localeRoute('/about', 'fr')

$loadPageTranslations

  • Type: (locale: string, routeName: string) => Promise<void>
  • Description: Loads translations for the specified page and locale, enabling lazy-loading of translations.
  • Example:
    js
    const { $loadPageTranslations } = useI18n()\nawait $loadPageTranslations('fr', 'home')

🛠️ Example Usages

Basic Locale Retrieval

Retrieve the current locale of the application.

js
const { $getLocale } = useI18n()\nconst locale = $getLocale()

Translation with Parameters

Translate a string with dynamic parameters, with a fallback default value.

js
const { $t } = useI18n()\nconst welcomeMessage = $t('welcome', { name: 'Jane' }, 'Welcome!')

Switching Locales

Switch the application to a different locale.

js
const { $switchLocale } = useI18n()\n$switchLocale('de')

Generating a Localized Route

Generate a route localized to the current or specified locale.

js
const { $localeRoute } = useI18n()\nconst route = $localeRoute('/about', 'fr')

Loading Page-Specific Translations

Lazy-load translations for a specific page and locale.

js
const { $loadPageTranslations } = useI18n()\nawait $loadPageTranslations('de', 'dashboard')
',43)]))}const c=i(n,[["render",l]]);export{g as __pageData,c as default}; diff --git a/assets/composables_useLocaleHead.md.BS009Eh1.js b/assets/composables_useLocaleHead.md.BS009Eh1.js new file mode 100644 index 0000000..310fea1 --- /dev/null +++ b/assets/composables_useLocaleHead.md.BS009Eh1.js @@ -0,0 +1,21 @@ +import{_ as a,c as e,a2 as i,o as t}from"./chunks/framework.CBrKbnPu.js";const k=JSON.parse('{"title":"🌍 useLocaleHead Composable","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"composables/useLocaleHead.md","filePath":"composables/useLocaleHead.md","lastUpdated":1724679268000}'),n={name:"composables/useLocaleHead.md"};function l(o,s,d,h,r,p){return t(),e("div",null,s[0]||(s[0]=[i(`

🌍 useLocaleHead Composable

The useLocaleHead composable is a utility in Nuxt I18n Micro that helps you manage SEO attributes and HTML meta tags for localized routes. It dynamically generates attributes for the lang and dir of the HTML document and creates meta and link tags to improve the SEO of your localized content.

⚙️ Options

The useLocaleHead composable accepts an options object to customize its behavior:

addDirAttribute

  • Type: boolean
  • Default: true
  • Description: If true, adds the dir attribute to the HTML document based on the current locale's direction (ltr or rtl).
  • Example:
    js
    const head = useLocaleHead({ addDirAttribute: false })

identifierAttribute

  • Type: string
  • Default: 'id'
  • Description: Specifies the attribute used to identify the generated meta and link tags. This is useful for differentiating tags when inspecting the document head.
  • Example:
    js
    const head = useLocaleHead({ identifierAttribute: 'data-i18n' })

addSeoAttributes

  • Type: boolean
  • Default: true
  • Description: If true, includes SEO-related meta and link tags, such as og:locale, og:url, and hreflang attributes for alternate languages.
  • Example:
    js
    const head = useLocaleHead({ addSeoAttributes: false })

baseUrl

  • Type: string
  • Default: '/'
  • Description: The base URL of your application, used to generate canonical and alternate URLs for SEO purposes.
  • Example:
    js
    const head = useLocaleHead({ baseUrl: 'https://example.com' })

🛠️ Return Values

The useLocaleHead composable returns an object with htmlAttrs, meta, and link properties, which can be directly used in the <head> section of your Nuxt application.

htmlAttrs

  • Type: Record<string, string>
  • Description: Contains attributes to be added to the <html> tag, such as lang and dir.
  • Example:
    js
    const { htmlAttrs } = useLocaleHead()
    +console.log(htmlAttrs)
    +// Output: { lang: 'en-US', dir: 'ltr' }

meta

  • Type: Array<Record<string, string>>
  • Description: Contains meta tags for SEO, including Open Graph locale tags and alternate locales.
  • Example:
    js
    const { meta } = useLocaleHead()
    +console.log(meta)
    +// Output: [{ id: 'i18n-og', property: 'og:locale', content: 'en-US' }, ...]
  • Type: Array<Record<string, string>>
  • Description: Contains link tags for canonical URLs and alternate language versions of the page.
  • Example:
    js
    const { link } = useLocaleHead()
    +console.log(link)
    +// Output: [{ id: 'i18n-can', rel: 'canonical', href: 'https://example.com/about' }, ...]

🛠️ Example Usages

Basic Usage

Generate locale-specific head attributes with default options.

js
const head = useLocaleHead()

Customize Identifier Attribute

Use a custom identifier attribute for the generated tags.

js
const head = useLocaleHead({ identifierAttribute: 'data-i18n' })

Disable SEO Attributes

Generate head attributes without adding SEO-related meta and link tags.

js
const head = useLocaleHead({ addSeoAttributes: false })

Specify a Base URL

Set a custom base URL for canonical and alternate URLs.

js
const head = useLocaleHead({ baseUrl: 'https://mywebsite.com' })

🚀 Additional Features

When addSeoAttributes is enabled, the composable automatically generates the following tags:

  • og:locale for the current locale.
  • og:url for the canonical URL of the page.
  • og:locale:alternate for alternate language versions.
  • rel="canonical" and rel="alternate" links for SEO optimization.

Dynamic Locale and Direction

The composable dynamically determines the lang and dir attributes based on the current route's locale, ensuring that your HTML document is correctly configured for international users.

Handling Localized Routes

If your routes are prefixed with locale codes (e.g., /en/about), the composable intelligently adjusts the full path for generating URLs, ensuring that SEO attributes are accurate and relevant.

This composable simplifies the process of optimizing your Nuxt application for international audiences, ensuring that your site is well-prepared for global search engines and users.

🛠️ Example Usage

The following example demonstrates how to use the useLocaleHead composable within a Vue component with default settings:

vue
<script setup>
+const head = useLocaleHead({
+  addDirAttribute: true,
+  identifierAttribute: 'id',
+  addSeoAttributes: true,
+})
+
+useHead(head)
+</script>
+
+<template>
+  <div>
+    
+  </div>
+</template>

Explanation of the Code

  • useLocaleHead Composable: This composable is called in the <script setup> section and returns an object containing htmlAttrs, meta, and link.

  • <html> Tag: The lang and dir attributes for the HTML document are dynamically determined based on the current locale and are applied to the <html> tag.

  • <head> Section:

    • Meta Tags: SEO-related meta tags are generated, including og:locale, og:url, and rel="canonical" and rel="alternate" tags to specify alternate language versions of the page.
    • Link Tags: Canonical links and links to alternate language versions are included.
  • <body> Section: The main content of the page is displayed here. In this example, a simple header and paragraph are used.

📝 Notes

  1. Attributes: The attributes used (lang, dir, rel, href, hreflang, property, content) are extracted from the object returned by useLocaleHead.

  2. SEO Tags Generation: If the addSeoAttributes option is set to true, the composable automatically generates SEO tags for the current locale.

  3. Base URL: You can set your custom base URL using the baseUrl option to correctly generate canonical and alternate links.

This example demonstrates how easy it is to integrate useLocaleHead into your application's components to ensure correct SEO attributes and improve the search engine indexing of localized pages.

`,50)]))}const g=a(n,[["render",l]]);export{k as __pageData,g as default}; diff --git a/assets/composables_useLocaleHead.md.BS009Eh1.lean.js b/assets/composables_useLocaleHead.md.BS009Eh1.lean.js new file mode 100644 index 0000000..310fea1 --- /dev/null +++ b/assets/composables_useLocaleHead.md.BS009Eh1.lean.js @@ -0,0 +1,21 @@ +import{_ as a,c as e,a2 as i,o as t}from"./chunks/framework.CBrKbnPu.js";const k=JSON.parse('{"title":"🌍 useLocaleHead Composable","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"composables/useLocaleHead.md","filePath":"composables/useLocaleHead.md","lastUpdated":1724679268000}'),n={name:"composables/useLocaleHead.md"};function l(o,s,d,h,r,p){return t(),e("div",null,s[0]||(s[0]=[i(`

🌍 useLocaleHead Composable

The useLocaleHead composable is a utility in Nuxt I18n Micro that helps you manage SEO attributes and HTML meta tags for localized routes. It dynamically generates attributes for the lang and dir of the HTML document and creates meta and link tags to improve the SEO of your localized content.

⚙️ Options

The useLocaleHead composable accepts an options object to customize its behavior:

addDirAttribute

  • Type: boolean
  • Default: true
  • Description: If true, adds the dir attribute to the HTML document based on the current locale's direction (ltr or rtl).
  • Example:
    js
    const head = useLocaleHead({ addDirAttribute: false })

identifierAttribute

  • Type: string
  • Default: 'id'
  • Description: Specifies the attribute used to identify the generated meta and link tags. This is useful for differentiating tags when inspecting the document head.
  • Example:
    js
    const head = useLocaleHead({ identifierAttribute: 'data-i18n' })

addSeoAttributes

  • Type: boolean
  • Default: true
  • Description: If true, includes SEO-related meta and link tags, such as og:locale, og:url, and hreflang attributes for alternate languages.
  • Example:
    js
    const head = useLocaleHead({ addSeoAttributes: false })

baseUrl

  • Type: string
  • Default: '/'
  • Description: The base URL of your application, used to generate canonical and alternate URLs for SEO purposes.
  • Example:
    js
    const head = useLocaleHead({ baseUrl: 'https://example.com' })

🛠️ Return Values

The useLocaleHead composable returns an object with htmlAttrs, meta, and link properties, which can be directly used in the <head> section of your Nuxt application.

htmlAttrs

  • Type: Record<string, string>
  • Description: Contains attributes to be added to the <html> tag, such as lang and dir.
  • Example:
    js
    const { htmlAttrs } = useLocaleHead()
    +console.log(htmlAttrs)
    +// Output: { lang: 'en-US', dir: 'ltr' }

meta

  • Type: Array<Record<string, string>>
  • Description: Contains meta tags for SEO, including Open Graph locale tags and alternate locales.
  • Example:
    js
    const { meta } = useLocaleHead()
    +console.log(meta)
    +// Output: [{ id: 'i18n-og', property: 'og:locale', content: 'en-US' }, ...]
  • Type: Array<Record<string, string>>
  • Description: Contains link tags for canonical URLs and alternate language versions of the page.
  • Example:
    js
    const { link } = useLocaleHead()
    +console.log(link)
    +// Output: [{ id: 'i18n-can', rel: 'canonical', href: 'https://example.com/about' }, ...]

🛠️ Example Usages

Basic Usage

Generate locale-specific head attributes with default options.

js
const head = useLocaleHead()

Customize Identifier Attribute

Use a custom identifier attribute for the generated tags.

js
const head = useLocaleHead({ identifierAttribute: 'data-i18n' })

Disable SEO Attributes

Generate head attributes without adding SEO-related meta and link tags.

js
const head = useLocaleHead({ addSeoAttributes: false })

Specify a Base URL

Set a custom base URL for canonical and alternate URLs.

js
const head = useLocaleHead({ baseUrl: 'https://mywebsite.com' })

🚀 Additional Features

When addSeoAttributes is enabled, the composable automatically generates the following tags:

  • og:locale for the current locale.
  • og:url for the canonical URL of the page.
  • og:locale:alternate for alternate language versions.
  • rel="canonical" and rel="alternate" links for SEO optimization.

Dynamic Locale and Direction

The composable dynamically determines the lang and dir attributes based on the current route's locale, ensuring that your HTML document is correctly configured for international users.

Handling Localized Routes

If your routes are prefixed with locale codes (e.g., /en/about), the composable intelligently adjusts the full path for generating URLs, ensuring that SEO attributes are accurate and relevant.

This composable simplifies the process of optimizing your Nuxt application for international audiences, ensuring that your site is well-prepared for global search engines and users.

🛠️ Example Usage

The following example demonstrates how to use the useLocaleHead composable within a Vue component with default settings:

vue
<script setup>
+const head = useLocaleHead({
+  addDirAttribute: true,
+  identifierAttribute: 'id',
+  addSeoAttributes: true,
+})
+
+useHead(head)
+</script>
+
+<template>
+  <div>
+    
+  </div>
+</template>

Explanation of the Code

  • useLocaleHead Composable: This composable is called in the <script setup> section and returns an object containing htmlAttrs, meta, and link.

  • <html> Tag: The lang and dir attributes for the HTML document are dynamically determined based on the current locale and are applied to the <html> tag.

  • <head> Section:

    • Meta Tags: SEO-related meta tags are generated, including og:locale, og:url, and rel="canonical" and rel="alternate" tags to specify alternate language versions of the page.
    • Link Tags: Canonical links and links to alternate language versions are included.
  • <body> Section: The main content of the page is displayed here. In this example, a simple header and paragraph are used.

📝 Notes

  1. Attributes: The attributes used (lang, dir, rel, href, hreflang, property, content) are extracted from the object returned by useLocaleHead.

  2. SEO Tags Generation: If the addSeoAttributes option is set to true, the composable automatically generates SEO tags for the current locale.

  3. Base URL: You can set your custom base URL using the baseUrl option to correctly generate canonical and alternate links.

This example demonstrates how easy it is to integrate useLocaleHead into your application's components to ensure correct SEO attributes and improve the search engine indexing of localized pages.

`,50)]))}const g=a(n,[["render",l]]);export{k as __pageData,g as default}; diff --git a/assets/examples.md.dgk20VMv.js b/assets/examples.md.dgk20VMv.js new file mode 100644 index 0000000..2eef8d9 --- /dev/null +++ b/assets/examples.md.dgk20VMv.js @@ -0,0 +1,246 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"📚 Nuxt I18n Micro Examples and Usage","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"examples.md","filePath":"examples.md","lastUpdated":1729141863000}'),h={name:"examples.md"};function l(k,s,p,e,E,r){return t(),a("div",null,s[0]||(s[0]=[n(`

📚 Nuxt I18n Micro Examples and Usage

This section provides various examples demonstrating how to use Nuxt I18n Micro in your Nuxt.js application. You'll see how to switch locales, use the <i18n-link>, <i18n-switcher>, and <i18n-t> components, and dynamically handle translation keys.

🛠️ Basic Setup

Here's a basic setup to get started with Nuxt I18n Micro:

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: false, displayName: 'English' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr', disabled: false, displayName: 'Français' },
+      { code: 'de', iso: 'de-DE', dir: 'ltr', disabled: false, displayName: 'Deutsch' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

🌍 Locale Switching

Switching Locales Programmatically

This example demonstrates how to switch locales programmatically using buttons:

vue
<template>
+  <div>
+    <p>Current Locale: {{ $getLocale() }}</p>
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale.code"
+        :disabled="locale.code === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ $t(locale.code) }}
+      </button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>

Example JSON for Locale Switching

json
{
+  "en": "English",
+  "fr": "Français",
+  "de": "Deutsch"
+}

Using <i18n-switcher> Component

The <i18n-switcher> component provides a dropdown for locale switching with customizable labels:

vue
<template>
+  <div>
+    <i18n-switcher
+      :custom-labels="{ en: 'English', fr: 'Français', de: 'Deutsch' }"
+    />
+  </div>
+</template>

The <i18n-link> component automatically handles locale-specific routing:

vue
<template>
+  <div>
+    <i18n-link to="/about">{{ $t('about') }}</i18n-link>
+    <i18n-link :to="{ name: 'index' }">{{ $t('home') }}</i18n-link>
+  </div>
+</template>
+
+<script setup>
+  import { useNuxtApp } from '#imports'
+
+  const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>
json
{
+  "about": "About Us",
+  "home": "Home"
+}
vue
<template>
+  <div>
+    <i18n-link to="/about" activeClass="current">About Us</i18n-link>
+  </div>
+</template>

The same JSON file can be used as in the previous example for this scenario.

📝 Rendering Dynamic Keys from Translation Files

In some scenarios, you may want to iterate over dynamic keys stored within your translation files and render their values conditionally. The example below demonstrates how to achieve this using Nuxt I18n Micro.

Example: Rendering Dynamic Keys

This example fetches an array of keys from a specific translation path (in this case, dynamic) and iterates over them. Each key is checked for its existence using $has before rendering its value with $t.

vue
<template>
+  <div>
+    <div
+      v-for="key in $t('dynamic')"
+      :key="key"
+    >
+      <p>{{ key }}: <span v-if="$has(key)">{{ $t(key) }}</span></p>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $t, $has } = useNuxtApp()
+</script>

Example Translation File (en.json)

json
{
+  "dynamic": ["key1", "key2", "key3"],
+  "key1": "This is the first key's value",
+  "key2": "This is the second key's value",
+  "key3": "This is the third key's value"
+}

Example: Rendering Dynamic Keys from an Object

In this example, we handle an object stored within your translation file. We fetch and iterate over the keys of the object, dynamically rendering both the key names and their associated values.

vue
<template>
+  <div>
+    <div v-for="(value, key) in $t('dynamicObject')" :key="key">
+      <p>{{ key }}: {{ value }}</p>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $t } = useNuxtApp()
+</script>

Example Translation File (en.json)

json
{
+  "dynamicObject": {
+    "title": "Welcome to our site",
+    "description": "This is a brief description of our services.",
+    "footerNote": "Thank you for visiting!"
+  }
+}

🌟 Using <i18n-t> for Translations with Slots and Interpolation

The <i18n-t> component is useful for rendering translations with dynamic content and HTML tags:

vue
<template>
+  <i18n-t keypath="greeting" tag="h1">
+    <template #default="{ translation }">
+      <strong>{{ translation.replace('page', 'page replace') }}</strong> <i>!!!</i>
+    </template>
+  </i18n-t>
+</template>

Example JSON for <i18n-t>

json
{
+  "greeting": "Welcome to the page"
+}

With Interpolation

vue
<template>
+  <i18n-t keypath="welcome" :params="{ username: 'Alice', unreadCount: 5 }"></i18n-t>
+</template>

Example JSON for Interpolation

json
{
+  "welcome": "Hello {username}, you have {unreadCount} unread messages."
+}

📝 Comprehensive Example with Nested Sections

Here's a complex structure demonstrating multiple translation uses within a single page:

vue
<template>
+  <div>
+    <h1>{{ $t('mainHeader') }}</h1>
+
+    <nav>
+      <ul>
+        <li><a href="#">{{ $t('nav.home') }}</a></li>
+        <li><a href="#">{{ $t('nav.about') }}</a></li>
+        <li><a href="#">{{ $t('nav.services') }}</a></li>
+        <li><a href="#">{{ $t('nav.contact') }}</a></li>
+      </ul>
+    </nav>
+
+    <section>
+      <h2>{{ $t('section1.header') }}</h2>
+      <p>{{ $t('section1.intro') }}</p>
+
+      <div>
+        <h3>{{ $t('section1.subsection1.header') }}</h3>
+        <p>{{ $t('section1.subsection1.content') }}</p>
+      </div>
+
+      <div>
+        <h3>{{ $t('section1.subsection2.header') }}</h3>
+        <ul>
+          <li>{{ $t('section1.subsection2.item1') }}</li>
+          <li>{{ $t('section1.subsection2.item2') }}</li>
+          <li>{{ $t('section1.subsection2.item3') }}</li>
+        </ul>
+      </div>
+    </section>
+
+    <footer>
+      <h4>{{ $t('footer.contact.header') }}</h4>
+      <address>
+        {{ $t('footer.contact.address') }}<br>
+        {{ $t('footer.contact.city') }}<br>
+        {{ $t('footer.contact.phone') }}
+      </address>
+    </footer>
+
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale.code"
+        :disabled="locale.code === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ locale.code }}
+      </button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>

Example JSON for Nested Sections

json
{
+  "mainHeader": "Welcome to Our Services",
+  "nav": {
+    "home": "Home",
+    "about": "About Us",
+    "services": "Services",
+    "contact": "Contact"
+  },
+  "section1": {
+    "header": "Our Expertise",
+    "intro": "We provide a wide range of services to meet your needs.",
+    "subsection1": {
+      "header": "Consulting",
+      "content": "Our team offers expert consulting services in various domains."
+    },
+    "subsection2": {
+      "header": "Development",
+      "item1":
+
+ "Web Development",
+      "item2": "Mobile Apps",
+      "item3": "Custom Software"
+    }
+  },
+  "footer": {
+    "contact": {
+      "header": "Contact Us",
+      "address": "123 Main Street",
+      "city": "Anytown, USA",
+      "phone": "+1 (555) 123-4567"
+    }
+  }
+}

🌟 Using $tc for Pluralization

The $tc function in Nuxt I18n Micro handles pluralization based on the count and locale settings. This is useful for dynamically adjusting messages that involve counts, such as items, notifications, or other entities that can vary in number.

Example: Using $tc for Pluralization

In the following example, we display a message indicating the number of apples using $tc. The translation key handles multiple plural forms based on the count provided.

vue
<template>
+  <div>
+    <!-- Display a pluralized message about the number of apples -->
+    <p>{{ $tc('apples', 0) }}</p>  <!-- Outputs: no apples -->
+    <p>{{ $tc('apples', 1) }}</p>  <!-- Outputs: one apple -->
+    <p>{{ $tc('apples', 10) }}</p> <!-- Outputs: 10 apples -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $tc } = useNuxtApp()
+</script>

Example JSON for Pluralization

Here's how you can define the translation in your JSON file to handle different plural forms:

json
{
+  "apples": "no apples | one apple | {count} apples"
+}

Explanation

  • $tc('apples', 0): Returns the first form, used when the count is zero ("no apples").
  • $tc('apples', 1): Returns the second form, used when the count is one ("one apple").
  • $tc('apples', 10): Returns the third form with the count value, used when the count is two or more ("10 apples").

Additional Example with More Complex Pluralization

If your application needs to handle more complex pluralization rules (e.g., specific cases for zero, one, two, few, many, other), you can extend the translation strings accordingly:

json
{
+  "apples": "no apples | one apple | two apples | a few apples | many apples | {count} apples"
+}
  • $tc('apples', 2): Could be set up to return "two apples".
  • $tc('apples', 3): Could return "a few apples", depending on the rules defined for the count.

🌐 Using $tn for Number Formatting

The $tn function formats numbers according to the current locale using the Intl.NumberFormat API. This is useful for displaying numbers in a way that matches the user's regional settings, such as currency, percentages, or other number formats.

Example: Using $tn for Number Formatting

vue
<template>
+  <div>
+    <!-- Format a number as currency -->
+    <p>{{ $tn(1234567.89, { style: 'currency', currency: 'USD' }) }}</p> <!-- Outputs: $1,234,567.89 in 'en-US' locale -->
+
+    <!-- Format a number with custom options -->
+    <p>{{ $tn(0.567, { style: 'percent', minimumFractionDigits: 1 }) }}</p> <!-- Outputs: 56.7% in 'en-US' locale -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $tn } = useNuxtApp()
+</script>

Example JSON for Number Formatting (No JSON needed for number formatting directly)

🗓️ Using $td for Date and Time Formatting

The $td function formats dates and times according to the current locale using the Intl.DateTimeFormat API. This is useful for displaying dates and times in formats that are familiar to the user based on their locale settings.

Example: Using $td for Date and Time Formatting

vue
<template>
+  <div>
+    <!-- Format a date with full options -->
+    <p>{{ $td(new Date(), { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) }}</p> <!-- Outputs: "Friday, September 1, 2023" in 'en-US' locale -->
+
+    <!-- Format a date with time -->
+    <p>{{ $td(new Date(), { hour: '2-digit', minute: '2-digit', second: '2-digit' }) }}</p> <!-- Outputs: "10:15:30 AM" in 'en-US' locale -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $td } = useNuxtApp()
+</script>
`,72)]))}const o=i(h,[["render",l]]);export{g as __pageData,o as default}; diff --git a/assets/examples.md.dgk20VMv.lean.js b/assets/examples.md.dgk20VMv.lean.js new file mode 100644 index 0000000..2eef8d9 --- /dev/null +++ b/assets/examples.md.dgk20VMv.lean.js @@ -0,0 +1,246 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"📚 Nuxt I18n Micro Examples and Usage","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"examples.md","filePath":"examples.md","lastUpdated":1729141863000}'),h={name:"examples.md"};function l(k,s,p,e,E,r){return t(),a("div",null,s[0]||(s[0]=[n(`

📚 Nuxt I18n Micro Examples and Usage

This section provides various examples demonstrating how to use Nuxt I18n Micro in your Nuxt.js application. You'll see how to switch locales, use the <i18n-link>, <i18n-switcher>, and <i18n-t> components, and dynamically handle translation keys.

🛠️ Basic Setup

Here's a basic setup to get started with Nuxt I18n Micro:

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: false, displayName: 'English' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr', disabled: false, displayName: 'Français' },
+      { code: 'de', iso: 'de-DE', dir: 'ltr', disabled: false, displayName: 'Deutsch' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

🌍 Locale Switching

Switching Locales Programmatically

This example demonstrates how to switch locales programmatically using buttons:

vue
<template>
+  <div>
+    <p>Current Locale: {{ $getLocale() }}</p>
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale.code"
+        :disabled="locale.code === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ $t(locale.code) }}
+      </button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>

Example JSON for Locale Switching

json
{
+  "en": "English",
+  "fr": "Français",
+  "de": "Deutsch"
+}

Using <i18n-switcher> Component

The <i18n-switcher> component provides a dropdown for locale switching with customizable labels:

vue
<template>
+  <div>
+    <i18n-switcher
+      :custom-labels="{ en: 'English', fr: 'Français', de: 'Deutsch' }"
+    />
+  </div>
+</template>

The <i18n-link> component automatically handles locale-specific routing:

vue
<template>
+  <div>
+    <i18n-link to="/about">{{ $t('about') }}</i18n-link>
+    <i18n-link :to="{ name: 'index' }">{{ $t('home') }}</i18n-link>
+  </div>
+</template>
+
+<script setup>
+  import { useNuxtApp } from '#imports'
+
+  const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>
json
{
+  "about": "About Us",
+  "home": "Home"
+}
vue
<template>
+  <div>
+    <i18n-link to="/about" activeClass="current">About Us</i18n-link>
+  </div>
+</template>

The same JSON file can be used as in the previous example for this scenario.

📝 Rendering Dynamic Keys from Translation Files

In some scenarios, you may want to iterate over dynamic keys stored within your translation files and render their values conditionally. The example below demonstrates how to achieve this using Nuxt I18n Micro.

Example: Rendering Dynamic Keys

This example fetches an array of keys from a specific translation path (in this case, dynamic) and iterates over them. Each key is checked for its existence using $has before rendering its value with $t.

vue
<template>
+  <div>
+    <div
+      v-for="key in $t('dynamic')"
+      :key="key"
+    >
+      <p>{{ key }}: <span v-if="$has(key)">{{ $t(key) }}</span></p>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $t, $has } = useNuxtApp()
+</script>

Example Translation File (en.json)

json
{
+  "dynamic": ["key1", "key2", "key3"],
+  "key1": "This is the first key's value",
+  "key2": "This is the second key's value",
+  "key3": "This is the third key's value"
+}

Example: Rendering Dynamic Keys from an Object

In this example, we handle an object stored within your translation file. We fetch and iterate over the keys of the object, dynamically rendering both the key names and their associated values.

vue
<template>
+  <div>
+    <div v-for="(value, key) in $t('dynamicObject')" :key="key">
+      <p>{{ key }}: {{ value }}</p>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $t } = useNuxtApp()
+</script>

Example Translation File (en.json)

json
{
+  "dynamicObject": {
+    "title": "Welcome to our site",
+    "description": "This is a brief description of our services.",
+    "footerNote": "Thank you for visiting!"
+  }
+}

🌟 Using <i18n-t> for Translations with Slots and Interpolation

The <i18n-t> component is useful for rendering translations with dynamic content and HTML tags:

vue
<template>
+  <i18n-t keypath="greeting" tag="h1">
+    <template #default="{ translation }">
+      <strong>{{ translation.replace('page', 'page replace') }}</strong> <i>!!!</i>
+    </template>
+  </i18n-t>
+</template>

Example JSON for <i18n-t>

json
{
+  "greeting": "Welcome to the page"
+}

With Interpolation

vue
<template>
+  <i18n-t keypath="welcome" :params="{ username: 'Alice', unreadCount: 5 }"></i18n-t>
+</template>

Example JSON for Interpolation

json
{
+  "welcome": "Hello {username}, you have {unreadCount} unread messages."
+}

📝 Comprehensive Example with Nested Sections

Here's a complex structure demonstrating multiple translation uses within a single page:

vue
<template>
+  <div>
+    <h1>{{ $t('mainHeader') }}</h1>
+
+    <nav>
+      <ul>
+        <li><a href="#">{{ $t('nav.home') }}</a></li>
+        <li><a href="#">{{ $t('nav.about') }}</a></li>
+        <li><a href="#">{{ $t('nav.services') }}</a></li>
+        <li><a href="#">{{ $t('nav.contact') }}</a></li>
+      </ul>
+    </nav>
+
+    <section>
+      <h2>{{ $t('section1.header') }}</h2>
+      <p>{{ $t('section1.intro') }}</p>
+
+      <div>
+        <h3>{{ $t('section1.subsection1.header') }}</h3>
+        <p>{{ $t('section1.subsection1.content') }}</p>
+      </div>
+
+      <div>
+        <h3>{{ $t('section1.subsection2.header') }}</h3>
+        <ul>
+          <li>{{ $t('section1.subsection2.item1') }}</li>
+          <li>{{ $t('section1.subsection2.item2') }}</li>
+          <li>{{ $t('section1.subsection2.item3') }}</li>
+        </ul>
+      </div>
+    </section>
+
+    <footer>
+      <h4>{{ $t('footer.contact.header') }}</h4>
+      <address>
+        {{ $t('footer.contact.address') }}<br>
+        {{ $t('footer.contact.city') }}<br>
+        {{ $t('footer.contact.phone') }}
+      </address>
+    </footer>
+
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale.code"
+        :disabled="locale.code === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ locale.code }}
+      </button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>

Example JSON for Nested Sections

json
{
+  "mainHeader": "Welcome to Our Services",
+  "nav": {
+    "home": "Home",
+    "about": "About Us",
+    "services": "Services",
+    "contact": "Contact"
+  },
+  "section1": {
+    "header": "Our Expertise",
+    "intro": "We provide a wide range of services to meet your needs.",
+    "subsection1": {
+      "header": "Consulting",
+      "content": "Our team offers expert consulting services in various domains."
+    },
+    "subsection2": {
+      "header": "Development",
+      "item1":
+
+ "Web Development",
+      "item2": "Mobile Apps",
+      "item3": "Custom Software"
+    }
+  },
+  "footer": {
+    "contact": {
+      "header": "Contact Us",
+      "address": "123 Main Street",
+      "city": "Anytown, USA",
+      "phone": "+1 (555) 123-4567"
+    }
+  }
+}

🌟 Using $tc for Pluralization

The $tc function in Nuxt I18n Micro handles pluralization based on the count and locale settings. This is useful for dynamically adjusting messages that involve counts, such as items, notifications, or other entities that can vary in number.

Example: Using $tc for Pluralization

In the following example, we display a message indicating the number of apples using $tc. The translation key handles multiple plural forms based on the count provided.

vue
<template>
+  <div>
+    <!-- Display a pluralized message about the number of apples -->
+    <p>{{ $tc('apples', 0) }}</p>  <!-- Outputs: no apples -->
+    <p>{{ $tc('apples', 1) }}</p>  <!-- Outputs: one apple -->
+    <p>{{ $tc('apples', 10) }}</p> <!-- Outputs: 10 apples -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $tc } = useNuxtApp()
+</script>

Example JSON for Pluralization

Here's how you can define the translation in your JSON file to handle different plural forms:

json
{
+  "apples": "no apples | one apple | {count} apples"
+}

Explanation

  • $tc('apples', 0): Returns the first form, used when the count is zero ("no apples").
  • $tc('apples', 1): Returns the second form, used when the count is one ("one apple").
  • $tc('apples', 10): Returns the third form with the count value, used when the count is two or more ("10 apples").

Additional Example with More Complex Pluralization

If your application needs to handle more complex pluralization rules (e.g., specific cases for zero, one, two, few, many, other), you can extend the translation strings accordingly:

json
{
+  "apples": "no apples | one apple | two apples | a few apples | many apples | {count} apples"
+}
  • $tc('apples', 2): Could be set up to return "two apples".
  • $tc('apples', 3): Could return "a few apples", depending on the rules defined for the count.

🌐 Using $tn for Number Formatting

The $tn function formats numbers according to the current locale using the Intl.NumberFormat API. This is useful for displaying numbers in a way that matches the user's regional settings, such as currency, percentages, or other number formats.

Example: Using $tn for Number Formatting

vue
<template>
+  <div>
+    <!-- Format a number as currency -->
+    <p>{{ $tn(1234567.89, { style: 'currency', currency: 'USD' }) }}</p> <!-- Outputs: $1,234,567.89 in 'en-US' locale -->
+
+    <!-- Format a number with custom options -->
+    <p>{{ $tn(0.567, { style: 'percent', minimumFractionDigits: 1 }) }}</p> <!-- Outputs: 56.7% in 'en-US' locale -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $tn } = useNuxtApp()
+</script>

Example JSON for Number Formatting (No JSON needed for number formatting directly)

🗓️ Using $td for Date and Time Formatting

The $td function formats dates and times according to the current locale using the Intl.DateTimeFormat API. This is useful for displaying dates and times in formats that are familiar to the user based on their locale settings.

Example: Using $td for Date and Time Formatting

vue
<template>
+  <div>
+    <!-- Format a date with full options -->
+    <p>{{ $td(new Date(), { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) }}</p> <!-- Outputs: "Friday, September 1, 2023" in 'en-US' locale -->
+
+    <!-- Format a date with time -->
+    <p>{{ $td(new Date(), { hour: '2-digit', minute: '2-digit', second: '2-digit' }) }}</p> <!-- Outputs: "10:15:30 AM" in 'en-US' locale -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $td } = useNuxtApp()
+</script>
`,72)]))}const o=i(h,[["render",l]]);export{g as __pageData,o as default}; diff --git a/assets/guide_cli.md.ZyFjsvrl.js b/assets/guide_cli.md.ZyFjsvrl.js new file mode 100644 index 0000000..7827371 --- /dev/null +++ b/assets/guide_cli.md.ZyFjsvrl.js @@ -0,0 +1 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🌐 nuxt-i18n-micro-cli Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/cli.md","filePath":"guide/cli.md","lastUpdated":1726648924000}'),n={name:"guide/cli.md"};function o(l,s,r,p,h,d){return t(),a("div",null,s[0]||(s[0]=[e('

🌐 nuxt-i18n-micro-cli Guide

📖 Introduction

nuxt-i18n-micro-cli is a command-line tool designed to streamline the localization and internationalization process in Nuxt.js projects using the nuxt-i18n module. It provides utilities to extract translation keys from your codebase, manage translation files, synchronize translations across locales, and automate the translation process using external translation services.

This guide will walk you through installing, configuring, and using nuxt-i18n-micro-cli to effectively manage your project's translations.

🔧 Installation and Setup

📦 Installing nuxt-i18n-micro-cli

Install nuxt-i18n-micro-cli globally using npm:

bash
npm install -g nuxt-i18n-micro-cli

This will make the i18n-micro command available globally on your system.

🛠 Initializing in Your Project

After installing, you can run i18n-micro commands in your Nuxt.js project directory.

Ensure that your project is set up with nuxt-i18n and has the necessary configuration in nuxt.config.js.

📄 Common Arguments

  • --cwd: Specify the current working directory (defaults to .).
  • --logLevel: Set the log level (silent, info, verbose).
  • --translationDir: Directory containing JSON translation files (default: locales).

📋 Commands

📊 stats Command

Description: The stats command is used to display translation statistics for each locale in your Nuxt.js project. It helps you understand the progress of your translations by showing how many keys are translated compared to the total number of keys available.

Usage:

bash
i18n-micro stats [options]

Options:

  • --full: Display combined translations statistics only (default: false).

Example:

bash
i18n-micro stats --full

🌍 translate Command

Description: The translate command automatically translates missing keys using external translation services. This command simplifies the translation process by leveraging APIs from services like Google Translate, DeepL, and others to fill in missing translations.

Usage:

bash
i18n-micro translate [options]

Options:

  • --service: Translation service to use (e.g., google, deepl, yandex). If not specified, the command will prompt you to select one.
  • --token: API key corresponding to the chosen translation service. If not provided, you will be prompted to enter it.
  • --options: Additional options for the translation service, provided as key:value pairs, separated by commas (e.g., model:gpt-3.5-turbo,max_tokens:1000).
  • --replace: Translate all keys, replacing existing translations (default: false).

Example:

bash
i18n-micro translate --service deepl --token YOUR_DEEPL_API_KEY

🌐 Supported Translation Services

The translate command supports multiple translation services. Some of the supported services are:

  • Google Translate (google)
  • DeepL (deepl)
  • Yandex Translate (yandex)
  • OpenAI (openai)
  • Azure Translator (azure)
  • IBM Watson (ibm)
  • Baidu Translate (baidu)
  • LibreTranslate (libretranslate)
  • MyMemory (mymemory)
  • Lingva Translate (lingvatranslate)
  • Papago (papago)
  • Tencent Translate (tencent)
  • Systran Translate (systran)
  • Yandex Cloud Translate (yandexcloud)
  • ModernMT (modernmt)
  • Lilt (lilt)
  • Unbabel (unbabel)
  • Reverso Translate (reverso)

⚙️ Service Configuration

Some services require specific configurations or API keys. When using the translate command, you can specify the service and provide the required --token (API key) and additional --options if needed.

For example:

bash
i18n-micro translate --service openai --token YOUR_OPENAI_API_KEY --options openaiModel:gpt-3.5-turbo,max_tokens:1000

🛠️ extract Command

Description: Extracts translation keys from your codebase and organizes them by scope.

Usage:

bash
i18n-micro extract [options]

Options:

  • --prod, -p: Run in production mode.

Example:

bash
i18n-micro extract

🔄 sync Command

Description: Synchronizes translation files across locales, ensuring all locales have the same keys.

Usage:

bash
i18n-micro sync [options]

Example:

bash
i18n-micro sync

validate Command

Description: Validates translation files for missing or extra keys compared to the reference locale.

Usage:

bash
i18n-micro validate [options]

Example:

bash
i18n-micro validate

🧹 clean Command

Description: Removes unused translation keys from translation files.

Usage:

bash
i18n-micro clean [options]

Example:

bash
i18n-micro clean

📤 import Command

Description: Converts PO files back to JSON format and saves them in the translation directory.

Usage:

bash
i18n-micro import [options]

Options:

  • --potsDir: Directory containing PO files (default: pots).

Example:

bash
i18n-micro import --potsDir pots

📥 export Command

Description: Exports translations to PO files for external translation management.

Usage:

bash
i18n-micro export [options]

Options:

  • --potsDir: Directory to save PO files (default: pots).

Example:

bash
i18n-micro export --potsDir pots

🗂️ export-csv Command

Description: The export-csv command exports translation keys and values from JSON files, including their file paths, into a CSV format. This command is useful for teams who prefer working with translation data in spreadsheet software.

Usage:

bash
i18n-micro export-csv [options]

Options:

  • --csvDir: Directory where the exported CSV files will be saved.
  • --delimiter: Specify a delimiter for the CSV file (default: ,).

Example:

bash
i18n-micro export-csv --csvDir csv_files

📑 import-csv Command

Description: The import-csv command imports translation data from CSV files, updating the corresponding JSON files. This is useful for applying bulk translation updates from spreadsheets.

Usage:

bash
i18n-micro import-csv [options]

Options:

  • --csvDir: Directory containing the CSV files to be imported.
  • --delimiter: Specify a delimiter used in the CSV file (default: ,).

Example:

bash
i18n-micro import-csv --csvDir csv_files

🧾 diff Command

Description: Compares translation files between the default locale and other locales within the same directory (including subdirectories). The command identifies missing keys and their values in the default locale compared to other locales, making it easier to track translation progress or discrepancies.

Usage:

bash
i18n-micro diff [options]

Example:

bash
i18n-micro diff

🔍 check-duplicates Command

Description: The check-duplicates command checks for duplicate translation values within each locale across all translation files, including both global and page-specific translations. It ensures that different keys within the same language do not share identical translation values, helping maintain clarity and consistency in your translations.

Usage:

bash
i18n-micro check-duplicates [options]

Example:

bash
i18n-micro check-duplicates

How it works:

  • The command checks both global and page-specific translation files for each locale.
  • If a translation value appears in multiple locations (either within global translations or across different pages), it reports the duplicate values along with the file and key where they are found.
  • If no duplicates are found, the command confirms that the locale is free of duplicated translation values.

This command helps ensure that translation keys maintain unique values, preventing accidental repetition within the same locale.

🔄 replace-values Command

Description: The replace-values command allows you to perform bulk replacements of translation values across all locales. It supports both simple text replacements and advanced replacements using regular expressions (regex). You can also use capturing groups in regex patterns and reference them in the replacement string, making it ideal for more complex replacement scenarios.

Usage:

bash
i18n-micro replace-values [options]

Options:

  • --search: The text or regex pattern to search for in translations. This is a required option.
  • --replace: The replacement text to be used for the found translations. This is a required option.
  • --useRegex: Enable search using a regular expression pattern (default: false).

Example 1: Simple replacement

Replace the string "Hello" with "Hi" across all locales:

bash
i18n-micro replace-values --search "Hello" --replace "Hi"

Example 2: Regex replacement

Enable regex search and replace any string starting with "Hello" followed by numbers (e.g., "Hello123") with "Hi" across all locales:

bash
i18n-micro replace-values --search "Hello\\\\d+" --replace "Hi" --useRegex

Example 3: Using regex capturing groups

Use capturing groups to dynamically insert part of the matched string into the replacement. For example, replace "Hello [name]" with "Hi [name]" while keeping the name intact:

bash
i18n-micro replace-values --search "Hello (\\\\w+)" --replace "Hi $1" --useRegex

In this case, $1 refers to the first capturing group, which matches the [name] part after "Hello". The replacement will keep the name from the original string.

How it works:

  • The command scans through all translation files (both global and page-specific).
  • When a match is found based on the search string or regex pattern, it replaces the matched text with the provided replacement.
  • When using regex, capturing groups can be used in the replacement string by referencing them with $1, $2, etc.
  • All changes are logged, showing the file path, translation key, and the before/after state of the translation value.

Logging: For each replacement, the command logs details including:

  • Locale and file path
  • The translation key being modified
  • The old value and the new value after replacement
  • If using regex with capturing groups, the logs will show the group matches and how they were replaced.

This allows you to track exactly where and what changes were made during the replacement operation, providing a clear history of modifications across your translation files.

🛠 Examples

  • Extracting translations:

    bash
    i18n-micro extract
  • Translating missing keys using Google Translate:

    bash
    i18n-micro translate --service google --token YOUR_GOOGLE_API_KEY
  • Translating all keys, replacing existing translations:

    bash
    i18n-micro translate --service deepl --token YOUR_DEEPL_API_KEY --replace
  • Validating translation files:

    bash
    i18n-micro validate
  • Cleaning unused translation keys:

    bash
    i18n-micro clean
  • Synchronizing translation files:

    bash
    i18n-micro sync

⚙️ Configuration Guide

nuxt-i18n-micro-cli relies on your Nuxt.js i18n configuration in nuxt.config.js. Ensure you have the nuxt-i18n module installed and configured.

🔑 nuxt.config.js Example

js
export default {\n  modules: ['@nuxtjs/i18n'],\n  i18n: {\n    locales: [\n      { code: 'en', iso: 'en-US' },\n      { code: 'fr', iso: 'fr-FR' },\n      { code: 'es', iso: 'es-ES' },\n      // Add other locales as needed\n    ],\n    defaultLocale: 'en',\n    vueI18n: {\n      fallbackLocale: 'en',\n    },\n    // Specify the directory where your translation files are stored\n    translationDir: 'locales',\n  },\n};

Ensure that the translationDir matches the directory used by nuxt-i18n-micro-cli (default is locales).

📝 Best Practices

🔑 Consistent Key Naming

Ensure translation keys are consistent and descriptive to avoid confusion and duplication.

🧹 Regular Maintenance

Use the clean command regularly to remove unused translation keys and keep your translation files clean.

🛠 Automate Translation Workflow

Integrate nuxt-i18n-micro-cli commands into your development workflow or CI/CD pipeline to automate extraction, translation, validation, and synchronization of translation files.

🛡️ Secure API Keys

When using translation services that require API keys, ensure your keys are kept secure and not committed to version control systems. Consider using environment variables or secure key management solutions.

📞 Support and Contributions

If you encounter issues or have suggestions for improvements, feel free to contribute to the project or open an issue on the project's repository.


By following this guide, you'll be able to effectively manage translations in your Nuxt.js project using nuxt-i18n-micro-cli, streamlining your internationalization efforts and ensuring a smooth experience for users in different locales.

',152)]))}const k=i(n,[["render",o]]);export{g as __pageData,k as default}; diff --git a/assets/guide_cli.md.ZyFjsvrl.lean.js b/assets/guide_cli.md.ZyFjsvrl.lean.js new file mode 100644 index 0000000..7827371 --- /dev/null +++ b/assets/guide_cli.md.ZyFjsvrl.lean.js @@ -0,0 +1 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🌐 nuxt-i18n-micro-cli Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/cli.md","filePath":"guide/cli.md","lastUpdated":1726648924000}'),n={name:"guide/cli.md"};function o(l,s,r,p,h,d){return t(),a("div",null,s[0]||(s[0]=[e('

🌐 nuxt-i18n-micro-cli Guide

📖 Introduction

nuxt-i18n-micro-cli is a command-line tool designed to streamline the localization and internationalization process in Nuxt.js projects using the nuxt-i18n module. It provides utilities to extract translation keys from your codebase, manage translation files, synchronize translations across locales, and automate the translation process using external translation services.

This guide will walk you through installing, configuring, and using nuxt-i18n-micro-cli to effectively manage your project's translations.

🔧 Installation and Setup

📦 Installing nuxt-i18n-micro-cli

Install nuxt-i18n-micro-cli globally using npm:

bash
npm install -g nuxt-i18n-micro-cli

This will make the i18n-micro command available globally on your system.

🛠 Initializing in Your Project

After installing, you can run i18n-micro commands in your Nuxt.js project directory.

Ensure that your project is set up with nuxt-i18n and has the necessary configuration in nuxt.config.js.

📄 Common Arguments

  • --cwd: Specify the current working directory (defaults to .).
  • --logLevel: Set the log level (silent, info, verbose).
  • --translationDir: Directory containing JSON translation files (default: locales).

📋 Commands

📊 stats Command

Description: The stats command is used to display translation statistics for each locale in your Nuxt.js project. It helps you understand the progress of your translations by showing how many keys are translated compared to the total number of keys available.

Usage:

bash
i18n-micro stats [options]

Options:

  • --full: Display combined translations statistics only (default: false).

Example:

bash
i18n-micro stats --full

🌍 translate Command

Description: The translate command automatically translates missing keys using external translation services. This command simplifies the translation process by leveraging APIs from services like Google Translate, DeepL, and others to fill in missing translations.

Usage:

bash
i18n-micro translate [options]

Options:

  • --service: Translation service to use (e.g., google, deepl, yandex). If not specified, the command will prompt you to select one.
  • --token: API key corresponding to the chosen translation service. If not provided, you will be prompted to enter it.
  • --options: Additional options for the translation service, provided as key:value pairs, separated by commas (e.g., model:gpt-3.5-turbo,max_tokens:1000).
  • --replace: Translate all keys, replacing existing translations (default: false).

Example:

bash
i18n-micro translate --service deepl --token YOUR_DEEPL_API_KEY

🌐 Supported Translation Services

The translate command supports multiple translation services. Some of the supported services are:

  • Google Translate (google)
  • DeepL (deepl)
  • Yandex Translate (yandex)
  • OpenAI (openai)
  • Azure Translator (azure)
  • IBM Watson (ibm)
  • Baidu Translate (baidu)
  • LibreTranslate (libretranslate)
  • MyMemory (mymemory)
  • Lingva Translate (lingvatranslate)
  • Papago (papago)
  • Tencent Translate (tencent)
  • Systran Translate (systran)
  • Yandex Cloud Translate (yandexcloud)
  • ModernMT (modernmt)
  • Lilt (lilt)
  • Unbabel (unbabel)
  • Reverso Translate (reverso)

⚙️ Service Configuration

Some services require specific configurations or API keys. When using the translate command, you can specify the service and provide the required --token (API key) and additional --options if needed.

For example:

bash
i18n-micro translate --service openai --token YOUR_OPENAI_API_KEY --options openaiModel:gpt-3.5-turbo,max_tokens:1000

🛠️ extract Command

Description: Extracts translation keys from your codebase and organizes them by scope.

Usage:

bash
i18n-micro extract [options]

Options:

  • --prod, -p: Run in production mode.

Example:

bash
i18n-micro extract

🔄 sync Command

Description: Synchronizes translation files across locales, ensuring all locales have the same keys.

Usage:

bash
i18n-micro sync [options]

Example:

bash
i18n-micro sync

validate Command

Description: Validates translation files for missing or extra keys compared to the reference locale.

Usage:

bash
i18n-micro validate [options]

Example:

bash
i18n-micro validate

🧹 clean Command

Description: Removes unused translation keys from translation files.

Usage:

bash
i18n-micro clean [options]

Example:

bash
i18n-micro clean

📤 import Command

Description: Converts PO files back to JSON format and saves them in the translation directory.

Usage:

bash
i18n-micro import [options]

Options:

  • --potsDir: Directory containing PO files (default: pots).

Example:

bash
i18n-micro import --potsDir pots

📥 export Command

Description: Exports translations to PO files for external translation management.

Usage:

bash
i18n-micro export [options]

Options:

  • --potsDir: Directory to save PO files (default: pots).

Example:

bash
i18n-micro export --potsDir pots

🗂️ export-csv Command

Description: The export-csv command exports translation keys and values from JSON files, including their file paths, into a CSV format. This command is useful for teams who prefer working with translation data in spreadsheet software.

Usage:

bash
i18n-micro export-csv [options]

Options:

  • --csvDir: Directory where the exported CSV files will be saved.
  • --delimiter: Specify a delimiter for the CSV file (default: ,).

Example:

bash
i18n-micro export-csv --csvDir csv_files

📑 import-csv Command

Description: The import-csv command imports translation data from CSV files, updating the corresponding JSON files. This is useful for applying bulk translation updates from spreadsheets.

Usage:

bash
i18n-micro import-csv [options]

Options:

  • --csvDir: Directory containing the CSV files to be imported.
  • --delimiter: Specify a delimiter used in the CSV file (default: ,).

Example:

bash
i18n-micro import-csv --csvDir csv_files

🧾 diff Command

Description: Compares translation files between the default locale and other locales within the same directory (including subdirectories). The command identifies missing keys and their values in the default locale compared to other locales, making it easier to track translation progress or discrepancies.

Usage:

bash
i18n-micro diff [options]

Example:

bash
i18n-micro diff

🔍 check-duplicates Command

Description: The check-duplicates command checks for duplicate translation values within each locale across all translation files, including both global and page-specific translations. It ensures that different keys within the same language do not share identical translation values, helping maintain clarity and consistency in your translations.

Usage:

bash
i18n-micro check-duplicates [options]

Example:

bash
i18n-micro check-duplicates

How it works:

  • The command checks both global and page-specific translation files for each locale.
  • If a translation value appears in multiple locations (either within global translations or across different pages), it reports the duplicate values along with the file and key where they are found.
  • If no duplicates are found, the command confirms that the locale is free of duplicated translation values.

This command helps ensure that translation keys maintain unique values, preventing accidental repetition within the same locale.

🔄 replace-values Command

Description: The replace-values command allows you to perform bulk replacements of translation values across all locales. It supports both simple text replacements and advanced replacements using regular expressions (regex). You can also use capturing groups in regex patterns and reference them in the replacement string, making it ideal for more complex replacement scenarios.

Usage:

bash
i18n-micro replace-values [options]

Options:

  • --search: The text or regex pattern to search for in translations. This is a required option.
  • --replace: The replacement text to be used for the found translations. This is a required option.
  • --useRegex: Enable search using a regular expression pattern (default: false).

Example 1: Simple replacement

Replace the string "Hello" with "Hi" across all locales:

bash
i18n-micro replace-values --search "Hello" --replace "Hi"

Example 2: Regex replacement

Enable regex search and replace any string starting with "Hello" followed by numbers (e.g., "Hello123") with "Hi" across all locales:

bash
i18n-micro replace-values --search "Hello\\\\d+" --replace "Hi" --useRegex

Example 3: Using regex capturing groups

Use capturing groups to dynamically insert part of the matched string into the replacement. For example, replace "Hello [name]" with "Hi [name]" while keeping the name intact:

bash
i18n-micro replace-values --search "Hello (\\\\w+)" --replace "Hi $1" --useRegex

In this case, $1 refers to the first capturing group, which matches the [name] part after "Hello". The replacement will keep the name from the original string.

How it works:

  • The command scans through all translation files (both global and page-specific).
  • When a match is found based on the search string or regex pattern, it replaces the matched text with the provided replacement.
  • When using regex, capturing groups can be used in the replacement string by referencing them with $1, $2, etc.
  • All changes are logged, showing the file path, translation key, and the before/after state of the translation value.

Logging: For each replacement, the command logs details including:

  • Locale and file path
  • The translation key being modified
  • The old value and the new value after replacement
  • If using regex with capturing groups, the logs will show the group matches and how they were replaced.

This allows you to track exactly where and what changes were made during the replacement operation, providing a clear history of modifications across your translation files.

🛠 Examples

  • Extracting translations:

    bash
    i18n-micro extract
  • Translating missing keys using Google Translate:

    bash
    i18n-micro translate --service google --token YOUR_GOOGLE_API_KEY
  • Translating all keys, replacing existing translations:

    bash
    i18n-micro translate --service deepl --token YOUR_DEEPL_API_KEY --replace
  • Validating translation files:

    bash
    i18n-micro validate
  • Cleaning unused translation keys:

    bash
    i18n-micro clean
  • Synchronizing translation files:

    bash
    i18n-micro sync

⚙️ Configuration Guide

nuxt-i18n-micro-cli relies on your Nuxt.js i18n configuration in nuxt.config.js. Ensure you have the nuxt-i18n module installed and configured.

🔑 nuxt.config.js Example

js
export default {\n  modules: ['@nuxtjs/i18n'],\n  i18n: {\n    locales: [\n      { code: 'en', iso: 'en-US' },\n      { code: 'fr', iso: 'fr-FR' },\n      { code: 'es', iso: 'es-ES' },\n      // Add other locales as needed\n    ],\n    defaultLocale: 'en',\n    vueI18n: {\n      fallbackLocale: 'en',\n    },\n    // Specify the directory where your translation files are stored\n    translationDir: 'locales',\n  },\n};

Ensure that the translationDir matches the directory used by nuxt-i18n-micro-cli (default is locales).

📝 Best Practices

🔑 Consistent Key Naming

Ensure translation keys are consistent and descriptive to avoid confusion and duplication.

🧹 Regular Maintenance

Use the clean command regularly to remove unused translation keys and keep your translation files clean.

🛠 Automate Translation Workflow

Integrate nuxt-i18n-micro-cli commands into your development workflow or CI/CD pipeline to automate extraction, translation, validation, and synchronization of translation files.

🛡️ Secure API Keys

When using translation services that require API keys, ensure your keys are kept secure and not committed to version control systems. Consider using environment variables or secure key management solutions.

📞 Support and Contributions

If you encounter issues or have suggestions for improvements, feel free to contribute to the project or open an issue on the project's repository.


By following this guide, you'll be able to effectively manage translations in your Nuxt.js project using nuxt-i18n-micro-cli, streamlining your internationalization efforts and ensuring a smooth experience for users in different locales.

',152)]))}const k=i(n,[["render",o]]);export{g as __pageData,k as default}; diff --git a/assets/guide_contribution.md.BHsQWQY9.js b/assets/guide_contribution.md.BHsQWQY9.js new file mode 100644 index 0000000..f7d5ddb --- /dev/null +++ b/assets/guide_contribution.md.BHsQWQY9.js @@ -0,0 +1,5 @@ +import{_ as i,c as a,a2 as t,o as s}from"./chunks/framework.CBrKbnPu.js";const u=JSON.parse('{"title":"🤝 Contribution Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/contribution.md","filePath":"guide/contribution.md","lastUpdated":1724679268000}'),n={name:"guide/contribution.md"};function o(r,e,l,h,d,p){return s(),a("div",null,e[0]||(e[0]=[t(`

🤝 Contribution Guide

📖 Introduction

Thank you for your interest in contributing to Nuxt I18n Micro! We welcome contributions from the community, whether it's bug fixes, new features, or improvements to the documentation. This guide outlines the steps to help you get started and ensures that your contributions can be easily integrated into the project.

🚀 Getting Started

1. 📚 Familiarize Yourself with the Project

Before making changes, it's a good idea to familiarize yourself with the project's architecture and codebase. Read through the existing documentation and take a look at open issues and pull requests to understand ongoing work and challenges.

2. 🍴 Fork the Repository

  • Navigate to the Nuxt I18n Micro repository.
  • Click the "Fork" button in the upper right corner to create a copy of the repository in your GitHub account.

3. 📥 Clone Your Fork

Clone the forked repository to your local machine:

bash
git clone https://github.com/<your-username>/nuxt-i18n-micro.git
+cd nuxt-i18n-micro

Replace <your-username> with your GitHub username.

4. 🌱 Create a Branch

Create a new branch for your work:

bash
git checkout -b feature/your-feature-name

Use descriptive branch names, such as bugfix/fix-translation-error or feature/add-new-locale-support.

🛠️ Local Development Setup

🛠 Prerequisites

Before you begin, ensure that you have the following installed on your machine:

  • Node.js: v16 or later
  • npm: v7 or later

🚀 Getting Started

1. 📥 Clone the Repository

First, you need to clone the nuxt-i18n-micro repository to your local machine.

bash
git clone https://github.com/s00d/nuxt-i18n-micro.git
+cd nuxt-i18n-micro

2. 📦 Install Dependencies

Next, install the project dependencies using npm.

bash
npm install
+npm run prepack && cd playground && npm run prepare && cd ..

3. 🖥️ Run the Development Server

To start the development server and work on the module, run the following command:

bash
npm run dev

This command will start the Nuxt development server using the playground directory as the testing environment. You can view the app in your browser by navigating to http://localhost:3000.

4. 🏗️ Building the Module

To build the module, use the following command:

bash
npm run prepack

This command prepares the module by building the necessary files, stubbing certain components, and ensuring everything is ready for packaging.

5. 🧹 Linting the Code

To ensure your code adheres to the project's coding standards, run the linter:

bash
npm run lint

If there are any issues, you can attempt to automatically fix them using:

bash
npm run lint:fix

6. ✅ Running Tests

To run the test suite, use the following command:

bash
npm run test

This will run all the Playwright tests to ensure everything is functioning as expected.

7. 🔍 Type Checking

For TypeScript type checking, run:

bash
npm run typecheck

This checks the type definitions to ensure there are no type errors.

8. 📚 Building and Previewing the Documentation

To build and preview the documentation locally, use the following commands:

bash
npm run docs:build
+npm run docs:serve

This will build the documentation and serve it locally, allowing you to view it in your browser.

9. 🎮 Running the Playground

If you want to test your changes in a sample Nuxt application, the playground directory serves as a sandbox environment. Run the following command to start the playground:

bash
npm run dev:build

You can access the playground app at http://localhost:3000.

🔧 Summary of Common Scripts

  • npm run dev: Start the development server using the playground.
  • npm run prepack: Build the module and prepare it for publishing.
  • npm run lint: Run the linter to check for code quality issues.
  • npm run lint:fix: Automatically fix linter issues.
  • npm run test: Run the test suite.
  • npm run typecheck: Check TypeScript types.
  • npm run docs:dev: Start the documentation site in development mode.
  • npm run docs:build: Build the documentation site.
  • npm run docs:serve: Serve the built documentation site locally.
  • npm run dev:build: Build the playground environment.

🚧 Making Changes

1. 💻 Code

  • Make your changes in the codebase according to the project’s architecture.
  • Follow the existing code style and conventions.
  • If you’re adding a new feature, consider writing tests for it.

2. 🧹 Run Linting

Before committing your changes, ensure that your code adheres to the project's coding standards by running the linter:

bash
npm run lint

Fix any linting errors before proceeding.

3. 🧪 Test Your Changes

Make sure your changes work and do not break any existing functionality:

  • Run all tests to ensure there are no errors:
bash
npm run test
  • If you’re fixing a bug, add tests to cover the fix.

4. 📝 Commit Your Changes

To ensure consistency across the project, we use a standardized commit message format. Please follow this format when making commits:

✅ Commit Message Format

Each commit message should be structured as follows:

<type>(<scope>): <short description>

📋 Examples:

  • fix(router): resolve issue with locale switching
  • feat(seo): add automatic og:locale meta tag generation
  • docs(contribution): update contribution guide with commit message format

🛠️ Commit Types:

  • feat: A new feature.
  • fix: A bug fix.
  • docs: Documentation changes or updates.
  • style: Code style or formatting changes (no functional impact).
  • refactor: Code changes that neither fix a bug nor add a feature.
  • test: Adding or updating tests.
  • chore: Miscellaneous tasks, such as updating build scripts or dependencies.

5. 🚀 Push to GitHub

Push your changes to your fork on GitHub:

bash
git push origin feature/your-feature-name

6. 🔄 Create a Pull Request

  • Go to your forked repository on GitHub.
  • Click the "Compare & pull request" button.
  • Ensure your PR targets the main branch of the original repository (s00d/nuxt-i18n-micro).
  • Describe your changes in the PR, and link to any relevant issues.

7. 🕵️‍♂️ Await Feedback

Once your pull request is submitted, a maintainer will review your changes. Be prepared to make adjustments based on feedback. Once approved, your PR will be merged into the main branch.

💡 Contribution Tips

  • 📝 Documentation: If you add or change a feature, ensure that you update the relevant documentation.
  • 🧼 Code Cleanliness: Keep your code clean and follow the project's coding standards.
  • 💬 Respectful Communication: Be respectful and friendly in your communications. We are all working towards the common goal of making Nuxt I18n Micro better.
`,88)]))}const g=i(n,[["render",o]]);export{u as __pageData,g as default}; diff --git a/assets/guide_contribution.md.BHsQWQY9.lean.js b/assets/guide_contribution.md.BHsQWQY9.lean.js new file mode 100644 index 0000000..f7d5ddb --- /dev/null +++ b/assets/guide_contribution.md.BHsQWQY9.lean.js @@ -0,0 +1,5 @@ +import{_ as i,c as a,a2 as t,o as s}from"./chunks/framework.CBrKbnPu.js";const u=JSON.parse('{"title":"🤝 Contribution Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/contribution.md","filePath":"guide/contribution.md","lastUpdated":1724679268000}'),n={name:"guide/contribution.md"};function o(r,e,l,h,d,p){return s(),a("div",null,e[0]||(e[0]=[t(`

🤝 Contribution Guide

📖 Introduction

Thank you for your interest in contributing to Nuxt I18n Micro! We welcome contributions from the community, whether it's bug fixes, new features, or improvements to the documentation. This guide outlines the steps to help you get started and ensures that your contributions can be easily integrated into the project.

🚀 Getting Started

1. 📚 Familiarize Yourself with the Project

Before making changes, it's a good idea to familiarize yourself with the project's architecture and codebase. Read through the existing documentation and take a look at open issues and pull requests to understand ongoing work and challenges.

2. 🍴 Fork the Repository

  • Navigate to the Nuxt I18n Micro repository.
  • Click the "Fork" button in the upper right corner to create a copy of the repository in your GitHub account.

3. 📥 Clone Your Fork

Clone the forked repository to your local machine:

bash
git clone https://github.com/<your-username>/nuxt-i18n-micro.git
+cd nuxt-i18n-micro

Replace <your-username> with your GitHub username.

4. 🌱 Create a Branch

Create a new branch for your work:

bash
git checkout -b feature/your-feature-name

Use descriptive branch names, such as bugfix/fix-translation-error or feature/add-new-locale-support.

🛠️ Local Development Setup

🛠 Prerequisites

Before you begin, ensure that you have the following installed on your machine:

  • Node.js: v16 or later
  • npm: v7 or later

🚀 Getting Started

1. 📥 Clone the Repository

First, you need to clone the nuxt-i18n-micro repository to your local machine.

bash
git clone https://github.com/s00d/nuxt-i18n-micro.git
+cd nuxt-i18n-micro

2. 📦 Install Dependencies

Next, install the project dependencies using npm.

bash
npm install
+npm run prepack && cd playground && npm run prepare && cd ..

3. 🖥️ Run the Development Server

To start the development server and work on the module, run the following command:

bash
npm run dev

This command will start the Nuxt development server using the playground directory as the testing environment. You can view the app in your browser by navigating to http://localhost:3000.

4. 🏗️ Building the Module

To build the module, use the following command:

bash
npm run prepack

This command prepares the module by building the necessary files, stubbing certain components, and ensuring everything is ready for packaging.

5. 🧹 Linting the Code

To ensure your code adheres to the project's coding standards, run the linter:

bash
npm run lint

If there are any issues, you can attempt to automatically fix them using:

bash
npm run lint:fix

6. ✅ Running Tests

To run the test suite, use the following command:

bash
npm run test

This will run all the Playwright tests to ensure everything is functioning as expected.

7. 🔍 Type Checking

For TypeScript type checking, run:

bash
npm run typecheck

This checks the type definitions to ensure there are no type errors.

8. 📚 Building and Previewing the Documentation

To build and preview the documentation locally, use the following commands:

bash
npm run docs:build
+npm run docs:serve

This will build the documentation and serve it locally, allowing you to view it in your browser.

9. 🎮 Running the Playground

If you want to test your changes in a sample Nuxt application, the playground directory serves as a sandbox environment. Run the following command to start the playground:

bash
npm run dev:build

You can access the playground app at http://localhost:3000.

🔧 Summary of Common Scripts

  • npm run dev: Start the development server using the playground.
  • npm run prepack: Build the module and prepare it for publishing.
  • npm run lint: Run the linter to check for code quality issues.
  • npm run lint:fix: Automatically fix linter issues.
  • npm run test: Run the test suite.
  • npm run typecheck: Check TypeScript types.
  • npm run docs:dev: Start the documentation site in development mode.
  • npm run docs:build: Build the documentation site.
  • npm run docs:serve: Serve the built documentation site locally.
  • npm run dev:build: Build the playground environment.

🚧 Making Changes

1. 💻 Code

  • Make your changes in the codebase according to the project’s architecture.
  • Follow the existing code style and conventions.
  • If you’re adding a new feature, consider writing tests for it.

2. 🧹 Run Linting

Before committing your changes, ensure that your code adheres to the project's coding standards by running the linter:

bash
npm run lint

Fix any linting errors before proceeding.

3. 🧪 Test Your Changes

Make sure your changes work and do not break any existing functionality:

  • Run all tests to ensure there are no errors:
bash
npm run test
  • If you’re fixing a bug, add tests to cover the fix.

4. 📝 Commit Your Changes

To ensure consistency across the project, we use a standardized commit message format. Please follow this format when making commits:

✅ Commit Message Format

Each commit message should be structured as follows:

<type>(<scope>): <short description>

📋 Examples:

  • fix(router): resolve issue with locale switching
  • feat(seo): add automatic og:locale meta tag generation
  • docs(contribution): update contribution guide with commit message format

🛠️ Commit Types:

  • feat: A new feature.
  • fix: A bug fix.
  • docs: Documentation changes or updates.
  • style: Code style or formatting changes (no functional impact).
  • refactor: Code changes that neither fix a bug nor add a feature.
  • test: Adding or updating tests.
  • chore: Miscellaneous tasks, such as updating build scripts or dependencies.

5. 🚀 Push to GitHub

Push your changes to your fork on GitHub:

bash
git push origin feature/your-feature-name

6. 🔄 Create a Pull Request

  • Go to your forked repository on GitHub.
  • Click the "Compare & pull request" button.
  • Ensure your PR targets the main branch of the original repository (s00d/nuxt-i18n-micro).
  • Describe your changes in the PR, and link to any relevant issues.

7. 🕵️‍♂️ Await Feedback

Once your pull request is submitted, a maintainer will review your changes. Be prepared to make adjustments based on feedback. Once approved, your PR will be merged into the main branch.

💡 Contribution Tips

  • 📝 Documentation: If you add or change a feature, ensure that you update the relevant documentation.
  • 🧼 Code Cleanliness: Keep your code clean and follow the project's coding standards.
  • 💬 Respectful Communication: Be respectful and friendly in your communications. We are all working towards the common goal of making Nuxt I18n Micro better.
`,88)]))}const g=i(n,[["render",o]]);export{u as __pageData,g as default}; diff --git a/assets/guide_crowdin.md.DEb4srNU.js b/assets/guide_crowdin.md.DEb4srNU.js new file mode 100644 index 0000000..619b2c5 --- /dev/null +++ b/assets/guide_crowdin.md.DEb4srNU.js @@ -0,0 +1,16 @@ +import{_ as a,c as s,a2 as n,o as e}from"./chunks/framework.CBrKbnPu.js";const u=JSON.parse('{"title":"🌐 Crowdin Integration Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/crowdin.md","filePath":"guide/crowdin.md","lastUpdated":1726410447000}'),t={name:"guide/crowdin.md"};function o(l,i,r,d,h,p){return e(),s("div",null,i[0]||(i[0]=[n(`

🌐 Crowdin Integration Guide

📖 Introduction

Integrating Crowdin into your project streamlines the localization and translation process, making it easier to manage translations across multiple languages and platforms. This guide provides a step-by-step walkthrough on setting up Crowdin with your project, including configuration, uploading sources, and downloading translations.

🔧 Installation and Setup

To get started with Crowdin, you'll need to install the Crowdin CLI globally on your machine and initialize it within your project directory.

📦 Installing Crowdin CLI

First, install the Crowdin CLI globally using npm:

bash
npm install -g @crowdin/cli

🛠 Initializing Crowdin in Your Project

Initialize Crowdin in your project by running:

bash
crowdin init

This command will guide you through the setup process, including setting your project ID, API token, and other configuration details.

🗂️ Configuration Guide

📄 Crowdin Configuration File (crowdin.yml)

The Crowdin configuration file (crowdin.yml) defines how your source files are mapped and where translations should be placed. Below is an example configuration:

yml
"project_id": "YOUR_PROJECT_ID"
+"api_token": "YOUR_API_TOKEN"
+"base_path": "./locales"
+"base_url": "https://api.crowdin.com"
+"preserve_hierarchy": true
+
+files: [
+  {
+    "source": "/en.json",
+    "translation": "/%two_letters_code%.json",
+  },
+  {
+    "source": "/pages/**/en.json",
+    "translation": "/pages/**/%two_letters_code%.json",
+  }
+]

📂 Key Configuration Parameters

  • project_id: Your Crowdin project ID. This identifies the project within Crowdin where translations are managed.
  • api_token: The API token used for authentication. Ensure this token has the correct permissions to upload and download translations.
  • base_path: Specifies the base directory for source files. In this example, translations are stored in the ./locales directory.
  • base_url: The base URL for the Crowdin API.
  • preserve_hierarchy: When set to true, Crowdin will maintain the folder structure of your source files in the project.

📂 Files Configuration

The files section maps your source files to the paths where translations will be stored. For example:

  • Source Path: Defines the location of the original translation files.
  • Translation Path: Specifies where the translated files will be stored in Crowdin. Placeholders like %two_letters_code% are used to dynamically set the language code in the file paths.

⬆️ Uploading Source Files to Crowdin

Once your Crowdin configuration is set up, you can upload your source files using the following command:

bash
crowdin upload sources

This command uploads all specified source files in your configuration to Crowdin, making them available for translation.

⬇️ Downloading Translations from Crowdin

After translations are completed or updated in Crowdin, you can download them to your project using:

bash
crowdin download

This command fetches the latest translations from Crowdin and saves them according to the paths specified in your configuration file.

⚙️ Best Practices

🔑 Consistent Key Naming

Ensure translation keys are consistent across all files to avoid confusion and duplication.

🧹 Regular Maintenance

Periodically review and clean up unused translation keys to keep your files organized and manageable.

🛠 Automate Uploads and Downloads

Integrate the Crowdin CLI commands into your CI/CD pipeline to automate the upload of source files and download of translations, ensuring your translations are always up to date.

By following this guide, you’ll be able to seamlessly integrate Crowdin into your project, ensuring an efficient and organized approach to managing your internationalization efforts.

`,37)]))}const g=a(t,[["render",o]]);export{u as __pageData,g as default}; diff --git a/assets/guide_crowdin.md.DEb4srNU.lean.js b/assets/guide_crowdin.md.DEb4srNU.lean.js new file mode 100644 index 0000000..619b2c5 --- /dev/null +++ b/assets/guide_crowdin.md.DEb4srNU.lean.js @@ -0,0 +1,16 @@ +import{_ as a,c as s,a2 as n,o as e}from"./chunks/framework.CBrKbnPu.js";const u=JSON.parse('{"title":"🌐 Crowdin Integration Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/crowdin.md","filePath":"guide/crowdin.md","lastUpdated":1726410447000}'),t={name:"guide/crowdin.md"};function o(l,i,r,d,h,p){return e(),s("div",null,i[0]||(i[0]=[n(`

🌐 Crowdin Integration Guide

📖 Introduction

Integrating Crowdin into your project streamlines the localization and translation process, making it easier to manage translations across multiple languages and platforms. This guide provides a step-by-step walkthrough on setting up Crowdin with your project, including configuration, uploading sources, and downloading translations.

🔧 Installation and Setup

To get started with Crowdin, you'll need to install the Crowdin CLI globally on your machine and initialize it within your project directory.

📦 Installing Crowdin CLI

First, install the Crowdin CLI globally using npm:

bash
npm install -g @crowdin/cli

🛠 Initializing Crowdin in Your Project

Initialize Crowdin in your project by running:

bash
crowdin init

This command will guide you through the setup process, including setting your project ID, API token, and other configuration details.

🗂️ Configuration Guide

📄 Crowdin Configuration File (crowdin.yml)

The Crowdin configuration file (crowdin.yml) defines how your source files are mapped and where translations should be placed. Below is an example configuration:

yml
"project_id": "YOUR_PROJECT_ID"
+"api_token": "YOUR_API_TOKEN"
+"base_path": "./locales"
+"base_url": "https://api.crowdin.com"
+"preserve_hierarchy": true
+
+files: [
+  {
+    "source": "/en.json",
+    "translation": "/%two_letters_code%.json",
+  },
+  {
+    "source": "/pages/**/en.json",
+    "translation": "/pages/**/%two_letters_code%.json",
+  }
+]

📂 Key Configuration Parameters

  • project_id: Your Crowdin project ID. This identifies the project within Crowdin where translations are managed.
  • api_token: The API token used for authentication. Ensure this token has the correct permissions to upload and download translations.
  • base_path: Specifies the base directory for source files. In this example, translations are stored in the ./locales directory.
  • base_url: The base URL for the Crowdin API.
  • preserve_hierarchy: When set to true, Crowdin will maintain the folder structure of your source files in the project.

📂 Files Configuration

The files section maps your source files to the paths where translations will be stored. For example:

  • Source Path: Defines the location of the original translation files.
  • Translation Path: Specifies where the translated files will be stored in Crowdin. Placeholders like %two_letters_code% are used to dynamically set the language code in the file paths.

⬆️ Uploading Source Files to Crowdin

Once your Crowdin configuration is set up, you can upload your source files using the following command:

bash
crowdin upload sources

This command uploads all specified source files in your configuration to Crowdin, making them available for translation.

⬇️ Downloading Translations from Crowdin

After translations are completed or updated in Crowdin, you can download them to your project using:

bash
crowdin download

This command fetches the latest translations from Crowdin and saves them according to the paths specified in your configuration file.

⚙️ Best Practices

🔑 Consistent Key Naming

Ensure translation keys are consistent across all files to avoid confusion and duplication.

🧹 Regular Maintenance

Periodically review and clean up unused translation keys to keep your files organized and manageable.

🛠 Automate Uploads and Downloads

Integrate the Crowdin CLI commands into your CI/CD pipeline to automate the upload of source files and download of translations, ensuring your translations are always up to date.

By following this guide, you’ll be able to seamlessly integrate Crowdin into your project, ensuring an efficient and organized approach to managing your internationalization efforts.

`,37)]))}const g=a(t,[["render",o]]);export{u as __pageData,g as default}; diff --git a/assets/guide_custom-locale-routes.md.DeZ1f3q2.js b/assets/guide_custom-locale-routes.md.DeZ1f3q2.js new file mode 100644 index 0000000..3bdf3ac --- /dev/null +++ b/assets/guide_custom-locale-routes.md.DeZ1f3q2.js @@ -0,0 +1,35 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/custom-locale-routes.md","filePath":"guide/custom-locale-routes.md","lastUpdated":1725088182000}'),n={name:"guide/custom-locale-routes.md"};function l(o,s,h,p,r,k){return t(),a("div",null,s[0]||(s[0]=[e(`

🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro

📖 Introduction to localeRoutes

The localeRoutes feature in Nuxt I18n Micro allows you to define custom routes for specific locales, offering flexibility and control over the routing structure of your application. This feature is particularly useful when certain locales require different URL structures, tailored paths, or need to follow specific regional or linguistic conventions.

🚀 Primary Use Case of localeRoutes

The primary use case for localeRoutes is to provide distinct routes for different locales, enhancing the user experience by ensuring URLs are intuitive and relevant to the target audience. For example, you might have different paths for English and Russian versions of a page, where the Russian locale follows a localized URL format.

📄 Example: Defining localeRoutes in $defineI18nRoute

Here’s an example of how you might define custom routes for specific locales using localeRoutes in your $defineI18nRoute function:

typescript
$defineI18nRoute({
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for the Russian locale
+    de: '/lokaleseite',   // Custom route path for the German locale
+  },
+})

🔄 How localeRoutes Work

  • Default Behavior: Without localeRoutes, all locales use a common route structure defined by the primary path.
  • Custom Behavior: With localeRoutes, specific locales can have their own routes, overriding the default path with locale-specific routes defined in the configuration.

🌱 Use Cases for localeRoutes

📄 Example: Using localeRoutes in a Page

Here’s a simple Vue component demonstrating the use of $defineI18nRoute with localeRoutes:

vue
<template>
+  <div>
+    <!-- Display greeting message based on the current locale -->
+    <p>{{ $t('greeting') }}</p>
+
+    <!-- Navigation links -->
+    <div>
+      <NuxtLink :to="$localeRoute({ name: 'index' })">
+        Go to Index
+      </NuxtLink>
+      |
+      <NuxtLink :to="$localeRoute({ name: 'about' })">
+        Go to About Page
+      </NuxtLink>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t, $defineI18nRoute } = useNuxtApp()
+
+// Define translations and custom routes for specific locales
+$defineI18nRoute({
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for Russian locale
+  },
+})
+</script>

🛠️ Using localeRoutes in Different Contexts

  • Landing Pages: Use custom routes to localize URLs for landing pages, ensuring they align with marketing campaigns.
  • Documentation Sites: Provide distinct routes for each locale to better match the localized content structure.
  • E-commerce Sites: Tailor product or category URLs per locale for improved SEO and user experience.

📝 Best Practices for Using localeRoutes

  • 🚀 Use for Relevant Locales: Apply localeRoutes primarily where the URL structure significantly impacts the user experience or SEO. Avoid overuse for minor differences.
  • 🔧 Maintain Consistency: Keep a consistent routing pattern across locales unless there's a strong reason to deviate. This approach helps in maintaining clarity and reducing complexity.
  • 📚 Document Custom Routes: Clearly document any custom routes you define with localeRoutes, especially in modular applications, to ensure team members understand the routing logic.
`,18)]))}const E=i(n,[["render",l]]);export{d as __pageData,E as default}; diff --git a/assets/guide_custom-locale-routes.md.DeZ1f3q2.lean.js b/assets/guide_custom-locale-routes.md.DeZ1f3q2.lean.js new file mode 100644 index 0000000..3bdf3ac --- /dev/null +++ b/assets/guide_custom-locale-routes.md.DeZ1f3q2.lean.js @@ -0,0 +1,35 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/custom-locale-routes.md","filePath":"guide/custom-locale-routes.md","lastUpdated":1725088182000}'),n={name:"guide/custom-locale-routes.md"};function l(o,s,h,p,r,k){return t(),a("div",null,s[0]||(s[0]=[e(`

🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro

📖 Introduction to localeRoutes

The localeRoutes feature in Nuxt I18n Micro allows you to define custom routes for specific locales, offering flexibility and control over the routing structure of your application. This feature is particularly useful when certain locales require different URL structures, tailored paths, or need to follow specific regional or linguistic conventions.

🚀 Primary Use Case of localeRoutes

The primary use case for localeRoutes is to provide distinct routes for different locales, enhancing the user experience by ensuring URLs are intuitive and relevant to the target audience. For example, you might have different paths for English and Russian versions of a page, where the Russian locale follows a localized URL format.

📄 Example: Defining localeRoutes in $defineI18nRoute

Here’s an example of how you might define custom routes for specific locales using localeRoutes in your $defineI18nRoute function:

typescript
$defineI18nRoute({
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for the Russian locale
+    de: '/lokaleseite',   // Custom route path for the German locale
+  },
+})

🔄 How localeRoutes Work

  • Default Behavior: Without localeRoutes, all locales use a common route structure defined by the primary path.
  • Custom Behavior: With localeRoutes, specific locales can have their own routes, overriding the default path with locale-specific routes defined in the configuration.

🌱 Use Cases for localeRoutes

📄 Example: Using localeRoutes in a Page

Here’s a simple Vue component demonstrating the use of $defineI18nRoute with localeRoutes:

vue
<template>
+  <div>
+    <!-- Display greeting message based on the current locale -->
+    <p>{{ $t('greeting') }}</p>
+
+    <!-- Navigation links -->
+    <div>
+      <NuxtLink :to="$localeRoute({ name: 'index' })">
+        Go to Index
+      </NuxtLink>
+      |
+      <NuxtLink :to="$localeRoute({ name: 'about' })">
+        Go to About Page
+      </NuxtLink>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t, $defineI18nRoute } = useNuxtApp()
+
+// Define translations and custom routes for specific locales
+$defineI18nRoute({
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for Russian locale
+  },
+})
+</script>

🛠️ Using localeRoutes in Different Contexts

  • Landing Pages: Use custom routes to localize URLs for landing pages, ensuring they align with marketing campaigns.
  • Documentation Sites: Provide distinct routes for each locale to better match the localized content structure.
  • E-commerce Sites: Tailor product or category URLs per locale for improved SEO and user experience.

📝 Best Practices for Using localeRoutes

  • 🚀 Use for Relevant Locales: Apply localeRoutes primarily where the URL structure significantly impacts the user experience or SEO. Avoid overuse for minor differences.
  • 🔧 Maintain Consistency: Keep a consistent routing pattern across locales unless there's a strong reason to deviate. This approach helps in maintaining clarity and reducing complexity.
  • 📚 Document Custom Routes: Clearly document any custom routes you define with localeRoutes, especially in modular applications, to ensure team members understand the routing logic.
`,18)]))}const E=i(n,[["render",l]]);export{d as __pageData,E as default}; diff --git a/assets/guide_faq.md.Vyfgzyoq.js b/assets/guide_faq.md.Vyfgzyoq.js new file mode 100644 index 0000000..fe9c5e4 --- /dev/null +++ b/assets/guide_faq.md.Vyfgzyoq.js @@ -0,0 +1,20 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"FAQ: Common Issues & Solutions","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/faq.md","filePath":"guide/faq.md","lastUpdated":1729616442000}'),n={name:"guide/faq.md"};function l(h,s,p,r,k,o){return t(),a("div",null,s[0]||(s[0]=[e(`

FAQ: Common Issues & Solutions

❓ What if a route doesn't load?

One common issue when using Nuxt I18n Micro is that some routes might not open as expected. This can happen when the router doesn’t automatically assign a name to a route, particularly in subfolders.

Solution: To fix this, manually define the page’s route name by adding the following to the corresponding Vue file:

javascript
definePageMeta({ name: 'pageName' })

This ensures that the route is properly registered, and the application can navigate to it without issues.


❓ Why is the assets/_locales/ folder added to the server folder?

When deploying to platforms like Netlify, the build process might behave differently compared to local development. This can lead to issues where certain files or folders are not found during server-side rendering (SSR).

To ensure that localization files are available during SSR, the assets/_locales/ folder is added to the server folder. This is a workaround to make sure that the localization files are accessible in the production environment, especially when the build process and runtime environment differ.

Explanation:

  • Build Process: During the build, all translations are cached in the production folder. However, when deploying to platforms like Netlify, the server code is moved to functions, and there might be a separate container where locale files are not accessible.
  • Prerendering: Prerendering does not work when using $fetch in SSR, leading to middleware not finding the localization files.
  • Server Assets: To address this, the localization files are saved in the Nitro server assets during prerendering. In production, they are read from the server assets.

❓ Is Nuxt I18n Micro inspired by vue-i18n? What about features like modifiers?

While Nuxt I18n Micro serves as a performance alternative to nuxt-i18n, it is not directly inspired by vue-i18n. The library was built from scratch to address issues in nuxt-i18n, and while some method names and parameters are similar, the underlying logic is entirely different.

Modifiers: The maintainer experimented with adding modifiers but found that components like <i18n-t> and <i18n-link> effectively cover the same needs. For example:

vue
<template>
+  <i18n-t keypath="feedback.text">
+    <template #link>
+      <nuxt-link :to="{ name: 'index' }">
+        <i18n-t keypath="feedback.link" />
+      </nuxt-link>
+    </template>
+  </i18n-t>
+</template>

Since this approach is flexible and powerful, releasing modifiers was deemed unnecessary for now. However, modifiers may be added in the future if demand arises.


Yes, Nuxt I18n Micro allows you to use NuxtLink or i18nLink in translations through the <i18n-t> component, eliminating the need to split translation strings, which can be especially helpful when dealing with languages that have different grammatical rules or RTL languages.

Example:

json
{
+  "example": "Share your {link} with friends",
+  "link_text": "translation link"
+}
vue
<template>
+  <i18n-t keypath="example">
+    <template #link>
+      <nuxt-link :to="{ name: 'referral' }">
+        <i18n-t keypath="link_text" />
+      </nuxt-link>
+    </template>
+  </i18n-t>
+</template>

This method supports dynamic link creation inside translations while maintaining proper localization structure.

`,25)]))}const g=i(n,[["render",l]]);export{E as __pageData,g as default}; diff --git a/assets/guide_faq.md.Vyfgzyoq.lean.js b/assets/guide_faq.md.Vyfgzyoq.lean.js new file mode 100644 index 0000000..fe9c5e4 --- /dev/null +++ b/assets/guide_faq.md.Vyfgzyoq.lean.js @@ -0,0 +1,20 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"FAQ: Common Issues & Solutions","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/faq.md","filePath":"guide/faq.md","lastUpdated":1729616442000}'),n={name:"guide/faq.md"};function l(h,s,p,r,k,o){return t(),a("div",null,s[0]||(s[0]=[e(`

FAQ: Common Issues & Solutions

❓ What if a route doesn't load?

One common issue when using Nuxt I18n Micro is that some routes might not open as expected. This can happen when the router doesn’t automatically assign a name to a route, particularly in subfolders.

Solution: To fix this, manually define the page’s route name by adding the following to the corresponding Vue file:

javascript
definePageMeta({ name: 'pageName' })

This ensures that the route is properly registered, and the application can navigate to it without issues.


❓ Why is the assets/_locales/ folder added to the server folder?

When deploying to platforms like Netlify, the build process might behave differently compared to local development. This can lead to issues where certain files or folders are not found during server-side rendering (SSR).

To ensure that localization files are available during SSR, the assets/_locales/ folder is added to the server folder. This is a workaround to make sure that the localization files are accessible in the production environment, especially when the build process and runtime environment differ.

Explanation:

  • Build Process: During the build, all translations are cached in the production folder. However, when deploying to platforms like Netlify, the server code is moved to functions, and there might be a separate container where locale files are not accessible.
  • Prerendering: Prerendering does not work when using $fetch in SSR, leading to middleware not finding the localization files.
  • Server Assets: To address this, the localization files are saved in the Nitro server assets during prerendering. In production, they are read from the server assets.

❓ Is Nuxt I18n Micro inspired by vue-i18n? What about features like modifiers?

While Nuxt I18n Micro serves as a performance alternative to nuxt-i18n, it is not directly inspired by vue-i18n. The library was built from scratch to address issues in nuxt-i18n, and while some method names and parameters are similar, the underlying logic is entirely different.

Modifiers: The maintainer experimented with adding modifiers but found that components like <i18n-t> and <i18n-link> effectively cover the same needs. For example:

vue
<template>
+  <i18n-t keypath="feedback.text">
+    <template #link>
+      <nuxt-link :to="{ name: 'index' }">
+        <i18n-t keypath="feedback.link" />
+      </nuxt-link>
+    </template>
+  </i18n-t>
+</template>

Since this approach is flexible and powerful, releasing modifiers was deemed unnecessary for now. However, modifiers may be added in the future if demand arises.


Yes, Nuxt I18n Micro allows you to use NuxtLink or i18nLink in translations through the <i18n-t> component, eliminating the need to split translation strings, which can be especially helpful when dealing with languages that have different grammatical rules or RTL languages.

Example:

json
{
+  "example": "Share your {link} with friends",
+  "link_text": "translation link"
+}
vue
<template>
+  <i18n-t keypath="example">
+    <template #link>
+      <nuxt-link :to="{ name: 'referral' }">
+        <i18n-t keypath="link_text" />
+      </nuxt-link>
+    </template>
+  </i18n-t>
+</template>

This method supports dynamic link creation inside translations while maintaining proper localization structure.

`,25)]))}const g=i(n,[["render",l]]);export{E as __pageData,g as default}; diff --git a/assets/guide_folder-structure.md.Cky6Juvc.js b/assets/guide_folder-structure.md.Cky6Juvc.js new file mode 100644 index 0000000..96c6dbd --- /dev/null +++ b/assets/guide_folder-structure.md.Cky6Juvc.js @@ -0,0 +1,44 @@ +import{_ as s,c as e,a2 as n,o as i}from"./chunks/framework.CBrKbnPu.js";const u=JSON.parse('{"title":"📂 Folder Structure Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/folder-structure.md","filePath":"guide/folder-structure.md","lastUpdated":1724243643000}'),t={name:"guide/folder-structure.md"};function o(l,a,r,p,d,c){return i(),e("div",null,a[0]||(a[0]=[n(`

📂 Folder Structure Guide

📖 Introduction

Organizing your translation files effectively is essential for maintaining a scalable and efficient internationalization (i18n) system. Nuxt I18n Micro simplifies this process by offering a clear approach to managing global and page-specific translations. This guide will walk you through the recommended folder structure and explain how Nuxt I18n Micro handles these translations.

Nuxt I18n Micro organizes translations into global files and page-specific files within the pages directory. This ensures that only the necessary translation data is loaded when required, optimizing both performance and organization.

🔧 Basic Structure

Here’s a basic example of the folder structure you should follow:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json

📄 Explanation of Structure

1. 🌍 Global Translation Files

  • Path: /locales/{locale}.json (e.g., /locales/en.json)

  • Purpose: These files contain translations that are shared across the entire application. This is useful for common elements like navigation menus, headers, footers, or any text that appears on multiple pages.

    Example Content (/locales/en.json):

    json
    {
    +  "menu": {
    +    "home": "Home",
    +    "about": "About Us",
    +    "contact": "Contact"
    +  },
    +  "footer": {
    +    "copyright": "© 2024 Your Company"
    +  }
    +}

2. 📄 Page-Specific Translation Files

  • Path: /locales/pages/{routeName}/{locale}.json (e.g., /locales/pages/index/en.json)

  • Purpose: These files are used for translations that are specific to individual pages. This allows you to load only the necessary translations when a user visits a particular page, which enhances performance by reducing the amount of data that needs to be loaded.

    Example Content (/locales/pages/index/en.json):

    json
    {
    +  "title": "Welcome to Our Website",
    +  "description": "We offer a wide range of products and services to meet your needs."
    +}

    Example Content (/locales/pages/about/en.json):

    json
    {
    +  "title": "About Us",
    +  "description": "Learn more about our mission, vision, and values."
    +}

📂 Handling Dynamic Routes and Nested Paths

Nuxt I18n Micro automatically transforms dynamic segments and nested paths in routes into a flat folder structure using a specific renaming convention. This ensures that all translations are stored in a consistent and easily accessible manner.

Dynamic Route Translation Folder Structure

When dealing with dynamic routes, such as /products/[id], the module converts the dynamic segment [id] into a static format within the file structure.

Example Folder Structure for Dynamic Routes:

For a route like /products/[id], the translation files would be stored in a folder named products-id:

plaintext
  /locales/pages
+  ├── /products-id
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

Example Folder Structure for Nested Dynamic Routes:

For a nested route like /products/key/[id], the translation files would be stored in a folder named products-key-id:

plaintext
  /locales/pages
+  ├── /products-key-id
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

Example Folder Structure for Multi-Level Nested Routes:

For a more complex nested route like /products/category/[id]/details, the translation files would be stored in a folder named products-category-id-details:

plaintext
  /locales/pages
+  ├── /products-category-id-details
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

🛠 Customizing the Directory Structure

If you prefer to store translations in a different directory, Nuxt I18n Micro allows you to customize the directory where translation files are stored. You can configure this in your nuxt.config.ts file.

Example: Customizing the Translation Directory

typescript
export default defineNuxtConfig({
+  i18n: {
+    translationDir: 'i18n' // Custom directory path
+  }
+})

This will instruct Nuxt I18n Micro to look for translation files in the /i18n directory instead of the default /locales directory.

⚙️ How Translations are Loaded

🌍 Dynamic Locale Routes

Nuxt I18n Micro uses dynamic locale routes to load translations efficiently. When a user visits a page, the module determines the appropriate locale and loads the corresponding translation files based on the current route and locale.

For example:

  • Visiting /en/index will load translations from /locales/pages/index/en.json.
  • Visiting /fr/about will load translations from /locales/pages/about/fr.json.

This method ensures that only the necessary translations are loaded, optimizing both server load and client-side performance.

💾 Caching and Pre-rendering

To further enhance performance, Nuxt I18n Micro supports caching and pre-rendering of translation files:

  • Caching: Once a translation file is loaded, it’s cached for subsequent requests, reducing the need to repeatedly fetch the same data.
  • Pre-rendering: During the build process, you can pre-render translation files for all configured locales and routes, allowing them to be served directly from the server without runtime delays.

📝 Best Practices

📂 Use Page-Specific Files Wisely

Leverage page-specific files to avoid bloating global translation files. This keeps each page’s translations lean and fast to load, which is especially important for pages with complex or large content.

🔑 Keep Translation Keys Consistent

Use consistent naming conventions for your translation keys across files. This helps maintain clarity and prevents issues when managing translations, especially as your application grows.

🗂️ Organize Translations by Context

Group related translations together within your files. For example, group all button labels under a buttons key and all form-related texts under a forms key. This not only improves readability but also makes it easier to manage translations across different locales.

🧹 Regularly Clean Up Unused Translations

Over time, your application might accumulate unused translation keys, especially if features are removed or restructured. Periodically review and clean up your translation files to keep them lean and maintainable.

`,49)]))}const g=s(t,[["render",o]]);export{u as __pageData,g as default}; diff --git a/assets/guide_folder-structure.md.Cky6Juvc.lean.js b/assets/guide_folder-structure.md.Cky6Juvc.lean.js new file mode 100644 index 0000000..96c6dbd --- /dev/null +++ b/assets/guide_folder-structure.md.Cky6Juvc.lean.js @@ -0,0 +1,44 @@ +import{_ as s,c as e,a2 as n,o as i}from"./chunks/framework.CBrKbnPu.js";const u=JSON.parse('{"title":"📂 Folder Structure Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/folder-structure.md","filePath":"guide/folder-structure.md","lastUpdated":1724243643000}'),t={name:"guide/folder-structure.md"};function o(l,a,r,p,d,c){return i(),e("div",null,a[0]||(a[0]=[n(`

📂 Folder Structure Guide

📖 Introduction

Organizing your translation files effectively is essential for maintaining a scalable and efficient internationalization (i18n) system. Nuxt I18n Micro simplifies this process by offering a clear approach to managing global and page-specific translations. This guide will walk you through the recommended folder structure and explain how Nuxt I18n Micro handles these translations.

Nuxt I18n Micro organizes translations into global files and page-specific files within the pages directory. This ensures that only the necessary translation data is loaded when required, optimizing both performance and organization.

🔧 Basic Structure

Here’s a basic example of the folder structure you should follow:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json

📄 Explanation of Structure

1. 🌍 Global Translation Files

  • Path: /locales/{locale}.json (e.g., /locales/en.json)

  • Purpose: These files contain translations that are shared across the entire application. This is useful for common elements like navigation menus, headers, footers, or any text that appears on multiple pages.

    Example Content (/locales/en.json):

    json
    {
    +  "menu": {
    +    "home": "Home",
    +    "about": "About Us",
    +    "contact": "Contact"
    +  },
    +  "footer": {
    +    "copyright": "© 2024 Your Company"
    +  }
    +}

2. 📄 Page-Specific Translation Files

  • Path: /locales/pages/{routeName}/{locale}.json (e.g., /locales/pages/index/en.json)

  • Purpose: These files are used for translations that are specific to individual pages. This allows you to load only the necessary translations when a user visits a particular page, which enhances performance by reducing the amount of data that needs to be loaded.

    Example Content (/locales/pages/index/en.json):

    json
    {
    +  "title": "Welcome to Our Website",
    +  "description": "We offer a wide range of products and services to meet your needs."
    +}

    Example Content (/locales/pages/about/en.json):

    json
    {
    +  "title": "About Us",
    +  "description": "Learn more about our mission, vision, and values."
    +}

📂 Handling Dynamic Routes and Nested Paths

Nuxt I18n Micro automatically transforms dynamic segments and nested paths in routes into a flat folder structure using a specific renaming convention. This ensures that all translations are stored in a consistent and easily accessible manner.

Dynamic Route Translation Folder Structure

When dealing with dynamic routes, such as /products/[id], the module converts the dynamic segment [id] into a static format within the file structure.

Example Folder Structure for Dynamic Routes:

For a route like /products/[id], the translation files would be stored in a folder named products-id:

plaintext
  /locales/pages
+  ├── /products-id
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

Example Folder Structure for Nested Dynamic Routes:

For a nested route like /products/key/[id], the translation files would be stored in a folder named products-key-id:

plaintext
  /locales/pages
+  ├── /products-key-id
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

Example Folder Structure for Multi-Level Nested Routes:

For a more complex nested route like /products/category/[id]/details, the translation files would be stored in a folder named products-category-id-details:

plaintext
  /locales/pages
+  ├── /products-category-id-details
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

🛠 Customizing the Directory Structure

If you prefer to store translations in a different directory, Nuxt I18n Micro allows you to customize the directory where translation files are stored. You can configure this in your nuxt.config.ts file.

Example: Customizing the Translation Directory

typescript
export default defineNuxtConfig({
+  i18n: {
+    translationDir: 'i18n' // Custom directory path
+  }
+})

This will instruct Nuxt I18n Micro to look for translation files in the /i18n directory instead of the default /locales directory.

⚙️ How Translations are Loaded

🌍 Dynamic Locale Routes

Nuxt I18n Micro uses dynamic locale routes to load translations efficiently. When a user visits a page, the module determines the appropriate locale and loads the corresponding translation files based on the current route and locale.

For example:

  • Visiting /en/index will load translations from /locales/pages/index/en.json.
  • Visiting /fr/about will load translations from /locales/pages/about/fr.json.

This method ensures that only the necessary translations are loaded, optimizing both server load and client-side performance.

💾 Caching and Pre-rendering

To further enhance performance, Nuxt I18n Micro supports caching and pre-rendering of translation files:

  • Caching: Once a translation file is loaded, it’s cached for subsequent requests, reducing the need to repeatedly fetch the same data.
  • Pre-rendering: During the build process, you can pre-render translation files for all configured locales and routes, allowing them to be served directly from the server without runtime delays.

📝 Best Practices

📂 Use Page-Specific Files Wisely

Leverage page-specific files to avoid bloating global translation files. This keeps each page’s translations lean and fast to load, which is especially important for pages with complex or large content.

🔑 Keep Translation Keys Consistent

Use consistent naming conventions for your translation keys across files. This helps maintain clarity and prevents issues when managing translations, especially as your application grows.

🗂️ Organize Translations by Context

Group related translations together within your files. For example, group all button labels under a buttons key and all form-related texts under a forms key. This not only improves readability but also makes it easier to manage translations across different locales.

🧹 Regularly Clean Up Unused Translations

Over time, your application might accumulate unused translation keys, especially if features are removed or restructured. Periodically review and clean up your translation files to keep them lean and maintainable.

`,49)]))}const g=s(t,[["render",o]]);export{u as __pageData,g as default}; diff --git a/assets/guide_getting-started.md.-u7BlIMn.js b/assets/guide_getting-started.md.-u7BlIMn.js new file mode 100644 index 0000000..5096aea --- /dev/null +++ b/assets/guide_getting-started.md.-u7BlIMn.js @@ -0,0 +1,69 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const c=JSON.parse('{"title":"🌐 Getting Started with Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/getting-started.md","filePath":"guide/getting-started.md","lastUpdated":1729515293000}'),n={name:"guide/getting-started.md"};function l(p,s,h,o,r,d){return t(),a("div",null,s[0]||(s[0]=[e(`

🌐 Getting Started with Nuxt I18n Micro

📖 Overview

Nuxt I18n Micro is a lightweight internationalization module for Nuxt that delivers superior performance compared to traditional solutions. It's designed to reduce build times, memory usage, and server load, making it ideal for high-traffic and large projects.

🤔 Why Choose Nuxt I18n Micro?

Here are some key benefits of using Nuxt I18n Micro:

  • 🚀 High Performance: Significantly reduces build times and memory consumption.
  • 📦 Compact Size: Has minimal impact on your app's bundle size.
  • ⚙️ Efficiency: Optimized for large-scale applications with a focus on memory consumption and server load.

🛠 Installation

To install the module in your Nuxt application, run the following command:

bash
npm install nuxt-i18n-micro

⚙️ Basic Setup

After installation, add the module to your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  modules: [
+    'nuxt-i18n-micro',
+  ],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

📂 Folder Structure

Translation files are organized into global and page-specific directories:

  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json
  • Global Files: Contain translations shared across the entire app.
  • Page-Specific Files: Contain translations unique to specific pages.

⚙️ Module Configuration Options

The Nuxt I18n Micro module provides a range of customizable options to fine-tune your internationalization setup:

🌍 locales

Defines the locales available in your application.

Type: Locale[]

Each locale object includes:

  • code (string, required): A unique identifier for the locale, e.g., 'en' for English.
  • iso (string, optional): The ISO code, e.g., 'en-US', used for the lang attribute in HTML.
  • dir (string, optional): Text direction, either 'rtl' for right-to-left or 'ltr' for left-to-right languages.
  • disabled (boolean, optional): Indicates if the locale should be disabled.

Example:

typescript
locales: [
+  { code: 'en', iso: 'en-US', dir: 'ltr' },
+  { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+  { code: 'ar', iso: 'ar-SA', dir: 'rtl', disabled: false }
+]

🌐 defaultLocale

Sets the default locale if no specific locale is selected by the user.

Type: string

Example:

typescript
defaultLocale: 'en'

🗂 translationDir

Specifies the directory where translation files are stored.

Type: string
Default: 'locales'

Example:

typescript
translationDir: 'i18n' // Custom directory for translation files

🔍 meta

Automatically generates SEO-related meta tags, such as alternate links for different locales.

Type: boolean
Default: true

Example:

typescript
meta: true // Enable automatic SEO meta tags generation

🐛 debug

Enables logging and debugging information during the generation process to help with troubleshooting.

Type: boolean
Default: false

Example:

typescript
debug: true // Enable logging and debugging information

🐛 types

Adds types to the project during the postinstall process. If you encounter issues with types, you can disable this option.

Type: boolean
Default: true

Example:

typescript
types: true

🔗 metaBaseUrl

Sets the base URL for generating SEO-related meta tags like canonical and alternate URLs.

Type: string
Default: '/'

Example:

typescript
metaBaseUrl: 'https://example.com' // Custom base URL for meta tags

🌍 autoDetectLanguage

Automatically detects the user's preferred language based on browser settings and redirects to the appropriate locale.

Type: boolean
Default: false

Example:

typescript
autoDetectLanguage: true // Enable automatic language detection and redirection

🔍 autoDetectPath

Specifies the route path(s) on which the locale auto-detection and switching should occur.

Type: string
Default: "*"

Example:

typescript
autoDetectPath: '/' // Locale detection will only happen on the home route

🔢 plural

Custom function for handling pluralization in translations based on count and locale.

Type: (key: string, translation: unknown, count: number, locale: string) => string

Example:

typescript
export type Getter = (key: string, params?: Record<string, string | number | boolean>, defaultValue?: string) => unknown
+
+{
+  plural: (key: string, count: number, _locale: string, t: Getter) => {
+    const translation = t(key)
+    if (!translation) {
+      return key
+    }
+    const forms = translation.toString().split('|')
+    if (count === 0 && forms.length > 2) {
+      return forms[0].trim() // Case for "no apples"
+    }
+    if (count === 1 && forms.length > 1) {
+      return forms[1].trim() // Case for "one apple"
+    }
+    return (forms.length > 2 ? forms[2].trim() : forms[forms.length - 1].trim()).replace('{count}', count.toString())
+  }
+}

🚦 includeDefaultLocaleRoute

Automatically redirects routes without a locale prefix to the default locale.

Type: boolean
Default: false

Example:

typescript
includeDefaultLocaleRoute: true // Ensure consistency across routes by redirecting to the default locale

🚦 customRegexMatcher

I18n-micro meticulously checks each locale via vue-router route regex. If you have a lot of locales, you can improve pattern matching performances via a custom regex matcher.

Type: string | RegExp
Default: false

Example:

typescript
customRegexMatcher: '[a-z]-[A-Z]'// This matches locales in isoCode (e.g: '/en-US', 'de-DE' etc)

Creates links between different pages' locale files to share translations, reducing duplication.

Type: Record<string, string>

Example:

typescript
routesLocaleLinks: {
+  'products-id': 'products',
+  'about-us': 'about'
+}

🧩 define

Enables or disables the addition of a special define plugin that allows you to use Nuxt's runtime configuration for overriding settings in your translation files.

Type: boolean
Default: true

Example:

typescript
define: false // Disable the define plugin

🔄 disablePageLocales

Allows you to disable page-specific translations, limiting the module to only use global translation files.

Type: boolean
Default: false

Example:

typescript
disablePageLocales: true // Disable page-specific translations, using only global translations

📂 Folder Structure with disablePageLocales: true

When disablePageLocales is enabled, the module will only use the translations defined in the global files located directly under the locales directory. Page-specific translation files (located in /locales/pages) will be ignored.

  /locales
+  ├── en.json
+  ├── fr.json
+  └── ar.json

👀 disableWatcher

Disables the automatic creation of locale files during development.

Type: boolean
Default: false

Example:

typescript
disableWatcher: true // Disables the automatic creation of locale files

🔗 apiBaseUrl

env: NUXT_I18N_APP_BASE_URL

Defines the base URL that the server will use to fetch cached translations. By default, this is set to _locales, but you can change it to any custom path, such as api/_locales, if you want to load translations from a different endpoint.

Type: string
Default: '_locales'

Example:

typescript
apiBaseUrl: 'api/_locales' // Custom URL for fetching cached translations

When set, the module will use the specified URL to request cached translations instead of using the default _locales.

🍪 localeCookie

Specifies the name of the cookie used to store the user's selected locale.

Type: string
Default: 'user-locale'

🌐 fallbackLocale

Specifies a fallback locale to be used when the current locale does not have a specific translation available.

Type: string | undefined
Default: undefined

Example:

typescript
i18n: {
+  locales: [
+    { code: 'en', iso: 'en-US', dir: 'ltr' },
+    { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    { code: 'es', iso: 'es-ES', dir: 'ltr' }
+  ],
+  defaultLocale: 'en',
+  fallbackLocale: 'en', // Use English as a fallback locale
+}

🌐 globalLocaleRoutes

Allows you to define custom localized routes for specific pages. You can specify a custom path for each locale for a given page, or disable localization for certain pages entirely.

Type: Record<string, Record<string, string> | false>

  • Key (string): The name of the page you want to customize or disable localization for.
  • Value:
    • Record<string, string>: A set of locale codes with corresponding custom paths for the page.
    • false: Disable localization for this page entirely. The page will not be localized, and it will remain accessible only through its default path.

This option gives you the flexibility to localize certain pages differently while leaving others unaffected by localization.

Example:

typescript
globalLocaleRoutes: {
+  page2: {
+    en: '/custom-page2-en',
+    de: '/custom-page2-de',
+    ru: '/custom-page2-ru',
+  },
+  unlocalized: false, // Unlocalized page should not be localized
+}

Usage:

In the example above:

  • page2: Custom localized paths are defined for the page page2 in English (en), German (de), and Russian (ru). Instead of following the standard localization pattern (like /en/page2), each locale will have a completely custom URL, such as /en/custom-page2-en for English, /de/custom-page2-de for German, and /ru/custom-page2-ru for Russian.
  • unlocalized: This page will not be localized, so it remains accessible only at /unlocalized, without any locale prefixes or custom paths.

🔄 Caching Mechanism

One of the standout features of Nuxt I18n Micro is its intelligent caching system. When a translation is requested during server-side rendering (SSR), the result is stored in a cache. This means that subsequent requests for the same translation can

retrieve the data from the cache rather than searching through the translation files again. This caching mechanism drastically reduces the time needed to fetch translations and significantly lowers the server's resource consumption.

`,132)]))}const g=i(n,[["render",l]]);export{c as __pageData,g as default}; diff --git a/assets/guide_getting-started.md.-u7BlIMn.lean.js b/assets/guide_getting-started.md.-u7BlIMn.lean.js new file mode 100644 index 0000000..5096aea --- /dev/null +++ b/assets/guide_getting-started.md.-u7BlIMn.lean.js @@ -0,0 +1,69 @@ +import{_ as i,c as a,a2 as e,o as t}from"./chunks/framework.CBrKbnPu.js";const c=JSON.parse('{"title":"🌐 Getting Started with Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/getting-started.md","filePath":"guide/getting-started.md","lastUpdated":1729515293000}'),n={name:"guide/getting-started.md"};function l(p,s,h,o,r,d){return t(),a("div",null,s[0]||(s[0]=[e(`

🌐 Getting Started with Nuxt I18n Micro

📖 Overview

Nuxt I18n Micro is a lightweight internationalization module for Nuxt that delivers superior performance compared to traditional solutions. It's designed to reduce build times, memory usage, and server load, making it ideal for high-traffic and large projects.

🤔 Why Choose Nuxt I18n Micro?

Here are some key benefits of using Nuxt I18n Micro:

  • 🚀 High Performance: Significantly reduces build times and memory consumption.
  • 📦 Compact Size: Has minimal impact on your app's bundle size.
  • ⚙️ Efficiency: Optimized for large-scale applications with a focus on memory consumption and server load.

🛠 Installation

To install the module in your Nuxt application, run the following command:

bash
npm install nuxt-i18n-micro

⚙️ Basic Setup

After installation, add the module to your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  modules: [
+    'nuxt-i18n-micro',
+  ],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

📂 Folder Structure

Translation files are organized into global and page-specific directories:

  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json
  • Global Files: Contain translations shared across the entire app.
  • Page-Specific Files: Contain translations unique to specific pages.

⚙️ Module Configuration Options

The Nuxt I18n Micro module provides a range of customizable options to fine-tune your internationalization setup:

🌍 locales

Defines the locales available in your application.

Type: Locale[]

Each locale object includes:

  • code (string, required): A unique identifier for the locale, e.g., 'en' for English.
  • iso (string, optional): The ISO code, e.g., 'en-US', used for the lang attribute in HTML.
  • dir (string, optional): Text direction, either 'rtl' for right-to-left or 'ltr' for left-to-right languages.
  • disabled (boolean, optional): Indicates if the locale should be disabled.

Example:

typescript
locales: [
+  { code: 'en', iso: 'en-US', dir: 'ltr' },
+  { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+  { code: 'ar', iso: 'ar-SA', dir: 'rtl', disabled: false }
+]

🌐 defaultLocale

Sets the default locale if no specific locale is selected by the user.

Type: string

Example:

typescript
defaultLocale: 'en'

🗂 translationDir

Specifies the directory where translation files are stored.

Type: string
Default: 'locales'

Example:

typescript
translationDir: 'i18n' // Custom directory for translation files

🔍 meta

Automatically generates SEO-related meta tags, such as alternate links for different locales.

Type: boolean
Default: true

Example:

typescript
meta: true // Enable automatic SEO meta tags generation

🐛 debug

Enables logging and debugging information during the generation process to help with troubleshooting.

Type: boolean
Default: false

Example:

typescript
debug: true // Enable logging and debugging information

🐛 types

Adds types to the project during the postinstall process. If you encounter issues with types, you can disable this option.

Type: boolean
Default: true

Example:

typescript
types: true

🔗 metaBaseUrl

Sets the base URL for generating SEO-related meta tags like canonical and alternate URLs.

Type: string
Default: '/'

Example:

typescript
metaBaseUrl: 'https://example.com' // Custom base URL for meta tags

🌍 autoDetectLanguage

Automatically detects the user's preferred language based on browser settings and redirects to the appropriate locale.

Type: boolean
Default: false

Example:

typescript
autoDetectLanguage: true // Enable automatic language detection and redirection

🔍 autoDetectPath

Specifies the route path(s) on which the locale auto-detection and switching should occur.

Type: string
Default: "*"

Example:

typescript
autoDetectPath: '/' // Locale detection will only happen on the home route

🔢 plural

Custom function for handling pluralization in translations based on count and locale.

Type: (key: string, translation: unknown, count: number, locale: string) => string

Example:

typescript
export type Getter = (key: string, params?: Record<string, string | number | boolean>, defaultValue?: string) => unknown
+
+{
+  plural: (key: string, count: number, _locale: string, t: Getter) => {
+    const translation = t(key)
+    if (!translation) {
+      return key
+    }
+    const forms = translation.toString().split('|')
+    if (count === 0 && forms.length > 2) {
+      return forms[0].trim() // Case for "no apples"
+    }
+    if (count === 1 && forms.length > 1) {
+      return forms[1].trim() // Case for "one apple"
+    }
+    return (forms.length > 2 ? forms[2].trim() : forms[forms.length - 1].trim()).replace('{count}', count.toString())
+  }
+}

🚦 includeDefaultLocaleRoute

Automatically redirects routes without a locale prefix to the default locale.

Type: boolean
Default: false

Example:

typescript
includeDefaultLocaleRoute: true // Ensure consistency across routes by redirecting to the default locale

🚦 customRegexMatcher

I18n-micro meticulously checks each locale via vue-router route regex. If you have a lot of locales, you can improve pattern matching performances via a custom regex matcher.

Type: string | RegExp
Default: false

Example:

typescript
customRegexMatcher: '[a-z]-[A-Z]'// This matches locales in isoCode (e.g: '/en-US', 'de-DE' etc)

Creates links between different pages' locale files to share translations, reducing duplication.

Type: Record<string, string>

Example:

typescript
routesLocaleLinks: {
+  'products-id': 'products',
+  'about-us': 'about'
+}

🧩 define

Enables or disables the addition of a special define plugin that allows you to use Nuxt's runtime configuration for overriding settings in your translation files.

Type: boolean
Default: true

Example:

typescript
define: false // Disable the define plugin

🔄 disablePageLocales

Allows you to disable page-specific translations, limiting the module to only use global translation files.

Type: boolean
Default: false

Example:

typescript
disablePageLocales: true // Disable page-specific translations, using only global translations

📂 Folder Structure with disablePageLocales: true

When disablePageLocales is enabled, the module will only use the translations defined in the global files located directly under the locales directory. Page-specific translation files (located in /locales/pages) will be ignored.

  /locales
+  ├── en.json
+  ├── fr.json
+  └── ar.json

👀 disableWatcher

Disables the automatic creation of locale files during development.

Type: boolean
Default: false

Example:

typescript
disableWatcher: true // Disables the automatic creation of locale files

🔗 apiBaseUrl

env: NUXT_I18N_APP_BASE_URL

Defines the base URL that the server will use to fetch cached translations. By default, this is set to _locales, but you can change it to any custom path, such as api/_locales, if you want to load translations from a different endpoint.

Type: string
Default: '_locales'

Example:

typescript
apiBaseUrl: 'api/_locales' // Custom URL for fetching cached translations

When set, the module will use the specified URL to request cached translations instead of using the default _locales.

🍪 localeCookie

Specifies the name of the cookie used to store the user's selected locale.

Type: string
Default: 'user-locale'

🌐 fallbackLocale

Specifies a fallback locale to be used when the current locale does not have a specific translation available.

Type: string | undefined
Default: undefined

Example:

typescript
i18n: {
+  locales: [
+    { code: 'en', iso: 'en-US', dir: 'ltr' },
+    { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    { code: 'es', iso: 'es-ES', dir: 'ltr' }
+  ],
+  defaultLocale: 'en',
+  fallbackLocale: 'en', // Use English as a fallback locale
+}

🌐 globalLocaleRoutes

Allows you to define custom localized routes for specific pages. You can specify a custom path for each locale for a given page, or disable localization for certain pages entirely.

Type: Record<string, Record<string, string> | false>

  • Key (string): The name of the page you want to customize or disable localization for.
  • Value:
    • Record<string, string>: A set of locale codes with corresponding custom paths for the page.
    • false: Disable localization for this page entirely. The page will not be localized, and it will remain accessible only through its default path.

This option gives you the flexibility to localize certain pages differently while leaving others unaffected by localization.

Example:

typescript
globalLocaleRoutes: {
+  page2: {
+    en: '/custom-page2-en',
+    de: '/custom-page2-de',
+    ru: '/custom-page2-ru',
+  },
+  unlocalized: false, // Unlocalized page should not be localized
+}

Usage:

In the example above:

  • page2: Custom localized paths are defined for the page page2 in English (en), German (de), and Russian (ru). Instead of following the standard localization pattern (like /en/page2), each locale will have a completely custom URL, such as /en/custom-page2-en for English, /de/custom-page2-de for German, and /ru/custom-page2-ru for Russian.
  • unlocalized: This page will not be localized, so it remains accessible only at /unlocalized, without any locale prefixes or custom paths.

🔄 Caching Mechanism

One of the standout features of Nuxt I18n Micro is its intelligent caching system. When a translation is requested during server-side rendering (SSR), the result is stored in a cache. This means that subsequent requests for the same translation can

retrieve the data from the cache rather than searching through the translation files again. This caching mechanism drastically reduces the time needed to fetch translations and significantly lowers the server's resource consumption.

`,132)]))}const g=i(n,[["render",l]]);export{c as __pageData,g as default}; diff --git a/assets/guide_layers.md.Dy4zl8SE.js b/assets/guide_layers.md.Dy4zl8SE.js new file mode 100644 index 0000000..5c5d92c --- /dev/null +++ b/assets/guide_layers.md.Dy4zl8SE.js @@ -0,0 +1,72 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const o=JSON.parse('{"title":"🗂️ Layers in Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/layers.md","filePath":"guide/layers.md","lastUpdated":1724243643000}'),e={name:"guide/layers.md"};function l(h,s,p,k,r,E){return t(),a("div",null,s[0]||(s[0]=[n(`

🗂️ Layers in Nuxt I18n Micro

📖 Introduction to Layers

Layers in Nuxt I18n Micro allow you to manage and customize localization settings flexibly across different parts of your application. By defining different layers, you can adjust the configuration for various contexts, such as overriding settings for specific sections of your site or creating reusable base configurations that can be extended by other parts of your application.

🛠️ Primary Configuration Layer

The Primary Configuration Layer is where you set up the default localization settings for your entire application. This layer is essential as it defines the global configuration, including the supported locales, default language, and other critical i18n settings.

📄 Example: Defining the Primary Configuration Layer

Here’s an example of how you might define the primary configuration layer in your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en', // The default locale for the entire app
+    translationDir: 'locales', // Directory where translations are stored
+    meta: true, // Automatically generate SEO-related meta tags like \`alternate\`
+    autoDetectLanguage: true, // Automatically detect and use the user's preferred language
+  },
+})

🌱 Child Layers

Child layers are used to extend or override the primary configuration for specific parts of your application. For instance, you might want to add additional locales or modify the default locale for a particular section of your site. Child layers are especially useful in modular applications where different parts of the application might have different localization requirements.

📄 Example: Extending the Primary Layer in a Child Layer

Suppose you have a section of your site that needs to support additional locales, or you want to disable a particular locale in a certain context. Here’s how you can achieve that by extending the primary configuration layer:

typescript
// basic/nuxt.config.ts (Primary Layer)
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    meta: true,
+    translationDir: 'locales',
+  },
+})
typescript
// extended/nuxt.config.ts (Child Layer)
+export default defineNuxtConfig({
+  extends: '../basic', // Inherit the base configuration from the 'basic' layer
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited from the base layer
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited from the base layer
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Added in the child layer
+    ],
+    defaultLocale: 'fr', // Override the default locale to French for this section
+    autoDetectLanguage: false, // Disable automatic language detection in this section
+  },
+})

🌐 Using Layers in a Modular Application

In a larger, modular Nuxt application, you might have multiple sections, each requiring its own i18n settings. By leveraging layers, you can maintain a clean and scalable configuration structure.

📄 Example: Layered Configuration in a Modular Application

Imagine you have an e-commerce site with distinct sections like the main website, admin panel, and customer support portal. Each section might need a different set of locales or other i18n settings.

Primary Layer (Global Configuration):

typescript
// nuxt.config.ts
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    meta: true,
+    translationDir: 'locales',
+    autoDetectLanguage: true,
+  },
+})

Child Layer for Admin Panel:

typescript
// admin/nuxt.config.ts
+export default defineNuxtConfig({
+  extends: '../nuxt.config', // Inherit the global settings
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited
+      { code: 'es', iso: 'es-ES', dir: 'ltr' }, // Specific to the admin panel
+    ],
+    defaultLocale: 'en',
+    meta: false, // Disable automatic meta generation in the admin panel
+  },
+})

Child Layer for Customer Support Portal:

typescript
// support/nuxt.config.ts
+export default defineNuxtConfig({
+  extends: '../nuxt.config', // Inherit the global settings
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Specific to the support portal
+    ],
+    defaultLocale: 'de', // Default to German in the support portal
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

In this modular example:

  • Each section (admin, support) has its own i18n settings, but they all inherit the base configuration.
  • The admin panel adds Spanish (es) as a locale and disables meta tag generation.
  • The support portal adds German (de) as a locale and defaults to German for the user interface.

📝 Best Practices for Using Layers

  • 🔧 Keep the Primary Layer Simple: The primary layer should contain the most commonly used settings that apply globally across your application. Keep it straightforward to ensure consistency.
  • ⚙️ Use Child Layers for Specific Customizations: Only override or extend settings in child layers when necessary. This approach avoids unnecessary complexity in your configuration.
  • 📚 Document Your Layers: Clearly document the purpose and specifics of each layer in your project. This will help maintain clarity and make it easier for others (or future you) to understand the configuration.
`,28)]))}const y=i(e,[["render",l]]);export{o as __pageData,y as default}; diff --git a/assets/guide_layers.md.Dy4zl8SE.lean.js b/assets/guide_layers.md.Dy4zl8SE.lean.js new file mode 100644 index 0000000..5c5d92c --- /dev/null +++ b/assets/guide_layers.md.Dy4zl8SE.lean.js @@ -0,0 +1,72 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const o=JSON.parse('{"title":"🗂️ Layers in Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/layers.md","filePath":"guide/layers.md","lastUpdated":1724243643000}'),e={name:"guide/layers.md"};function l(h,s,p,k,r,E){return t(),a("div",null,s[0]||(s[0]=[n(`

🗂️ Layers in Nuxt I18n Micro

📖 Introduction to Layers

Layers in Nuxt I18n Micro allow you to manage and customize localization settings flexibly across different parts of your application. By defining different layers, you can adjust the configuration for various contexts, such as overriding settings for specific sections of your site or creating reusable base configurations that can be extended by other parts of your application.

🛠️ Primary Configuration Layer

The Primary Configuration Layer is where you set up the default localization settings for your entire application. This layer is essential as it defines the global configuration, including the supported locales, default language, and other critical i18n settings.

📄 Example: Defining the Primary Configuration Layer

Here’s an example of how you might define the primary configuration layer in your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en', // The default locale for the entire app
+    translationDir: 'locales', // Directory where translations are stored
+    meta: true, // Automatically generate SEO-related meta tags like \`alternate\`
+    autoDetectLanguage: true, // Automatically detect and use the user's preferred language
+  },
+})

🌱 Child Layers

Child layers are used to extend or override the primary configuration for specific parts of your application. For instance, you might want to add additional locales or modify the default locale for a particular section of your site. Child layers are especially useful in modular applications where different parts of the application might have different localization requirements.

📄 Example: Extending the Primary Layer in a Child Layer

Suppose you have a section of your site that needs to support additional locales, or you want to disable a particular locale in a certain context. Here’s how you can achieve that by extending the primary configuration layer:

typescript
// basic/nuxt.config.ts (Primary Layer)
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    meta: true,
+    translationDir: 'locales',
+  },
+})
typescript
// extended/nuxt.config.ts (Child Layer)
+export default defineNuxtConfig({
+  extends: '../basic', // Inherit the base configuration from the 'basic' layer
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited from the base layer
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited from the base layer
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Added in the child layer
+    ],
+    defaultLocale: 'fr', // Override the default locale to French for this section
+    autoDetectLanguage: false, // Disable automatic language detection in this section
+  },
+})

🌐 Using Layers in a Modular Application

In a larger, modular Nuxt application, you might have multiple sections, each requiring its own i18n settings. By leveraging layers, you can maintain a clean and scalable configuration structure.

📄 Example: Layered Configuration in a Modular Application

Imagine you have an e-commerce site with distinct sections like the main website, admin panel, and customer support portal. Each section might need a different set of locales or other i18n settings.

Primary Layer (Global Configuration):

typescript
// nuxt.config.ts
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    meta: true,
+    translationDir: 'locales',
+    autoDetectLanguage: true,
+  },
+})

Child Layer for Admin Panel:

typescript
// admin/nuxt.config.ts
+export default defineNuxtConfig({
+  extends: '../nuxt.config', // Inherit the global settings
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited
+      { code: 'es', iso: 'es-ES', dir: 'ltr' }, // Specific to the admin panel
+    ],
+    defaultLocale: 'en',
+    meta: false, // Disable automatic meta generation in the admin panel
+  },
+})

Child Layer for Customer Support Portal:

typescript
// support/nuxt.config.ts
+export default defineNuxtConfig({
+  extends: '../nuxt.config', // Inherit the global settings
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Specific to the support portal
+    ],
+    defaultLocale: 'de', // Default to German in the support portal
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

In this modular example:

  • Each section (admin, support) has its own i18n settings, but they all inherit the base configuration.
  • The admin panel adds Spanish (es) as a locale and disables meta tag generation.
  • The support portal adds German (de) as a locale and defaults to German for the user interface.

📝 Best Practices for Using Layers

  • 🔧 Keep the Primary Layer Simple: The primary layer should contain the most commonly used settings that apply globally across your application. Keep it straightforward to ensure consistency.
  • ⚙️ Use Child Layers for Specific Customizations: Only override or extend settings in child layers when necessary. This approach avoids unnecessary complexity in your configuration.
  • 📚 Document Your Layers: Clearly document the purpose and specifics of each layer in your project. This will help maintain clarity and make it easier for others (or future you) to understand the configuration.
`,28)]))}const y=i(e,[["render",l]]);export{o as __pageData,y as default}; diff --git a/assets/guide_migration.md.CUupWGuG.js b/assets/guide_migration.md.CUupWGuG.js new file mode 100644 index 0000000..49177b9 --- /dev/null +++ b/assets/guide_migration.md.CUupWGuG.js @@ -0,0 +1,36 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const c=JSON.parse('{"title":"🔄 Migration from nuxt-i18n to Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/migration.md","filePath":"guide/migration.md","lastUpdated":1724265480000}'),e={name:"guide/migration.md"};function l(o,s,h,p,r,d){return t(),a("div",null,s[0]||(s[0]=[n(`

🔄 Migration from nuxt-i18n to Nuxt I18n Micro

📖 Introduction

Migrating from nuxt-i18n to Nuxt I18n Micro can significantly improve the performance of your Nuxt application, especially in high-traffic environments or projects with large translation files. This guide provides a step-by-step approach to help you smoothly transition from nuxt-i18n to Nuxt I18n Micro.

🚀 Why Migrate?

The Nuxt I18n Micro module offers several advantages over the traditional nuxt-i18n:

  • ⚡ Improved Performance: Faster build times, lower memory usage, and smaller bundle sizes.
  • 🔧 Simplified Configuration: A more streamlined setup process with fewer moving parts.
  • 📉 Better Resource Management: Optimized handling of large translation files and reduced server load.

🔍 Key Differences

Before you begin the migration process, it’s essential to understand the key differences between nuxt-i18n and Nuxt I18n Micro:

  • 🌐 Route Management: Nuxt I18n Micro uses dynamic regex-based routing, generating only two routes regardless of the number of locales, unlike nuxt-i18n which creates a separate route for each locale.
  • 🗂️ Translation Files: Only JSON files are supported in Nuxt I18n Micro. The translations are split into global and page-specific files, which are auto-generated in development mode if not present.
  • 📈 SEO Integration: Nuxt I18n Micro offers built-in SEO optimization with automatic meta tag generation and support for hreflang tags.

🛠️ Step-by-Step Migration

1. 🛠️ Install Nuxt I18n Micro

First, add Nuxt I18n Micro to your Nuxt project:

bash
npm install nuxt-i18n-micro

2. 🔄 Update Configuration

Replace your existing nuxt-i18n configuration in nuxt.config.ts with the Nuxt I18n Micro configuration. Here’s an example:

Before (nuxt-i18n):

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US' },
+      { code: 'fr', iso: 'fr-FR' },
+    ],
+    defaultLocale: 'en',
+    vueI18n: './i18n.config.js',
+  },
+})

After (Nuxt I18n Micro):

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

3. 🗂️ Reorganize Translation Files

Move your translation files to the locales directory. Ensure they are in JSON format and organized by locale. For example:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json

If you are using <nuxt-link> for navigation, replace it with <NuxtLink> to ensure compatibility with the new module.

Before:

vue
<nuxt-link :to="{ name: 'index' }">Home</nuxt-link>

After:

vue
<NuxtLink :to="$localeRoute({ name: 'index' })">Home</NuxtLink>
+<!-- or -->
+<i18n-link :to="{ name: 'index' }">Home</i18n-link>

5. 🛠️ Handle SEO Configurations

Ensure that your SEO configurations are updated to take advantage of Nuxt I18n Micro’s automatic meta tag generation. Remove any redundant SEO configurations that were specific to nuxt-i18n.

6. 🧪 Test Your Application

After completing the migration steps, thoroughly test your application to ensure that all translations are loading correctly and that navigation between locales works as expected. Pay special attention to SEO-related tags and ensure that they are generated as intended.

🛡️ Common Issues and Troubleshooting

❌ Translation Files Not Loading

Ensure that your translation files are in the correct directory and follow the JSON format. Also, confirm that the translationDir option in your configuration matches the location of your translation files.

⚠️ Route Not Found Errors

Check that the routes are correctly set up in your application and that the locales array in the configuration includes all necessary locale codes.

🏷️ Missing SEO Tags

If SEO tags are not being generated, verify that the meta option is enabled in your configuration and that each locale has a valid iso code.

`,39)]))}const E=i(e,[["render",l]]);export{c as __pageData,E as default}; diff --git a/assets/guide_migration.md.CUupWGuG.lean.js b/assets/guide_migration.md.CUupWGuG.lean.js new file mode 100644 index 0000000..49177b9 --- /dev/null +++ b/assets/guide_migration.md.CUupWGuG.lean.js @@ -0,0 +1,36 @@ +import{_ as i,c as a,a2 as n,o as t}from"./chunks/framework.CBrKbnPu.js";const c=JSON.parse('{"title":"🔄 Migration from nuxt-i18n to Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/migration.md","filePath":"guide/migration.md","lastUpdated":1724265480000}'),e={name:"guide/migration.md"};function l(o,s,h,p,r,d){return t(),a("div",null,s[0]||(s[0]=[n(`

🔄 Migration from nuxt-i18n to Nuxt I18n Micro

📖 Introduction

Migrating from nuxt-i18n to Nuxt I18n Micro can significantly improve the performance of your Nuxt application, especially in high-traffic environments or projects with large translation files. This guide provides a step-by-step approach to help you smoothly transition from nuxt-i18n to Nuxt I18n Micro.

🚀 Why Migrate?

The Nuxt I18n Micro module offers several advantages over the traditional nuxt-i18n:

  • ⚡ Improved Performance: Faster build times, lower memory usage, and smaller bundle sizes.
  • 🔧 Simplified Configuration: A more streamlined setup process with fewer moving parts.
  • 📉 Better Resource Management: Optimized handling of large translation files and reduced server load.

🔍 Key Differences

Before you begin the migration process, it’s essential to understand the key differences between nuxt-i18n and Nuxt I18n Micro:

  • 🌐 Route Management: Nuxt I18n Micro uses dynamic regex-based routing, generating only two routes regardless of the number of locales, unlike nuxt-i18n which creates a separate route for each locale.
  • 🗂️ Translation Files: Only JSON files are supported in Nuxt I18n Micro. The translations are split into global and page-specific files, which are auto-generated in development mode if not present.
  • 📈 SEO Integration: Nuxt I18n Micro offers built-in SEO optimization with automatic meta tag generation and support for hreflang tags.

🛠️ Step-by-Step Migration

1. 🛠️ Install Nuxt I18n Micro

First, add Nuxt I18n Micro to your Nuxt project:

bash
npm install nuxt-i18n-micro

2. 🔄 Update Configuration

Replace your existing nuxt-i18n configuration in nuxt.config.ts with the Nuxt I18n Micro configuration. Here’s an example:

Before (nuxt-i18n):

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US' },
+      { code: 'fr', iso: 'fr-FR' },
+    ],
+    defaultLocale: 'en',
+    vueI18n: './i18n.config.js',
+  },
+})

After (Nuxt I18n Micro):

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

3. 🗂️ Reorganize Translation Files

Move your translation files to the locales directory. Ensure they are in JSON format and organized by locale. For example:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json

If you are using <nuxt-link> for navigation, replace it with <NuxtLink> to ensure compatibility with the new module.

Before:

vue
<nuxt-link :to="{ name: 'index' }">Home</nuxt-link>

After:

vue
<NuxtLink :to="$localeRoute({ name: 'index' })">Home</NuxtLink>
+<!-- or -->
+<i18n-link :to="{ name: 'index' }">Home</i18n-link>

5. 🛠️ Handle SEO Configurations

Ensure that your SEO configurations are updated to take advantage of Nuxt I18n Micro’s automatic meta tag generation. Remove any redundant SEO configurations that were specific to nuxt-i18n.

6. 🧪 Test Your Application

After completing the migration steps, thoroughly test your application to ensure that all translations are loading correctly and that navigation between locales works as expected. Pay special attention to SEO-related tags and ensure that they are generated as intended.

🛡️ Common Issues and Troubleshooting

❌ Translation Files Not Loading

Ensure that your translation files are in the correct directory and follow the JSON format. Also, confirm that the translationDir option in your configuration matches the location of your translation files.

⚠️ Route Not Found Errors

Check that the routes are correctly set up in your application and that the locales array in the configuration includes all necessary locale codes.

🏷️ Missing SEO Tags

If SEO tags are not being generated, verify that the meta option is enabled in your configuration and that each locale has a valid iso code.

`,39)]))}const E=i(e,[["render",l]]);export{c as __pageData,E as default}; diff --git a/assets/guide_multi-domain-locales.md.BMPCs2fg.js b/assets/guide_multi-domain-locales.md.BMPCs2fg.js new file mode 100644 index 0000000..391cb58 --- /dev/null +++ b/assets/guide_multi-domain-locales.md.BMPCs2fg.js @@ -0,0 +1,45 @@ +import{_ as s,c as a,a2 as n,o as e}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/multi-domain-locales.md","filePath":"guide/multi-domain-locales.md","lastUpdated":1724309370000}'),t={name:"guide/multi-domain-locales.md"};function l(h,i,p,r,o,k){return e(),a("div",null,i[0]||(i[0]=[n(`

🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers

📝 Introduction

By leveraging layers in Nuxt I18n Micro, you can create a flexible and maintainable multi-domain localization setup. This approach not only simplifies domain management by eliminating the need for complex functionalities but also allows for efficient load distribution and reduced project complexity. By running separate projects for different locales, your application can easily scale and adapt to varying locale requirements across multiple domains, offering a robust and scalable solution for global applications.

🎯 Objective

To create a setup where different domains serve specific locales by customizing configurations in child layers. This method leverages Nuxt's layering system, allowing you to maintain a base configuration while extending or modifying it for each domain.

🛠 Steps to Implement Multi-Domain Locales

1. Create the Base Layer

Start by creating a base configuration layer that includes all the common locale settings for your application. This configuration will serve as the foundation for other domain-specific configurations.

Base Layer Configuration

Create the base configuration file base/nuxt.config.ts:

typescript
// base/nuxt.config.ts
+
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'de', iso: 'de-DE', dir: 'ltr' },
+      { code: 'es', iso: 'es-ES', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+    autoDetectLanguage: true,
+  },
+})

2. Create Domain-Specific Child Layers

For each domain, create a child layer that modifies the base configuration to meet the specific requirements of that domain. You can disable locales that are not needed for a specific domain.

Example: Configuration for the French Domain

Create a child layer configuration for the French domain in fr/nuxt.config.ts:

typescript
// fr/nuxt.config.ts
+
+export default defineNuxtConfig({
+  extends: '../base', // Inherit from the base configuration
+
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: true }, // Disable English
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Add and enable the French locale
+      { code: 'de', iso: 'de-DE', dir: 'ltr', disabled: true }, // Disable German
+      { code: 'es', iso: 'es-ES', dir: 'ltr', disabled: true }, // Disable Spanish
+    ],
+    defaultLocale: 'fr', // Set French as the default locale
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

Example: Configuration for the German Domain

Similarly, create a child layer configuration for the German domain in de/nuxt.config.ts:

typescript
// de/nuxt.config.ts
+
+export default defineNuxtConfig({
+  extends: '../base', // Inherit from the base configuration
+
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: true }, // Disable English
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr', disabled: true }, // Disable French
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Use the German locale
+      { code: 'es', iso: 'es-ES', dir: 'ltr', disabled: true }, // Disable Spanish
+    ],
+    defaultLocale: 'de', // Set German as the default locale
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

3. Deploy the Application for Each Domain

Deploy the application with the appropriate configuration for each domain. For example:

  • Deploy the fr layer configuration to fr.example.com.
  • Deploy the de layer configuration to de.example.com.

4. Set Up Multiple Projects for Different Locales

For each locale and domain, you'll need to run a separate instance of the application. This ensures that each domain serves the correct locale configuration, optimizing the load distribution and simplifying the project's structure. By running multiple projects tailored to each locale, you can maintain a clean separation between configurations and reduce the complexity of the overall setup.

5. Configure Routing Based on Domain

Ensure that your routing is configured to direct users to the correct project based on the domain they are accessing. This will ensure that each domain serves the appropriate locale, enhancing user experience and maintaining consistency across different regions.

6. Deploy and Verify

After configuring the layers and deploying them to their respective domains, ensure each domain is serving the correct locale. Test the application thoroughly to confirm that the correct locale is loaded depending on the domain.

📝 Best Practices

  • Keep Base Configuration Generic: The base configuration should cover general settings applicable to all domains.
  • Isolate Domain-Specific Logic: Keep domain-specific configurations in their respective layers to maintain clarity and separation of concerns.

🎉 Conclusion

By leveraging layers in Nuxt I18n Micro, you can create a flexible and maintainable multi-domain localization setup. This approach not only eliminates the need for complex domain management functionalities but also allows you to distribute the load efficiently and reduce project complexity. Running separate projects for different locales ensures that your application can scale easily and adapt to different locale requirements across various domains, providing a robust and scalable solution for global applications.

`,32)]))}const c=s(t,[["render",l]]);export{E as __pageData,c as default}; diff --git a/assets/guide_multi-domain-locales.md.BMPCs2fg.lean.js b/assets/guide_multi-domain-locales.md.BMPCs2fg.lean.js new file mode 100644 index 0000000..391cb58 --- /dev/null +++ b/assets/guide_multi-domain-locales.md.BMPCs2fg.lean.js @@ -0,0 +1,45 @@ +import{_ as s,c as a,a2 as n,o as e}from"./chunks/framework.CBrKbnPu.js";const E=JSON.parse('{"title":"🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/multi-domain-locales.md","filePath":"guide/multi-domain-locales.md","lastUpdated":1724309370000}'),t={name:"guide/multi-domain-locales.md"};function l(h,i,p,r,o,k){return e(),a("div",null,i[0]||(i[0]=[n(`

🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers

📝 Introduction

By leveraging layers in Nuxt I18n Micro, you can create a flexible and maintainable multi-domain localization setup. This approach not only simplifies domain management by eliminating the need for complex functionalities but also allows for efficient load distribution and reduced project complexity. By running separate projects for different locales, your application can easily scale and adapt to varying locale requirements across multiple domains, offering a robust and scalable solution for global applications.

🎯 Objective

To create a setup where different domains serve specific locales by customizing configurations in child layers. This method leverages Nuxt's layering system, allowing you to maintain a base configuration while extending or modifying it for each domain.

🛠 Steps to Implement Multi-Domain Locales

1. Create the Base Layer

Start by creating a base configuration layer that includes all the common locale settings for your application. This configuration will serve as the foundation for other domain-specific configurations.

Base Layer Configuration

Create the base configuration file base/nuxt.config.ts:

typescript
// base/nuxt.config.ts
+
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'de', iso: 'de-DE', dir: 'ltr' },
+      { code: 'es', iso: 'es-ES', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+    autoDetectLanguage: true,
+  },
+})

2. Create Domain-Specific Child Layers

For each domain, create a child layer that modifies the base configuration to meet the specific requirements of that domain. You can disable locales that are not needed for a specific domain.

Example: Configuration for the French Domain

Create a child layer configuration for the French domain in fr/nuxt.config.ts:

typescript
// fr/nuxt.config.ts
+
+export default defineNuxtConfig({
+  extends: '../base', // Inherit from the base configuration
+
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: true }, // Disable English
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Add and enable the French locale
+      { code: 'de', iso: 'de-DE', dir: 'ltr', disabled: true }, // Disable German
+      { code: 'es', iso: 'es-ES', dir: 'ltr', disabled: true }, // Disable Spanish
+    ],
+    defaultLocale: 'fr', // Set French as the default locale
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

Example: Configuration for the German Domain

Similarly, create a child layer configuration for the German domain in de/nuxt.config.ts:

typescript
// de/nuxt.config.ts
+
+export default defineNuxtConfig({
+  extends: '../base', // Inherit from the base configuration
+
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: true }, // Disable English
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr', disabled: true }, // Disable French
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Use the German locale
+      { code: 'es', iso: 'es-ES', dir: 'ltr', disabled: true }, // Disable Spanish
+    ],
+    defaultLocale: 'de', // Set German as the default locale
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

3. Deploy the Application for Each Domain

Deploy the application with the appropriate configuration for each domain. For example:

  • Deploy the fr layer configuration to fr.example.com.
  • Deploy the de layer configuration to de.example.com.

4. Set Up Multiple Projects for Different Locales

For each locale and domain, you'll need to run a separate instance of the application. This ensures that each domain serves the correct locale configuration, optimizing the load distribution and simplifying the project's structure. By running multiple projects tailored to each locale, you can maintain a clean separation between configurations and reduce the complexity of the overall setup.

5. Configure Routing Based on Domain

Ensure that your routing is configured to direct users to the correct project based on the domain they are accessing. This will ensure that each domain serves the appropriate locale, enhancing user experience and maintaining consistency across different regions.

6. Deploy and Verify

After configuring the layers and deploying them to their respective domains, ensure each domain is serving the correct locale. Test the application thoroughly to confirm that the correct locale is loaded depending on the domain.

📝 Best Practices

  • Keep Base Configuration Generic: The base configuration should cover general settings applicable to all domains.
  • Isolate Domain-Specific Logic: Keep domain-specific configurations in their respective layers to maintain clarity and separation of concerns.

🎉 Conclusion

By leveraging layers in Nuxt I18n Micro, you can create a flexible and maintainable multi-domain localization setup. This approach not only eliminates the need for complex domain management functionalities but also allows you to distribute the load efficiently and reduce project complexity. Running separate projects for different locales ensures that your application can scale easily and adapt to different locale requirements across various domains, providing a robust and scalable solution for global applications.

`,32)]))}const c=s(t,[["render",l]]);export{E as __pageData,c as default}; diff --git a/assets/guide_per-component-translations.md.DC4w94aF.js b/assets/guide_per-component-translations.md.DC4w94aF.js new file mode 100644 index 0000000..3896ec7 --- /dev/null +++ b/assets/guide_per-component-translations.md.DC4w94aF.js @@ -0,0 +1,56 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"📖 Per-Component Translations in Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/per-component-translations.md","filePath":"guide/per-component-translations.md","lastUpdated":1726216827000}'),t={name:"guide/per-component-translations.md"};function l(h,s,p,r,k,o){return e(),a("div",null,s[0]||(s[0]=[n(`

📖 Per-Component Translations in Nuxt I18n Micro

Overview

Per-Component Translations in Nuxt I18n Micro allows developers to define translations directly within specific components or pages of a Nuxt application using the $defineI18nRoute function. This approach is ideal for managing localized content that is unique to individual components, providing a more modular and maintainable method for handling translations.

$defineI18nRoute Function

The $defineI18nRoute function configures route behavior based on the current locale, offering a versatile solution to:

  • Control access to specific routes based on available locales.
  • Provide translations for specific locales.
  • Set custom routes for different locales.

Method Signature

typescript
$defineI18nRoute(routeDefinition: { 
+  locales?: string[] | Record<string, Record<string, TranslationObject>>, 
+  localeRoutes?: Record<string, string> 
+})

Parameters

  • locales: Defines which locales are available for the route. This can be:

    • An array of strings, where each string is an available locale (e.g., ['en', 'fr', 'de']).
    • An object where each key is a locale code, and the value is an object containing translations or an empty object if no translations are needed.
  • localeRoutes: Allows custom routes for specific locales. Each key represents a locale code, and the value is the custom route path for that locale. This is useful for scenarios where different locales require unique routing.

Example Usage

typescript
$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+    de: { greeting: 'Hallo', farewell: 'Auf Wiedersehen' },
+  },
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for the Russian locale
+  },
+})

Use Cases

  1. Controlling Access Based on Locales: Define which locales are allowed for specific routes to ensure users only see content relevant to their language.

    typescript
    import { useNuxtApp } from '#imports'
    +
    +const { $defineI18nRoute } = useNuxtApp()
    +
    +$defineI18nRoute({
    +  locales: ['en', 'fr', 'de'] // Only these locales are allowed for this route
    +})
  2. Providing Translations for Locales: Use the locales object to provide specific translations for each route, enhancing the user experience by delivering content in the user's preferred language.

    typescript
    import { useNuxtApp } from '#imports'
    +
    +const { $defineI18nRoute } = useNuxtApp()
    +
    +$defineI18nRoute({
    +  locales: {
    +    en: { greeting: 'Hello', farewell: 'Goodbye' },
    +    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
    +    de: { greeting: 'Hallo', farewell: { aaa: { bbb: "Auf Wiedersehen" } } },
    +    ru: {} // Russian locale is allowed but no translations are provided
    +  }
    +})
  3. Custom Routing for Locales: Define custom paths for specific locales using the localeRoutes property. This allows you to create unique navigational flows or URL structures for different languages or regions.

Best Practices

  • Keep Translations Close to Components: Define translations directly within the relevant component to keep localized content organized and maintainable.
  • Use Locale Objects for Flexibility: Utilize the object format for the locales property when specific translations or access control based on locales are required.
  • Document Custom Routes: Clearly document any custom routes set for different locales to maintain clarity and simplify development and maintenance.

Here's an example of a Vue page using defineI18nRoute for per-component translations:

Example: Vue Page with Per-Component Translations

Below is an example of how to use $defineI18nRoute within a Vue component to handle translations and custom routing based on locale.

vue
<template>
+  <div>
+    <h1>{{ t('greeting') }}</h1>
+    <p>{{ t('farewell') }}</p>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useNuxtApp } from '#imports'
+
+// Access the $defineI18nRoute function from Nuxt's context
+const { $defineI18nRoute, $t: t } = useNuxtApp()
+
+// Define i18n route with translations for specific locales
+$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
+    de: { greeting: 'Hallo', farewell: 'Auf Wiedersehen' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+  },
+  localeRoutes: {
+    ru: '/ru-specific-path', // Custom route path for the Russian locale
+    fr: '/fr-specific-path'  // Custom route path for the French locale
+  }
+})
+</script>

Explanation

  • Component-Level Translations: The translations are defined directly in the component using the locales property of $defineI18nRoute. This keeps translations closely tied to the component, making them easy to manage and update.
  • Custom Routing: The localeRoutes property is used to set specific paths for different locales. This allows for unique navigational flows based on the user's language preference.

This setup enables the component to display localized greetings and farewells based on the current locale, and it also allows for custom routes tailored to specific locales, enhancing the user experience by delivering content in the preferred language and structure.

Summary

The Per-Component Translations feature, powered by the $defineI18nRoute function, offers a powerful and flexible way to manage localization within your Nuxt application. By allowing localized content and routing to be defined at the component level, it helps create a highly customized and user-friendly experience tailored to the language and regional preferences of your audience.

`,25)]))}const c=i(t,[["render",l]]);export{d as __pageData,c as default}; diff --git a/assets/guide_per-component-translations.md.DC4w94aF.lean.js b/assets/guide_per-component-translations.md.DC4w94aF.lean.js new file mode 100644 index 0000000..3896ec7 --- /dev/null +++ b/assets/guide_per-component-translations.md.DC4w94aF.lean.js @@ -0,0 +1,56 @@ +import{_ as i,c as a,a2 as n,o as e}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"📖 Per-Component Translations in Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/per-component-translations.md","filePath":"guide/per-component-translations.md","lastUpdated":1726216827000}'),t={name:"guide/per-component-translations.md"};function l(h,s,p,r,k,o){return e(),a("div",null,s[0]||(s[0]=[n(`

📖 Per-Component Translations in Nuxt I18n Micro

Overview

Per-Component Translations in Nuxt I18n Micro allows developers to define translations directly within specific components or pages of a Nuxt application using the $defineI18nRoute function. This approach is ideal for managing localized content that is unique to individual components, providing a more modular and maintainable method for handling translations.

$defineI18nRoute Function

The $defineI18nRoute function configures route behavior based on the current locale, offering a versatile solution to:

  • Control access to specific routes based on available locales.
  • Provide translations for specific locales.
  • Set custom routes for different locales.

Method Signature

typescript
$defineI18nRoute(routeDefinition: { 
+  locales?: string[] | Record<string, Record<string, TranslationObject>>, 
+  localeRoutes?: Record<string, string> 
+})

Parameters

  • locales: Defines which locales are available for the route. This can be:

    • An array of strings, where each string is an available locale (e.g., ['en', 'fr', 'de']).
    • An object where each key is a locale code, and the value is an object containing translations or an empty object if no translations are needed.
  • localeRoutes: Allows custom routes for specific locales. Each key represents a locale code, and the value is the custom route path for that locale. This is useful for scenarios where different locales require unique routing.

Example Usage

typescript
$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+    de: { greeting: 'Hallo', farewell: 'Auf Wiedersehen' },
+  },
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for the Russian locale
+  },
+})

Use Cases

  1. Controlling Access Based on Locales: Define which locales are allowed for specific routes to ensure users only see content relevant to their language.

    typescript
    import { useNuxtApp } from '#imports'
    +
    +const { $defineI18nRoute } = useNuxtApp()
    +
    +$defineI18nRoute({
    +  locales: ['en', 'fr', 'de'] // Only these locales are allowed for this route
    +})
  2. Providing Translations for Locales: Use the locales object to provide specific translations for each route, enhancing the user experience by delivering content in the user's preferred language.

    typescript
    import { useNuxtApp } from '#imports'
    +
    +const { $defineI18nRoute } = useNuxtApp()
    +
    +$defineI18nRoute({
    +  locales: {
    +    en: { greeting: 'Hello', farewell: 'Goodbye' },
    +    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
    +    de: { greeting: 'Hallo', farewell: { aaa: { bbb: "Auf Wiedersehen" } } },
    +    ru: {} // Russian locale is allowed but no translations are provided
    +  }
    +})
  3. Custom Routing for Locales: Define custom paths for specific locales using the localeRoutes property. This allows you to create unique navigational flows or URL structures for different languages or regions.

Best Practices

  • Keep Translations Close to Components: Define translations directly within the relevant component to keep localized content organized and maintainable.
  • Use Locale Objects for Flexibility: Utilize the object format for the locales property when specific translations or access control based on locales are required.
  • Document Custom Routes: Clearly document any custom routes set for different locales to maintain clarity and simplify development and maintenance.

Here's an example of a Vue page using defineI18nRoute for per-component translations:

Example: Vue Page with Per-Component Translations

Below is an example of how to use $defineI18nRoute within a Vue component to handle translations and custom routing based on locale.

vue
<template>
+  <div>
+    <h1>{{ t('greeting') }}</h1>
+    <p>{{ t('farewell') }}</p>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useNuxtApp } from '#imports'
+
+// Access the $defineI18nRoute function from Nuxt's context
+const { $defineI18nRoute, $t: t } = useNuxtApp()
+
+// Define i18n route with translations for specific locales
+$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
+    de: { greeting: 'Hallo', farewell: 'Auf Wiedersehen' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+  },
+  localeRoutes: {
+    ru: '/ru-specific-path', // Custom route path for the Russian locale
+    fr: '/fr-specific-path'  // Custom route path for the French locale
+  }
+})
+</script>

Explanation

  • Component-Level Translations: The translations are defined directly in the component using the locales property of $defineI18nRoute. This keeps translations closely tied to the component, making them easy to manage and update.
  • Custom Routing: The localeRoutes property is used to set specific paths for different locales. This allows for unique navigational flows based on the user's language preference.

This setup enables the component to display localized greetings and farewells based on the current locale, and it also allows for custom routes tailored to specific locales, enhancing the user experience by delivering content in the preferred language and structure.

Summary

The Per-Component Translations feature, powered by the $defineI18nRoute function, offers a powerful and flexible way to manage localization within your Nuxt application. By allowing localized content and routing to be defined at the component level, it helps create a highly customized and user-friendly experience tailored to the language and regional preferences of your audience.

`,25)]))}const c=i(t,[["render",l]]);export{d as __pageData,c as default}; diff --git a/assets/guide_performance-results.md.BbKR1XsP.js b/assets/guide_performance-results.md.BbKR1XsP.js new file mode 100644 index 0000000..1d5c8ff --- /dev/null +++ b/assets/guide_performance-results.md.BbKR1XsP.js @@ -0,0 +1 @@ +import{_ as r,c as t,a2 as s,o as i}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"Performance Test Results","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/performance-results.md","filePath":"guide/performance-results.md","lastUpdated":1726507196000}'),o={name:"guide/performance-results.md"};function n(a,e,l,g,c,m){return i(),t("div",null,e[0]||(e[0]=[s('

Performance Test Results

Project Information

Description:

This performance test compares two implementations of internationalization: i18n-micro and i18n. The main focus of the test is to evaluate build times, memory usage, CPU usage, and the performance of the server under stress (e.g., how many requests can be handled and how efficiently). The i18n-micro implementation shows slightly lower overall script execution times. This difference is attributed to its ability to handle more requests, which requires additional time for processing.

Important Note:

It is essential to recognize that the example used in this test is not entirely representative of the intended usage pattern for i18n-micro. The example simplifies the translation structure by consolidating all translations into a single file. However, i18n-micro is optimized for scenarios where translations are organized on a per-page basis. This approach allows for more granular control and efficiency, particularly in large-scale applications. The current setup is used merely for demonstration purposes and may not fully showcase the potential performance benefits of i18n-micro in real-world applications.


Build Performance for ./test/fixtures/i18n-micro

  • Build Time: 6.29 seconds
  • Max CPU Usage: 185.60%
  • Min CPU Usage: 84.60%
  • Average CPU Usage: 146.67%
  • Max Memory Usage: 1082.77 MB
  • Min Memory Usage: 172.28 MB
  • Average Memory Usage: 511.04 MB

Build Performance for ./test/fixtures/i18n

  • Build Time: 88.02 seconds
  • Max CPU Usage: 384.40%
  • Min CPU Usage: 84.70%
  • Average CPU Usage: 144.63%
  • Max Memory Usage: 9610.03 MB
  • Min Memory Usage: 196.80 MB
  • Average Memory Usage: 3642.73 MB

⏱️ Build Time and Resource Consumption

i18n
  • Build Time: 88.02 seconds
  • Max CPU Usage: 384.40%
  • Max Memory Usage: 9610.03 MB
i18n-micro
  • Build Time: 6.29 seconds
  • Max CPU Usage: 185.60%
  • Max Memory Usage: 1082.77 MB

Performance Comparison

  • i18n-micro: 6.29 seconds, Max Memory: 1082.77 MB, Max CPU: 185.60%
  • i18n: 88.02 seconds, Max Memory: 9610.03 MB, Max CPU: 384.40%
  • Time Difference: -81.73 seconds
  • Memory Difference: -8527.27 MB
  • CPU Usage Difference: -198.80%

Stress Test with Artillery for ./test/fixtures/i18n

  • Max CPU Usage: 155.10%
  • Min CPU Usage: 0.00%
  • Average CPU Usage: 95.97%
  • Max Memory Usage: 801.61 MB
  • Min Memory Usage: 49.72 MB
  • Average Memory Usage: 592.90 MB
  • Stress Test Time: 69.38 seconds
  • Average Response Time: 439.40 ms
  • Min Response Time: 1.00 ms
  • Max Response Time: 2994.00 ms
  • Requests per Second: 281.00
  • Error Rate: 0.00%

Stress Test with Artillery for ./test/fixtures/i18n-micro

  • Max CPU Usage: 130.70%
  • Min CPU Usage: 0.00%
  • Average CPU Usage: 91.83%
  • Max Memory Usage: 344.05 MB
  • Min Memory Usage: 48.22 MB
  • Average Memory Usage: 288.08 MB
  • Stress Test Time: 68.58 seconds
  • Average Response Time: 364.80 ms
  • Min Response Time: 0.00 ms
  • Max Response Time: 2483.00 ms
  • Requests per Second: 311.00
  • Error Rate: 0.00%

Comparison between i18n and i18n-micro

  • Max Memory Used Difference: -457.56 MB
  • Min Memory Used Difference: -1.50 MB
  • Avg Memory Used Difference: -304.82 MB
  • Max CPU Usage Difference: -24.40%
  • Min CPU Usage Difference: 0.00%
  • Avg CPU Usage Difference: -4.14%
  • Stress Test Time Difference: 0.00 seconds
  • Average Response Time Difference: -74.60 ms
  • Min Response Time Difference: -1.00 ms
  • Max Response Time Difference: -511.00 ms
  • Requests Per Second Difference: 30.00
  • Error Rate Difference: 0.00%

📊 Detailed Performance Analysis

🔍 Test Logic Explanation

The performance tests conducted for Nuxt I18n Micro and nuxt-i18n are designed to simulate real-world usage scenarios. Below is an overview of the key aspects of the test methodology:

  1. Build Time: Measures the time required to build the project, focusing on how efficiently each module handles large translation files.
  2. CPU Usage: Tracks the CPU load during the build and stress tests to assess the impact on server resources.
  3. Memory Usage: Monitors memory consumption to determine how each module manages memory, especially under high load.
  4. Stress Testing: Simulates a series of requests to evaluate the server's ability to handle concurrent traffic. The test is divided into two phases:
  • Warm-up Phase: Over 6 seconds, one request per second is sent to each of the specified URLs, with a maximum of 6 users, to ensure that the server is ready for the main test.
  • Main Test Phase: For 60 seconds, the server is subjected to 60 requests per second, spread across various endpoints, to measure response times, error rates, and overall throughput under load.

🛠 Why This Approach?

The chosen testing methodology is designed to reflect the scenarios that developers are likely to encounter in production environments. By focusing on build time, CPU and memory usage, and server performance under load, the tests provide a comprehensive view of how each module will perform in a large-scale, high-traffic application.

Nuxt I18n Micro is optimized for:

  • Faster Build Times: By reducing the overhead during the build process.
  • Lower Resource Consumption: Minimizing CPU and memory usage, making it suitable for resource-constrained environments.
  • Better Handling of Large Projects: With a focus on scalability, ensuring that applications remain responsive even as they grow.
',32)]))}const h=r(o,[["render",n]]);export{d as __pageData,h as default}; diff --git a/assets/guide_performance-results.md.BbKR1XsP.lean.js b/assets/guide_performance-results.md.BbKR1XsP.lean.js new file mode 100644 index 0000000..1d5c8ff --- /dev/null +++ b/assets/guide_performance-results.md.BbKR1XsP.lean.js @@ -0,0 +1 @@ +import{_ as r,c as t,a2 as s,o as i}from"./chunks/framework.CBrKbnPu.js";const d=JSON.parse('{"title":"Performance Test Results","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/performance-results.md","filePath":"guide/performance-results.md","lastUpdated":1726507196000}'),o={name:"guide/performance-results.md"};function n(a,e,l,g,c,m){return i(),t("div",null,e[0]||(e[0]=[s('

Performance Test Results

Project Information

Description:

This performance test compares two implementations of internationalization: i18n-micro and i18n. The main focus of the test is to evaluate build times, memory usage, CPU usage, and the performance of the server under stress (e.g., how many requests can be handled and how efficiently). The i18n-micro implementation shows slightly lower overall script execution times. This difference is attributed to its ability to handle more requests, which requires additional time for processing.

Important Note:

It is essential to recognize that the example used in this test is not entirely representative of the intended usage pattern for i18n-micro. The example simplifies the translation structure by consolidating all translations into a single file. However, i18n-micro is optimized for scenarios where translations are organized on a per-page basis. This approach allows for more granular control and efficiency, particularly in large-scale applications. The current setup is used merely for demonstration purposes and may not fully showcase the potential performance benefits of i18n-micro in real-world applications.


Build Performance for ./test/fixtures/i18n-micro

  • Build Time: 6.29 seconds
  • Max CPU Usage: 185.60%
  • Min CPU Usage: 84.60%
  • Average CPU Usage: 146.67%
  • Max Memory Usage: 1082.77 MB
  • Min Memory Usage: 172.28 MB
  • Average Memory Usage: 511.04 MB

Build Performance for ./test/fixtures/i18n

  • Build Time: 88.02 seconds
  • Max CPU Usage: 384.40%
  • Min CPU Usage: 84.70%
  • Average CPU Usage: 144.63%
  • Max Memory Usage: 9610.03 MB
  • Min Memory Usage: 196.80 MB
  • Average Memory Usage: 3642.73 MB

⏱️ Build Time and Resource Consumption

i18n
  • Build Time: 88.02 seconds
  • Max CPU Usage: 384.40%
  • Max Memory Usage: 9610.03 MB
i18n-micro
  • Build Time: 6.29 seconds
  • Max CPU Usage: 185.60%
  • Max Memory Usage: 1082.77 MB

Performance Comparison

  • i18n-micro: 6.29 seconds, Max Memory: 1082.77 MB, Max CPU: 185.60%
  • i18n: 88.02 seconds, Max Memory: 9610.03 MB, Max CPU: 384.40%
  • Time Difference: -81.73 seconds
  • Memory Difference: -8527.27 MB
  • CPU Usage Difference: -198.80%

Stress Test with Artillery for ./test/fixtures/i18n

  • Max CPU Usage: 155.10%
  • Min CPU Usage: 0.00%
  • Average CPU Usage: 95.97%
  • Max Memory Usage: 801.61 MB
  • Min Memory Usage: 49.72 MB
  • Average Memory Usage: 592.90 MB
  • Stress Test Time: 69.38 seconds
  • Average Response Time: 439.40 ms
  • Min Response Time: 1.00 ms
  • Max Response Time: 2994.00 ms
  • Requests per Second: 281.00
  • Error Rate: 0.00%

Stress Test with Artillery for ./test/fixtures/i18n-micro

  • Max CPU Usage: 130.70%
  • Min CPU Usage: 0.00%
  • Average CPU Usage: 91.83%
  • Max Memory Usage: 344.05 MB
  • Min Memory Usage: 48.22 MB
  • Average Memory Usage: 288.08 MB
  • Stress Test Time: 68.58 seconds
  • Average Response Time: 364.80 ms
  • Min Response Time: 0.00 ms
  • Max Response Time: 2483.00 ms
  • Requests per Second: 311.00
  • Error Rate: 0.00%

Comparison between i18n and i18n-micro

  • Max Memory Used Difference: -457.56 MB
  • Min Memory Used Difference: -1.50 MB
  • Avg Memory Used Difference: -304.82 MB
  • Max CPU Usage Difference: -24.40%
  • Min CPU Usage Difference: 0.00%
  • Avg CPU Usage Difference: -4.14%
  • Stress Test Time Difference: 0.00 seconds
  • Average Response Time Difference: -74.60 ms
  • Min Response Time Difference: -1.00 ms
  • Max Response Time Difference: -511.00 ms
  • Requests Per Second Difference: 30.00
  • Error Rate Difference: 0.00%

📊 Detailed Performance Analysis

🔍 Test Logic Explanation

The performance tests conducted for Nuxt I18n Micro and nuxt-i18n are designed to simulate real-world usage scenarios. Below is an overview of the key aspects of the test methodology:

  1. Build Time: Measures the time required to build the project, focusing on how efficiently each module handles large translation files.
  2. CPU Usage: Tracks the CPU load during the build and stress tests to assess the impact on server resources.
  3. Memory Usage: Monitors memory consumption to determine how each module manages memory, especially under high load.
  4. Stress Testing: Simulates a series of requests to evaluate the server's ability to handle concurrent traffic. The test is divided into two phases:
  • Warm-up Phase: Over 6 seconds, one request per second is sent to each of the specified URLs, with a maximum of 6 users, to ensure that the server is ready for the main test.
  • Main Test Phase: For 60 seconds, the server is subjected to 60 requests per second, spread across various endpoints, to measure response times, error rates, and overall throughput under load.

🛠 Why This Approach?

The chosen testing methodology is designed to reflect the scenarios that developers are likely to encounter in production environments. By focusing on build time, CPU and memory usage, and server performance under load, the tests provide a comprehensive view of how each module will perform in a large-scale, high-traffic application.

Nuxt I18n Micro is optimized for:

  • Faster Build Times: By reducing the overhead during the build process.
  • Lower Resource Consumption: Minimizing CPU and memory usage, making it suitable for resource-constrained environments.
  • Better Handling of Large Projects: With a focus on scalability, ensuring that applications remain responsive even as they grow.
',32)]))}const h=r(o,[["render",n]]);export{d as __pageData,h as default}; diff --git a/assets/guide_performance.md.SXcHzDO5.js b/assets/guide_performance.md.SXcHzDO5.js new file mode 100644 index 0000000..4d95d03 --- /dev/null +++ b/assets/guide_performance.md.SXcHzDO5.js @@ -0,0 +1 @@ +import{_ as r,c as o,a2 as n,o as a}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🚀 Performance Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/performance.md","filePath":"guide/performance.md","lastUpdated":1724679268000}'),i={name:"guide/performance.md"};function t(s,e,l,c,d,u){return a(),o("div",null,e[0]||(e[0]=[n('

🚀 Performance Guide

📖 Introduction

Nuxt I18n Micro is designed with performance in mind, offering a significant improvement over traditional internationalization (i18n) modules like nuxt-i18n. This guide provides an in-depth look at the performance benefits of using Nuxt I18n Micro, and how it compares to other solutions.

🤔 Why Focus on Performance?

In large-scale projects and high-traffic environments, performance bottlenecks can lead to slow build times, increased memory usage, and poor server response times. These issues become more pronounced with complex i18n setups involving large translation files. Nuxt I18n Micro was built to address these challenges head-on by optimizing for speed, memory efficiency, and minimal impact on your application’s bundle size.

📊 Performance Comparison

We conducted a series of tests to demonstrate the performance improvements that Nuxt I18n Micro brings to the table. Below is a detailed comparison between Nuxt I18n Micro and the traditional nuxt-i18n module, based on identical conditions with a 10MB translation file on the same hardware.

⏱️ Build Time and Resource Consumption

Nuxt I18n
  • Total Size: 54.7 MB (3.31 MB gzip)
  • Max CPU Usage: 391.4%
  • Max Memory Usage: 8305 MB
  • Elapsed Time: 1m 31s

Nuxt I18n Micro

  • Total Size: 1.93 MB (473 kB gzip) — 96% smaller
  • Max CPU Usage: 220.1% — 44% lower
  • Max Memory Usage: 655 MB — 92% less memory
  • Elapsed Time: 0m 5s — 94% faster

🌐 Server Performance Under Load

We also tested server performance by simulating 10,000 requests to each module.

Nuxt I18n
  • Requests per Second: 49.05 [#/sec] (mean)
  • Time per Request: 611.599 ms (mean)
  • Max Memory Usage: 703.73 MB

Nuxt I18n Micro

  • Requests per Second: 61.18 [#/sec] (mean) — 25% more requests per second
  • Time per Request: 490.379 ms (mean) — 20% faster
  • Max Memory Usage: 323.00 MB — 54% less memory usage

🔍 Interpretation of Results

These tests clearly indicate that Nuxt I18n Micro offers superior performance across multiple metrics:

  • 🗜️ Smaller Bundle Size: Reduces the overall size of your application bundle, leading to faster load times and better user experience.
  • 🔋 Lower CPU Usage: Decreases the load on your server’s CPU, allowing for more efficient processing of requests.
  • 🧠 Reduced Memory Consumption: Significantly lowers memory usage, minimizing the risk of memory leaks and enabling your application to handle larger workloads.
  • 🕒 Faster Build Times: Drastically reduces build times, which is particularly beneficial during development and CI/CD processes.

⚙️ Key Optimizations

🛠️ Minimalist Design

Nuxt I18n Micro is built around a minimalist architecture, using only 5 components (1 module and 4 plugins). This reduces overhead and simplifies the internal logic, leading to improved performance.

🚦 Efficient Routing

Unlike other i18n modules that generate a separate route for each locale, Nuxt I18n Micro uses dynamic regex-based routing. This approach generates only two routes regardless of the number of locales, significantly reducing the complexity of your routing configuration and speeding up route resolution.

📂 Streamlined Translation Loading

The module supports only JSON files for translations, with a clear separation between global and page-specific files. This ensures that only the necessary translation data is loaded at any given time, further enhancing performance.

💾 Caching and Pre-rendering

To optimize performance, Nuxt I18n Micro implements caching and supports pre-rendering of translation files:

  • 🗄️ Caching: Translations are cached after the initial load, reducing the need for subsequent requests and improving response times.
  • 🏁 Pre-rendering: During the build process, translation files for all configured locales and routes can be pre-rendered. This eliminates the need for runtime requests, ensuring that translations are served quickly and efficiently.

📝 Tips for Maximizing Performance

Here are a few tips to ensure you get the best performance out of Nuxt I18n Micro:

  • 📉 Limit Locale Data: Only include the locales you need in your project to keep the bundle size small.
  • 🗂️ Use Page-Specific Translations: Organize your translation files by page to avoid loading unnecessary data.
  • 💾 Enable Caching: Make use of the caching features to reduce server load and improve response times.
  • 🏁 Leverage Pre-rendering: Pre-render your translations to speed up page loads and reduce runtime overhead.

For detailed results of the performance tests, please refer to the Performance Test Results.

',31)]))}const p=r(i,[["render",t]]);export{g as __pageData,p as default}; diff --git a/assets/guide_performance.md.SXcHzDO5.lean.js b/assets/guide_performance.md.SXcHzDO5.lean.js new file mode 100644 index 0000000..4d95d03 --- /dev/null +++ b/assets/guide_performance.md.SXcHzDO5.lean.js @@ -0,0 +1 @@ +import{_ as r,c as o,a2 as n,o as a}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"🚀 Performance Guide","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/performance.md","filePath":"guide/performance.md","lastUpdated":1724679268000}'),i={name:"guide/performance.md"};function t(s,e,l,c,d,u){return a(),o("div",null,e[0]||(e[0]=[n('

🚀 Performance Guide

📖 Introduction

Nuxt I18n Micro is designed with performance in mind, offering a significant improvement over traditional internationalization (i18n) modules like nuxt-i18n. This guide provides an in-depth look at the performance benefits of using Nuxt I18n Micro, and how it compares to other solutions.

🤔 Why Focus on Performance?

In large-scale projects and high-traffic environments, performance bottlenecks can lead to slow build times, increased memory usage, and poor server response times. These issues become more pronounced with complex i18n setups involving large translation files. Nuxt I18n Micro was built to address these challenges head-on by optimizing for speed, memory efficiency, and minimal impact on your application’s bundle size.

📊 Performance Comparison

We conducted a series of tests to demonstrate the performance improvements that Nuxt I18n Micro brings to the table. Below is a detailed comparison between Nuxt I18n Micro and the traditional nuxt-i18n module, based on identical conditions with a 10MB translation file on the same hardware.

⏱️ Build Time and Resource Consumption

Nuxt I18n
  • Total Size: 54.7 MB (3.31 MB gzip)
  • Max CPU Usage: 391.4%
  • Max Memory Usage: 8305 MB
  • Elapsed Time: 1m 31s

Nuxt I18n Micro

  • Total Size: 1.93 MB (473 kB gzip) — 96% smaller
  • Max CPU Usage: 220.1% — 44% lower
  • Max Memory Usage: 655 MB — 92% less memory
  • Elapsed Time: 0m 5s — 94% faster

🌐 Server Performance Under Load

We also tested server performance by simulating 10,000 requests to each module.

Nuxt I18n
  • Requests per Second: 49.05 [#/sec] (mean)
  • Time per Request: 611.599 ms (mean)
  • Max Memory Usage: 703.73 MB

Nuxt I18n Micro

  • Requests per Second: 61.18 [#/sec] (mean) — 25% more requests per second
  • Time per Request: 490.379 ms (mean) — 20% faster
  • Max Memory Usage: 323.00 MB — 54% less memory usage

🔍 Interpretation of Results

These tests clearly indicate that Nuxt I18n Micro offers superior performance across multiple metrics:

  • 🗜️ Smaller Bundle Size: Reduces the overall size of your application bundle, leading to faster load times and better user experience.
  • 🔋 Lower CPU Usage: Decreases the load on your server’s CPU, allowing for more efficient processing of requests.
  • 🧠 Reduced Memory Consumption: Significantly lowers memory usage, minimizing the risk of memory leaks and enabling your application to handle larger workloads.
  • 🕒 Faster Build Times: Drastically reduces build times, which is particularly beneficial during development and CI/CD processes.

⚙️ Key Optimizations

🛠️ Minimalist Design

Nuxt I18n Micro is built around a minimalist architecture, using only 5 components (1 module and 4 plugins). This reduces overhead and simplifies the internal logic, leading to improved performance.

🚦 Efficient Routing

Unlike other i18n modules that generate a separate route for each locale, Nuxt I18n Micro uses dynamic regex-based routing. This approach generates only two routes regardless of the number of locales, significantly reducing the complexity of your routing configuration and speeding up route resolution.

📂 Streamlined Translation Loading

The module supports only JSON files for translations, with a clear separation between global and page-specific files. This ensures that only the necessary translation data is loaded at any given time, further enhancing performance.

💾 Caching and Pre-rendering

To optimize performance, Nuxt I18n Micro implements caching and supports pre-rendering of translation files:

  • 🗄️ Caching: Translations are cached after the initial load, reducing the need for subsequent requests and improving response times.
  • 🏁 Pre-rendering: During the build process, translation files for all configured locales and routes can be pre-rendered. This eliminates the need for runtime requests, ensuring that translations are served quickly and efficiently.

📝 Tips for Maximizing Performance

Here are a few tips to ensure you get the best performance out of Nuxt I18n Micro:

  • 📉 Limit Locale Data: Only include the locales you need in your project to keep the bundle size small.
  • 🗂️ Use Page-Specific Translations: Organize your translation files by page to avoid loading unnecessary data.
  • 💾 Enable Caching: Make use of the caching features to reduce server load and improve response times.
  • 🏁 Leverage Pre-rendering: Pre-render your translations to speed up page loads and reduce runtime overhead.

For detailed results of the performance tests, please refer to the Performance Test Results.

',31)]))}const p=r(i,[["render",t]]);export{g as __pageData,p as default}; diff --git a/assets/guide_seo.md.BpSpRrpu.js b/assets/guide_seo.md.BpSpRrpu.js new file mode 100644 index 0000000..de67253 --- /dev/null +++ b/assets/guide_seo.md.BpSpRrpu.js @@ -0,0 +1,13 @@ +import{_ as e,c as s,a2 as a,o as n}from"./chunks/framework.CBrKbnPu.js";const k=JSON.parse('{"title":"🌐 SEO Guide for Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/seo.md","filePath":"guide/seo.md","lastUpdated":1724243643000}'),t={name:"guide/seo.md"};function l(o,i,r,h,d,p){return n(),s("div",null,i[0]||(i[0]=[a(`

🌐 SEO Guide for Nuxt I18n Micro

📖 Introduction

Effective SEO (Search Engine Optimization) is essential for ensuring that your multilingual site is accessible and visible to users worldwide through search engines. Nuxt I18n Micro simplifies the process of managing SEO for multilingual sites by automatically generating essential meta tags and attributes that inform search engines about the structure and content of your site.

This guide explains how Nuxt I18n Micro handles SEO to enhance your site's visibility and user experience without requiring additional configuration.

⚙️ Automatic SEO Handling

🔑 Key SEO Features

When the meta option is enabled in Nuxt I18n Micro, the module automatically manages the following SEO aspects:

  1. 🌍 Language and Direction Attributes:

    • The module sets the lang and dir attributes on the <html> tag according to the current locale and text direction (e.g., ltr for English or rtl for Arabic).
  2. 🔗 Canonical URLs:

    • The module generates a canonical link (<link rel="canonical">) for each page, ensuring that search engines recognize the primary version of the content.
  3. 🌐 Alternate Language Links (hreflang):

    • The module automatically generates <link rel="alternate" hreflang=""> tags for all available locales. This helps search engines understand which language versions of your content are available, improving the user experience for global audiences.
  4. 🔖 Open Graph Metadata:

    • The module generates Open Graph meta tags (og:locale, og:url, etc.) for each locale, which is particularly useful for social media sharing and search engine indexing.

🛠️ Configuration

To enable these SEO features, ensure the meta option is set to true in your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true, // Enables automatic SEO management
+  },
+})

🎯 Benefits

By enabling the meta option, you benefit from:

  • 📈 Improved Search Engine Rankings: Search engines can better index your site, understanding the relationships between different language versions.
  • 👥 Better User Experience: Users are served the correct language version based on their preferences, leading to a more personalized experience.
  • 🔧 Reduced Manual Configuration: The module handles SEO tasks automatically, freeing you from the need to manually add SEO-related meta tags and attributes.
`,14)]))}const g=e(t,[["render",l]]);export{k as __pageData,g as default}; diff --git a/assets/guide_seo.md.BpSpRrpu.lean.js b/assets/guide_seo.md.BpSpRrpu.lean.js new file mode 100644 index 0000000..de67253 --- /dev/null +++ b/assets/guide_seo.md.BpSpRrpu.lean.js @@ -0,0 +1,13 @@ +import{_ as e,c as s,a2 as a,o as n}from"./chunks/framework.CBrKbnPu.js";const k=JSON.parse('{"title":"🌐 SEO Guide for Nuxt I18n Micro","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/seo.md","filePath":"guide/seo.md","lastUpdated":1724243643000}'),t={name:"guide/seo.md"};function l(o,i,r,h,d,p){return n(),s("div",null,i[0]||(i[0]=[a(`

🌐 SEO Guide for Nuxt I18n Micro

📖 Introduction

Effective SEO (Search Engine Optimization) is essential for ensuring that your multilingual site is accessible and visible to users worldwide through search engines. Nuxt I18n Micro simplifies the process of managing SEO for multilingual sites by automatically generating essential meta tags and attributes that inform search engines about the structure and content of your site.

This guide explains how Nuxt I18n Micro handles SEO to enhance your site's visibility and user experience without requiring additional configuration.

⚙️ Automatic SEO Handling

🔑 Key SEO Features

When the meta option is enabled in Nuxt I18n Micro, the module automatically manages the following SEO aspects:

  1. 🌍 Language and Direction Attributes:

    • The module sets the lang and dir attributes on the <html> tag according to the current locale and text direction (e.g., ltr for English or rtl for Arabic).
  2. 🔗 Canonical URLs:

    • The module generates a canonical link (<link rel="canonical">) for each page, ensuring that search engines recognize the primary version of the content.
  3. 🌐 Alternate Language Links (hreflang):

    • The module automatically generates <link rel="alternate" hreflang=""> tags for all available locales. This helps search engines understand which language versions of your content are available, improving the user experience for global audiences.
  4. 🔖 Open Graph Metadata:

    • The module generates Open Graph meta tags (og:locale, og:url, etc.) for each locale, which is particularly useful for social media sharing and search engine indexing.

🛠️ Configuration

To enable these SEO features, ensure the meta option is set to true in your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true, // Enables automatic SEO management
+  },
+})

🎯 Benefits

By enabling the meta option, you benefit from:

  • 📈 Improved Search Engine Rankings: Search engines can better index your site, understanding the relationships between different language versions.
  • 👥 Better User Experience: Users are served the correct language version based on their preferences, leading to a more personalized experience.
  • 🔧 Reduced Manual Configuration: The module handles SEO tasks automatically, freeing you from the need to manually add SEO-related meta tags and attributes.
`,14)]))}const g=e(t,[["render",l]]);export{k as __pageData,g as default}; diff --git a/assets/index.md.CpgHYvSM.js b/assets/index.md.CpgHYvSM.js new file mode 100644 index 0000000..b05c1a8 --- /dev/null +++ b/assets/index.md.CpgHYvSM.js @@ -0,0 +1,27 @@ +import{_ as i,c as n,a2 as e,o as a}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"Nuxt I18n Micro","text":"Fast, Simple, and Lightweight Internationalization for Nuxt","tagline":"Optimize your Nuxt app with a powerful and efficient i18n solution.","actions":[{"theme":"brand","text":"🚀 Get Started","link":"/guide/getting-started"},{"theme":"alt","text":"⭐ View on GitHub","link":"https://github.com/s00d/nuxt-i18n-micro"}]},"features":[{"title":"⚡ High Performance","details":"🚀 Significant reductions in build times, memory usage, and server load, making it ideal for large-scale projects."},{"title":"🪶 Compact and Lightweight","details":"🧩 Designed for efficiency, reducing the total bundle size by up to 96% compared to traditional i18n modules."},{"title":"🎨 Minimalist Design","details":"🧱 A simple structure with just 5 components, easy to extend and maintain."},{"title":"🔄 Dynamic Routing","details":"🗺️ Efficient regex-based routing that generates only two routes regardless of the number of locales."},{"title":"📂 Streamlined Translation Loading","details":"🔧 Supports only JSON files, with auto-generated page-specific translations."},{"title":"🌐 Seamless Nuxt Integration","details":"🛠️ Seamless integration with Nuxt.js, making it easy to add powerful i18n features to your application."}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1724249388000}'),t={name:"index.md"};function r(l,s,o,p,d,h){return a(),n("div",null,s[0]||(s[0]=[e(`

✨ Introduction

Nuxt I18n Micro is a fast, simple, and lightweight internationalization (i18n) module for Nuxt. Despite its compact size, it's designed with large projects in mind, offering significant performance improvements over traditional i18n solutions like nuxt-i18n. The module was built from the ground up to be highly efficient, focusing on minimizing build times, reducing server load, and shrinking bundle sizes.

📝 Why Nuxt I18n Micro?

The Nuxt I18n Micro module was created to address critical performance issues found in the original nuxt-i18n module, particularly in high-traffic environments and projects with large translation files. Key issues with nuxt-i18n include:

  • 🚨 High Memory Consumption: Consumes significant memory during both build and runtime, leading to performance bottlenecks.
  • 🐢 Slow Performance: Especially with large translation files, it causes noticeable slowdowns in build times and server response.
  • 💼 Large Bundle Size: Generates a large bundle, negatively impacting application performance.
  • 🐛 Memory Leaks and Bugs: Known for memory leaks and unpredictable behavior under heavy load.

🏁 Performance Comparison

To showcase the efficiency of Nuxt I18n Micro, we conducted tests under identical conditions. Both modules were tested with a 10MB translation file on the same hardware.

⏱️ Build Time and Resource Consumption

Nuxt I18n
  • Total Size: 54.7 MB (3.31 MB gzip)
  • Max CPU Usage: 391.4%
  • Max Memory Usage: 8305 MB
  • Elapsed Time: 0h 1m 31s

Nuxt I18n Micro

  • Total Size: 1.93 MB (473 kB gzip) — 96% smaller
  • Max CPU Usage: 220.1% — 44% lower
  • Max Memory Usage: 655 MB — 92% less memory
  • Elapsed Time: 0h 0m 5s — 94% faster

🌐 Server Performance (10k Requests)

Nuxt I18n
  • Requests per Second: 49.05 [#/sec] (mean)
  • Time per Request: 611.599 ms (mean)
  • Max Memory Usage: 703.73 MB

Nuxt I18n Micro

  • Requests per Second: 61.18 [#/sec] (mean) — 25% more requests per second
  • Time per Request: 490.379 ms (mean) — 20% faster
  • Max Memory Usage: 323.00 MB — 54% less memory usage

These results clearly demonstrate that Nuxt I18n Micro significantly outperforms the original module in every critical area.

🔑 Key Features

  • 🌐 Compact Yet Powerful: Despite its small size, Nuxt I18n Micro is designed for large-scale projects, focusing on performance and efficiency.
  • Optimized Build and Runtime: Reduces build times, memory usage, and server load, making it ideal for high-traffic applications.
  • 🛠️ Minimalist Design: The module is structured around just 5 components (1 module and 4 plugins), making it easy to understand, extend, and maintain.
  • 📏 Efficient Routing: Generates only 2 routes regardless of the number of locales, thanks to dynamic regex-based routing, unlike other i18n modules that generate separate routes for each locale.
  • 🗂 Streamlined Translation Loading: Only JSON files are supported, with translations split between a global file for common texts (e.g., menus) and page-specific files, which are auto-generated in the dev mode if not present.

⚙️ Quick Setup

Install the module in your Nuxt application with:

bash
npm install nuxt-i18n-micro

Then, add it to your nuxt.config.ts:

typescript
export default defineNuxtConfig({
+  modules: [
+    'nuxt-i18n-micro',
+  ],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

That's it! You're now ready to use Nuxt I18n Micro in your Nuxt app.

🗂 Folder Structure

Translations are organized into global and page-specific files:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json
`,26)]))}const u=i(t,[["render",r]]);export{g as __pageData,u as default}; diff --git a/assets/index.md.CpgHYvSM.lean.js b/assets/index.md.CpgHYvSM.lean.js new file mode 100644 index 0000000..b05c1a8 --- /dev/null +++ b/assets/index.md.CpgHYvSM.lean.js @@ -0,0 +1,27 @@ +import{_ as i,c as n,a2 as e,o as a}from"./chunks/framework.CBrKbnPu.js";const g=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"Nuxt I18n Micro","text":"Fast, Simple, and Lightweight Internationalization for Nuxt","tagline":"Optimize your Nuxt app with a powerful and efficient i18n solution.","actions":[{"theme":"brand","text":"🚀 Get Started","link":"/guide/getting-started"},{"theme":"alt","text":"⭐ View on GitHub","link":"https://github.com/s00d/nuxt-i18n-micro"}]},"features":[{"title":"⚡ High Performance","details":"🚀 Significant reductions in build times, memory usage, and server load, making it ideal for large-scale projects."},{"title":"🪶 Compact and Lightweight","details":"🧩 Designed for efficiency, reducing the total bundle size by up to 96% compared to traditional i18n modules."},{"title":"🎨 Minimalist Design","details":"🧱 A simple structure with just 5 components, easy to extend and maintain."},{"title":"🔄 Dynamic Routing","details":"🗺️ Efficient regex-based routing that generates only two routes regardless of the number of locales."},{"title":"📂 Streamlined Translation Loading","details":"🔧 Supports only JSON files, with auto-generated page-specific translations."},{"title":"🌐 Seamless Nuxt Integration","details":"🛠️ Seamless integration with Nuxt.js, making it easy to add powerful i18n features to your application."}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1724249388000}'),t={name:"index.md"};function r(l,s,o,p,d,h){return a(),n("div",null,s[0]||(s[0]=[e(`

✨ Introduction

Nuxt I18n Micro is a fast, simple, and lightweight internationalization (i18n) module for Nuxt. Despite its compact size, it's designed with large projects in mind, offering significant performance improvements over traditional i18n solutions like nuxt-i18n. The module was built from the ground up to be highly efficient, focusing on minimizing build times, reducing server load, and shrinking bundle sizes.

📝 Why Nuxt I18n Micro?

The Nuxt I18n Micro module was created to address critical performance issues found in the original nuxt-i18n module, particularly in high-traffic environments and projects with large translation files. Key issues with nuxt-i18n include:

  • 🚨 High Memory Consumption: Consumes significant memory during both build and runtime, leading to performance bottlenecks.
  • 🐢 Slow Performance: Especially with large translation files, it causes noticeable slowdowns in build times and server response.
  • 💼 Large Bundle Size: Generates a large bundle, negatively impacting application performance.
  • 🐛 Memory Leaks and Bugs: Known for memory leaks and unpredictable behavior under heavy load.

🏁 Performance Comparison

To showcase the efficiency of Nuxt I18n Micro, we conducted tests under identical conditions. Both modules were tested with a 10MB translation file on the same hardware.

⏱️ Build Time and Resource Consumption

Nuxt I18n
  • Total Size: 54.7 MB (3.31 MB gzip)
  • Max CPU Usage: 391.4%
  • Max Memory Usage: 8305 MB
  • Elapsed Time: 0h 1m 31s

Nuxt I18n Micro

  • Total Size: 1.93 MB (473 kB gzip) — 96% smaller
  • Max CPU Usage: 220.1% — 44% lower
  • Max Memory Usage: 655 MB — 92% less memory
  • Elapsed Time: 0h 0m 5s — 94% faster

🌐 Server Performance (10k Requests)

Nuxt I18n
  • Requests per Second: 49.05 [#/sec] (mean)
  • Time per Request: 611.599 ms (mean)
  • Max Memory Usage: 703.73 MB

Nuxt I18n Micro

  • Requests per Second: 61.18 [#/sec] (mean) — 25% more requests per second
  • Time per Request: 490.379 ms (mean) — 20% faster
  • Max Memory Usage: 323.00 MB — 54% less memory usage

These results clearly demonstrate that Nuxt I18n Micro significantly outperforms the original module in every critical area.

🔑 Key Features

  • 🌐 Compact Yet Powerful: Despite its small size, Nuxt I18n Micro is designed for large-scale projects, focusing on performance and efficiency.
  • Optimized Build and Runtime: Reduces build times, memory usage, and server load, making it ideal for high-traffic applications.
  • 🛠️ Minimalist Design: The module is structured around just 5 components (1 module and 4 plugins), making it easy to understand, extend, and maintain.
  • 📏 Efficient Routing: Generates only 2 routes regardless of the number of locales, thanks to dynamic regex-based routing, unlike other i18n modules that generate separate routes for each locale.
  • 🗂 Streamlined Translation Loading: Only JSON files are supported, with translations split between a global file for common texts (e.g., menus) and page-specific files, which are auto-generated in the dev mode if not present.

⚙️ Quick Setup

Install the module in your Nuxt application with:

bash
npm install nuxt-i18n-micro

Then, add it to your nuxt.config.ts:

typescript
export default defineNuxtConfig({
+  modules: [
+    'nuxt-i18n-micro',
+  ],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

That's it! You're now ready to use Nuxt I18n Micro in your Nuxt app.

🗂 Folder Structure

Translations are organized into global and page-specific files:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json
`,26)]))}const u=i(t,[["render",r]]);export{g as __pageData,u as default}; diff --git a/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 b/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 new file mode 100644 index 0000000..b6b603d Binary files /dev/null and b/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 differ diff --git a/assets/inter-italic-cyrillic.By2_1cv3.woff2 b/assets/inter-italic-cyrillic.By2_1cv3.woff2 new file mode 100644 index 0000000..def40a4 Binary files /dev/null and b/assets/inter-italic-cyrillic.By2_1cv3.woff2 differ diff --git a/assets/inter-italic-greek-ext.1u6EdAuj.woff2 b/assets/inter-italic-greek-ext.1u6EdAuj.woff2 new file mode 100644 index 0000000..e070c3d Binary files /dev/null and b/assets/inter-italic-greek-ext.1u6EdAuj.woff2 differ diff --git a/assets/inter-italic-greek.DJ8dCoTZ.woff2 b/assets/inter-italic-greek.DJ8dCoTZ.woff2 new file mode 100644 index 0000000..a3c16ca Binary files /dev/null and b/assets/inter-italic-greek.DJ8dCoTZ.woff2 differ diff --git a/assets/inter-italic-latin-ext.CN1xVJS-.woff2 b/assets/inter-italic-latin-ext.CN1xVJS-.woff2 new file mode 100644 index 0000000..2210a89 Binary files /dev/null and b/assets/inter-italic-latin-ext.CN1xVJS-.woff2 differ diff --git a/assets/inter-italic-latin.C2AdPX0b.woff2 b/assets/inter-italic-latin.C2AdPX0b.woff2 new file mode 100644 index 0000000..790d62d Binary files /dev/null and b/assets/inter-italic-latin.C2AdPX0b.woff2 differ diff --git a/assets/inter-italic-vietnamese.BSbpV94h.woff2 b/assets/inter-italic-vietnamese.BSbpV94h.woff2 new file mode 100644 index 0000000..1eec077 Binary files /dev/null and b/assets/inter-italic-vietnamese.BSbpV94h.woff2 differ diff --git a/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 b/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 new file mode 100644 index 0000000..2cfe615 Binary files /dev/null and b/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 differ diff --git a/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 b/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 new file mode 100644 index 0000000..e3886dd Binary files /dev/null and b/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 differ diff --git a/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 b/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 new file mode 100644 index 0000000..36d6748 Binary files /dev/null and b/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 differ diff --git a/assets/inter-roman-greek.BBVDIX6e.woff2 b/assets/inter-roman-greek.BBVDIX6e.woff2 new file mode 100644 index 0000000..2bed1e8 Binary files /dev/null and b/assets/inter-roman-greek.BBVDIX6e.woff2 differ diff --git a/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 b/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 new file mode 100644 index 0000000..9a8d1e2 Binary files /dev/null and b/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 differ diff --git a/assets/inter-roman-latin.Di8DUHzh.woff2 b/assets/inter-roman-latin.Di8DUHzh.woff2 new file mode 100644 index 0000000..07d3c53 Binary files /dev/null and b/assets/inter-roman-latin.Di8DUHzh.woff2 differ diff --git a/assets/inter-roman-vietnamese.BjW4sHH5.woff2 b/assets/inter-roman-vietnamese.BjW4sHH5.woff2 new file mode 100644 index 0000000..57bdc22 Binary files /dev/null and b/assets/inter-roman-vietnamese.BjW4sHH5.woff2 differ diff --git a/assets/style.DMVYS8rJ.css b/assets/style.DMVYS8rJ.css new file mode 100644 index 0000000..3822b3b --- /dev/null +++ b/assets/style.DMVYS8rJ.css @@ -0,0 +1 @@ +@import"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css";@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-roman-cyrillic.C5lxZ8CY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-roman-greek-ext.CqjqNYQ-.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-roman-greek.BBVDIX6e.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-roman-vietnamese.BjW4sHH5.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-roman-latin-ext.4ZJIpNVo.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-roman-latin.Di8DUHzh.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-italic-cyrillic-ext.r48I6akx.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-italic-cyrillic.By2_1cv3.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-italic-greek-ext.1u6EdAuj.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-italic-greek.DJ8dCoTZ.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-italic-vietnamese.BSbpV94h.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-italic-latin-ext.CN1xVJS-.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/nuxt-i18n-micro/assets/inter-italic-latin.C2AdPX0b.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Punctuation SC;font-weight:400;src:local("PingFang SC Regular"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:500;src:local("PingFang SC Medium"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:600;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:700;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: rgba(60, 60, 67);--vp-c-text-2: rgba(60, 60, 67, .78);--vp-c-text-3: rgba(60, 60, 67, .56)}.dark{--vp-c-text-1: rgba(255, 255, 245, .86);--vp-c-text-2: rgba(235, 235, 245, .6);--vp-c-text-3: rgba(235, 235, 245, .38)}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;font-optical-sizing:auto}:root:where(:lang(zh)){--vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui, "PingFang SC", "Noto Sans CJK SC", "Noto Sans SC", "Heiti SC", "Microsoft YaHei", "DengXian", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{overflow-x:auto}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.vpi-social-discord{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z'/%3E%3C/svg%3E")}.vpi-social-facebook{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z'/%3E%3C/svg%3E")}.vpi-social-github{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}.vpi-social-instagram{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.03.084c-1.277.06-2.149.264-2.91.563a5.874 5.874 0 0 0-2.124 1.388 5.878 5.878 0 0 0-1.38 2.127C.321 4.926.12 5.8.064 7.076.008 8.354-.005 8.764.001 12.023c.007 3.259.021 3.667.083 4.947.061 1.277.264 2.149.563 2.911.308.789.72 1.457 1.388 2.123a5.872 5.872 0 0 0 2.129 1.38c.763.295 1.636.496 2.913.552 1.278.056 1.689.069 4.947.063 3.257-.007 3.668-.021 4.947-.082 1.28-.06 2.147-.265 2.91-.563a5.881 5.881 0 0 0 2.123-1.388 5.881 5.881 0 0 0 1.38-2.129c.295-.763.496-1.636.551-2.912.056-1.28.07-1.69.063-4.948-.006-3.258-.02-3.667-.081-4.947-.06-1.28-.264-2.148-.564-2.911a5.892 5.892 0 0 0-1.387-2.123 5.857 5.857 0 0 0-2.128-1.38C19.074.322 18.202.12 16.924.066 15.647.009 15.236-.006 11.977 0 8.718.008 8.31.021 7.03.084m.14 21.693c-1.17-.05-1.805-.245-2.228-.408a3.736 3.736 0 0 1-1.382-.895 3.695 3.695 0 0 1-.9-1.378c-.165-.423-.363-1.058-.417-2.228-.06-1.264-.072-1.644-.08-4.848-.006-3.204.006-3.583.061-4.848.05-1.169.246-1.805.408-2.228.216-.561.477-.96.895-1.382a3.705 3.705 0 0 1 1.379-.9c.423-.165 1.057-.361 2.227-.417 1.265-.06 1.644-.072 4.848-.08 3.203-.006 3.583.006 4.85.062 1.168.05 1.804.244 2.227.408.56.216.96.475 1.382.895.421.42.681.817.9 1.378.165.422.362 1.056.417 2.227.06 1.265.074 1.645.08 4.848.005 3.203-.006 3.583-.061 4.848-.051 1.17-.245 1.805-.408 2.23-.216.56-.477.96-.896 1.38a3.705 3.705 0 0 1-1.378.9c-.422.165-1.058.362-2.226.418-1.266.06-1.645.072-4.85.079-3.204.007-3.582-.006-4.848-.06m9.783-16.192a1.44 1.44 0 1 0 1.437-1.442 1.44 1.44 0 0 0-1.437 1.442M5.839 12.012a6.161 6.161 0 1 0 12.323-.024 6.162 6.162 0 0 0-12.323.024M8 12.008A4 4 0 1 1 12.008 16 4 4 0 0 1 8 12.008'/%3E%3C/svg%3E")}.vpi-social-linkedin{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z'/%3E%3C/svg%3E")}.vpi-social-mastodon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E")}.vpi-social-npm{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z'/%3E%3C/svg%3E")}.vpi-social-slack{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.268a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z'/%3E%3C/svg%3E")}.vpi-social-twitter,.vpi-social-x{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E")}.vpi-social-youtube{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc h4{margin:24px 0 0;letter-spacing:-.01em;line-height:24px;font-size:18px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s;color:var(--vp-c-text-2)}.vp-doc blockquote>p{margin:0;font-size:16px;transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code,.vp-doc h4>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(.no-icon):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-c79a1216]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-c79a1216],.VPBackdrop.fade-leave-to[data-v-c79a1216]{opacity:0}.VPBackdrop.fade-leave-active[data-v-c79a1216]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-c79a1216]{display:none}}.NotFound[data-v-d6be1790]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-d6be1790]{padding:96px 32px 168px}}.code[data-v-d6be1790]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-d6be1790]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-d6be1790]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-d6be1790]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-d6be1790]{padding-top:20px}.link[data-v-d6be1790]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-d6be1790]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-b933a997]{position:relative;z-index:1}.nested[data-v-b933a997]{padding-right:16px;padding-left:16px}.outline-link[data-v-b933a997]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-b933a997]:hover,.outline-link.active[data-v-b933a997]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-b933a997]{padding-left:13px}.VPDocAsideOutline[data-v-a5bbad30]{display:none}.VPDocAsideOutline.has-outline[data-v-a5bbad30]{display:block}.content[data-v-a5bbad30]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-a5bbad30]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-a5bbad30]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-3f215769]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-3f215769]{flex-grow:1}.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-3f215769] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-e98dd255]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-e98dd255]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-e257564d]{margin-top:64px}.edit-info[data-v-e257564d]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-e257564d]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-e257564d]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-e257564d]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-e257564d]{margin-right:8px}.prev-next[data-v-e257564d]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-e257564d]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-e257564d]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-e257564d]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-e257564d]{margin-left:auto;text-align:right}.desc[data-v-e257564d]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-e257564d]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-39a288b8]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-39a288b8]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-39a288b8]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-39a288b8]{display:flex;justify-content:center}.VPDoc .aside[data-v-39a288b8]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{max-width:1104px}}.container[data-v-39a288b8]{margin:0 auto;width:100%}.aside[data-v-39a288b8]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-39a288b8]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-39a288b8]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-39a288b8]::-webkit-scrollbar{display:none}.aside-curtain[data-v-39a288b8]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-39a288b8]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-39a288b8]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-39a288b8]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-39a288b8]{order:1;margin:0;min-width:640px}}.content-container[data-v-39a288b8]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-39a288b8]{max-width:688px}.VPButton[data-v-cad61b99]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-cad61b99]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-cad61b99]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-cad61b99]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-cad61b99]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-cad61b99]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-cad61b99]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-cad61b99]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-cad61b99]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-cad61b99]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-cad61b99]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-cad61b99]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-cad61b99]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-8426fc1a]{display:none}.dark .VPImage.light[data-v-8426fc1a]{display:none}.VPHero[data-v-303bb580]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-303bb580]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-303bb580]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-303bb580]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-303bb580]{flex-direction:row}}.main[data-v-303bb580]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-303bb580]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-303bb580]{text-align:left}}@media (min-width: 960px){.main[data-v-303bb580]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-303bb580]{max-width:592px}}.name[data-v-303bb580],.text[data-v-303bb580]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-303bb580],.VPHero.has-image .text[data-v-303bb580]{margin:0 auto}.name[data-v-303bb580]{color:var(--vp-home-hero-name-color)}.clip[data-v-303bb580]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-303bb580],.text[data-v-303bb580]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-303bb580],.text[data-v-303bb580]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-303bb580],.VPHero.has-image .text[data-v-303bb580]{margin:0}}.tagline[data-v-303bb580]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-303bb580]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-303bb580]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-303bb580]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-303bb580]{margin:0}}.actions[data-v-303bb580]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-303bb580]{justify-content:center}@media (min-width: 640px){.actions[data-v-303bb580]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-303bb580]{justify-content:flex-start}}.action[data-v-303bb580]{flex-shrink:0;padding:6px}.image[data-v-303bb580]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-303bb580]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-303bb580]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-303bb580]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-303bb580]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-303bb580]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-303bb580]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-303bb580]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-303bb580]{width:320px;height:320px}}[data-v-303bb580] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-303bb580] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-303bb580] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-a3976bdc]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-a3976bdc]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-a3976bdc]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-a3976bdc]>.VPImage{margin-bottom:20px}.icon[data-v-a3976bdc]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-a3976bdc]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-a3976bdc]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-a3976bdc]{padding-top:8px}.link-text-value[data-v-a3976bdc]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-a3976bdc]{margin-left:6px}.VPFeatures[data-v-a6181336]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-a6181336]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-a6181336]{padding:0 64px}}.container[data-v-a6181336]{margin:0 auto;max-width:1152px}.items[data-v-a6181336]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-a6181336]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336]{width:50%}.item.grid-3[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-a6181336]{width:25%}}.container[data-v-8e2d4988]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-8e2d4988]{padding:0 48px}}@media (min-width: 960px){.container[data-v-8e2d4988]{width:100%;padding:0 64px}}.vp-doc[data-v-8e2d4988] .VPHomeSponsors,.vp-doc[data-v-8e2d4988] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-8e2d4988] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-8e2d4988] .VPHomeSponsors a,.vp-doc[data-v-8e2d4988] .VPTeamPage a{text-decoration:none}.VPHome[data-v-686f80a6]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-686f80a6]{margin-bottom:128px}}.VPContent[data-v-1428d186]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-1428d186]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-1428d186]{margin:0}@media (min-width: 960px){.VPContent[data-v-1428d186]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-1428d186]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-1428d186]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-e315a0ad]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-e315a0ad]{display:none}.VPFooter[data-v-e315a0ad] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-e315a0ad] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-e315a0ad]{padding:32px}}.container[data-v-e315a0ad]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-e315a0ad],.copyright[data-v-e315a0ad]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-17a5e62e]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-17a5e62e]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-17a5e62e]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-17a5e62e]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-17a5e62e]{color:var(--vp-c-text-1)}.icon[data-v-17a5e62e]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-17a5e62e]{font-size:14px}.icon[data-v-17a5e62e]{font-size:16px}}.open>.icon[data-v-17a5e62e]{transform:rotate(90deg)}.items[data-v-17a5e62e]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-17a5e62e]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-17a5e62e]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-17a5e62e]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-17a5e62e]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-17a5e62e]{transition:all .2s ease-out}.flyout-leave-active[data-v-17a5e62e]{transition:all .15s ease-in}.flyout-enter-from[data-v-17a5e62e],.flyout-leave-to[data-v-17a5e62e]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-a6f0e41e]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-a6f0e41e]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-a6f0e41e]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-a6f0e41e]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-a6f0e41e]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-a6f0e41e]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-a6f0e41e]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-a6f0e41e]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-a6f0e41e]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-a6f0e41e]{display:none}}.menu-icon[data-v-a6f0e41e]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 32px 11px}}.VPSwitch[data-v-1d5665e3]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-1d5665e3]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-1d5665e3]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-1d5665e3]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-1d5665e3] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-1d5665e3] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-5337faa4]{opacity:1}.moon[data-v-5337faa4],.dark .sun[data-v-5337faa4]{opacity:0}.dark .moon[data-v-5337faa4]{opacity:1}.dark .VPSwitchAppearance[data-v-5337faa4] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-6c893767]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-6c893767]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-43f1e123]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-43f1e123]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-43f1e123]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-43f1e123]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-69e747b5]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-69e747b5]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-69e747b5]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-69e747b5]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-b98bc113]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-b98bc113] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-b98bc113] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-b98bc113] .group:last-child{padding-bottom:0}.VPMenu[data-v-b98bc113] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-b98bc113] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-b98bc113] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-b98bc113] .action{padding-left:24px}.VPFlyout[data-v-b6c34ac9]{position:relative}.VPFlyout[data-v-b6c34ac9]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-b6c34ac9]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-b6c34ac9]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-b6c34ac9]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-b6c34ac9]{color:var(--vp-c-brand-2)}.VPFlyout:hover .menu[data-v-b6c34ac9],.button[aria-expanded=true]+.menu[data-v-b6c34ac9]{opacity:1;visibility:visible;transform:translateY(0)}.button[aria-expanded=false]+.menu[data-v-b6c34ac9]{opacity:0;visibility:hidden;transform:translateY(0)}.button[data-v-b6c34ac9]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-b6c34ac9]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-b6c34ac9]{margin-right:0;font-size:16px}.text-icon[data-v-b6c34ac9]{margin-left:4px;font-size:14px}.icon[data-v-b6c34ac9]{font-size:20px;transition:fill .25s}.menu[data-v-b6c34ac9]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-eee4e7cb]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-eee4e7cb]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-eee4e7cb]>svg,.VPSocialLink[data-v-eee4e7cb]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-7bc22406]{display:flex;justify-content:center}.VPNavBarExtra[data-v-bb2aa2f0]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-bb2aa2f0]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-bb2aa2f0]{display:none}}.trans-title[data-v-bb2aa2f0]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-bb2aa2f0],.item.social-links[data-v-bb2aa2f0]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-bb2aa2f0]{min-width:176px}.appearance-action[data-v-bb2aa2f0]{margin-right:-2px}.social-links-list[data-v-bb2aa2f0]{margin:-4px -8px}.VPNavBarHamburger[data-v-e5dd9c1c]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-e5dd9c1c]{display:none}}.container[data-v-e5dd9c1c]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-e5dd9c1c]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-e5dd9c1c],.middle[data-v-e5dd9c1c],.bottom[data-v-e5dd9c1c]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(0)}.middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-9c663999]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-9c663999],.VPNavBarMenuLink[data-v-9c663999]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-dc692963]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-dc692963]{display:flex}}/*! @docsearch/css 3.6.1 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 rgba(3,4,9,.30196078431372547);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;position:relative;padding:0 0 2px;border:0;top:-1px;width:20px}.DocSearch-Button-Key--pressed{transform:translate3d(0,1px,0);box-shadow:var(--docsearch-key-pressed-shadow)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:2px;box-shadow:var(--docsearch-key-shadow);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;color:var(--docsearch-muted-color);border:0;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button-Key--pressed{transform:none;box-shadow:none}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-0394ad82]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-0394ad82]{display:flex;align-items:center}}.title[data-v-ab179fa1]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-ab179fa1]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-ab179fa1]{border-bottom-color:var(--vp-c-divider)}}[data-v-ab179fa1] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-88af2de4]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-88af2de4]{display:flex;align-items:center}}.title[data-v-88af2de4]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-6aa21345]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .25s}.VPNavBar.screen-open[data-v-6aa21345]{transition:none;background-color:var(--vp-nav-bg-color);border-bottom:1px solid var(--vp-c-divider)}.VPNavBar[data-v-6aa21345]:not(.home){background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar[data-v-6aa21345]:not(.home){background-color:transparent}.VPNavBar[data-v-6aa21345]:not(.has-sidebar):not(.home.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-6aa21345]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-6aa21345]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-6aa21345]{padding:0}}.container[data-v-6aa21345]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-6aa21345],.container>.content[data-v-6aa21345]{pointer-events:none}.container[data-v-6aa21345] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-6aa21345]{max-width:100%}}.title[data-v-6aa21345]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-6aa21345]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-6aa21345]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-6aa21345]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-6aa21345]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-6aa21345]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-6aa21345]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.home.top) .content-body[data-v-6aa21345]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-6aa21345]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-6aa21345]{column-gap:.5rem}}.menu+.translations[data-v-6aa21345]:before,.menu+.appearance[data-v-6aa21345]:before,.menu+.social-links[data-v-6aa21345]:before,.translations+.appearance[data-v-6aa21345]:before,.appearance+.social-links[data-v-6aa21345]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-6aa21345]:before,.translations+.appearance[data-v-6aa21345]:before{margin-right:16px}.appearance+.social-links[data-v-6aa21345]:before{margin-left:16px}.social-links[data-v-6aa21345]{margin-right:-8px}.divider[data-v-6aa21345]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-6aa21345]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-6aa21345]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-6aa21345]{width:100%;height:1px;transition:background-color .5s}.VPNavBar:not(.home) .divider-line[data-v-6aa21345]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.home.top) .divider-line[data-v-6aa21345]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-6aa21345]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-b44890b2]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-b44890b2]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-7f31e1f6]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-7f31e1f6]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-19976ae1]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-19976ae1]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-8133b170]{display:block}.title[data-v-8133b170]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-b9ab8c58]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-b9ab8c58]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-b9ab8c58]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-b9ab8c58]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-b9ab8c58]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-b9ab8c58]{transform:rotate(45deg)}.button[data-v-b9ab8c58]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-b9ab8c58]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-b9ab8c58]{transition:transform .25s}.group[data-v-b9ab8c58]:first-child{padding-top:0}.group+.group[data-v-b9ab8c58],.group+.item[data-v-b9ab8c58]{padding-top:4px}.VPNavScreenTranslations[data-v-858fe1a4]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-858fe1a4]{height:auto}.title[data-v-858fe1a4]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-858fe1a4]{font-size:16px}.icon.lang[data-v-858fe1a4]{margin-right:8px}.icon.chevron[data-v-858fe1a4]{margin-left:4px}.list[data-v-858fe1a4]{padding:4px 0 0 24px}.link[data-v-858fe1a4]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-f2779853]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px));right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .25s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-f2779853],.VPNavScreen.fade-leave-active[data-v-f2779853]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-f2779853],.VPNavScreen.fade-leave-active .container[data-v-f2779853]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-f2779853],.VPNavScreen.fade-leave-to[data-v-f2779853]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-f2779853],.VPNavScreen.fade-leave-to .container[data-v-f2779853]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-f2779853]{display:none}}.container[data-v-f2779853]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-f2779853],.menu+.appearance[data-v-f2779853],.translations+.appearance[data-v-f2779853]{margin-top:24px}.menu+.social-links[data-v-f2779853]{margin-top:16px}.appearance+.social-links[data-v-f2779853]{margin-top:16px}.VPNav[data-v-ae24b3ad]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-ae24b3ad]{position:fixed}}.VPSidebarItem.level-0[data-v-b7550ba0]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-b7550ba0]{padding-bottom:10px}.item[data-v-b7550ba0]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-b7550ba0]{cursor:pointer}.indicator[data-v-b7550ba0]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-b7550ba0],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-b7550ba0],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-b7550ba0],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-b7550ba0]{background-color:var(--vp-c-brand-1)}.link[data-v-b7550ba0]{display:flex;align-items:center;flex-grow:1}.text[data-v-b7550ba0]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-b7550ba0]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-b7550ba0],.VPSidebarItem.level-2 .text[data-v-b7550ba0],.VPSidebarItem.level-3 .text[data-v-b7550ba0],.VPSidebarItem.level-4 .text[data-v-b7550ba0],.VPSidebarItem.level-5 .text[data-v-b7550ba0]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-b7550ba0],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-b7550ba0],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-b7550ba0],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-b7550ba0],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-b7550ba0],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-b7550ba0]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-b7550ba0],.VPSidebarItem.level-1.has-active>.item>.text[data-v-b7550ba0],.VPSidebarItem.level-2.has-active>.item>.text[data-v-b7550ba0],.VPSidebarItem.level-3.has-active>.item>.text[data-v-b7550ba0],.VPSidebarItem.level-4.has-active>.item>.text[data-v-b7550ba0],.VPSidebarItem.level-5.has-active>.item>.text[data-v-b7550ba0],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-b7550ba0],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-b7550ba0],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-b7550ba0],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-b7550ba0],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-b7550ba0],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-b7550ba0]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-b7550ba0],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-b7550ba0],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-b7550ba0],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-b7550ba0],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-b7550ba0],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-b7550ba0]{color:var(--vp-c-brand-1)}.caret[data-v-b7550ba0]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-b7550ba0]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-b7550ba0]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-b7550ba0]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-b7550ba0]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-b7550ba0],.VPSidebarItem.level-2 .items[data-v-b7550ba0],.VPSidebarItem.level-3 .items[data-v-b7550ba0],.VPSidebarItem.level-4 .items[data-v-b7550ba0],.VPSidebarItem.level-5 .items[data-v-b7550ba0]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-b7550ba0]{display:none}.no-transition[data-v-c40bc020] .caret-icon{transition:none}.group+.group[data-v-c40bc020]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-c40bc020]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSidebar[data-v-319d5ca6]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-319d5ca6]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-319d5ca6]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-319d5ca6]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-319d5ca6]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-319d5ca6]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-319d5ca6]{outline:0}.VPSkipLink[data-v-0f60ec36]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-0f60ec36]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-0f60ec36]{top:14px;left:16px}}.Layout[data-v-5d98c3a5]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-3d121b4a]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-3d121b4a]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{margin:128px 0}}.VPHomeSponsors[data-v-3d121b4a]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 64px}}.container[data-v-3d121b4a]{margin:0 auto;max-width:1152px}.love[data-v-3d121b4a]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-3d121b4a]{display:inline-block}.message[data-v-3d121b4a]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-3d121b4a]{padding-top:32px}.action[data-v-3d121b4a]{padding-top:40px;text-align:center}.VPTeamPage[data-v-7c57f839]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-7c57f839]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-7c57f839-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-7c57f839-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:96px}}.VPTeamMembers[data-v-7c57f839-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 64px}}.VPTeamPageTitle[data-v-bf2cbdac]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:80px 64px 48px}}.title[data-v-bf2cbdac]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-bf2cbdac]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-bf2cbdac]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-bf2cbdac]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-b1a88750]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-b1a88750]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-b1a88750]{padding:0 64px}}.title[data-v-b1a88750]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-b1a88750]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-b1a88750]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-b1a88750]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-b1a88750]{padding-top:40px}.VPTeamMembersItem[data-v-f3fa364a]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-f3fa364a]{padding:32px}.VPTeamMembersItem.small .data[data-v-f3fa364a]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-f3fa364a]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-f3fa364a]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-f3fa364a]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-f3fa364a]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-f3fa364a]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-f3fa364a]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-f3fa364a]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-f3fa364a]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-f3fa364a]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-f3fa364a]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-f3fa364a]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-f3fa364a]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-f3fa364a]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-f3fa364a]{text-align:center}.avatar[data-v-f3fa364a]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-f3fa364a]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-f3fa364a]{margin:0;font-weight:600}.affiliation[data-v-f3fa364a]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-f3fa364a]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-f3fa364a]:hover{color:var(--vp-c-brand-1)}.desc[data-v-f3fa364a]{margin:0 auto}.desc[data-v-f3fa364a] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-f3fa364a]{display:flex;justify-content:center;height:56px}.sp-link[data-v-f3fa364a]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-f3fa364a]:hover,.sp .sp-link.link[data-v-f3fa364a]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-f3fa364a]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-6cb0dbc4]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-6cb0dbc4]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-6cb0dbc4]{max-width:876px}.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-6cb0dbc4]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-6cb0dbc4]{max-width:760px}.container[data-v-6cb0dbc4]{display:grid;gap:24px;margin:0 auto;max-width:1152px}.VPLocalSearchBox[data-v-797a7f7c]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-797a7f7c]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-797a7f7c]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 767px){.shell[data-v-797a7f7c]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-797a7f7c]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 767px){.search-bar[data-v-797a7f7c]{padding:0 8px}}.search-bar[data-v-797a7f7c]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-797a7f7c]{display:block;font-size:18px}.navigate-icon[data-v-797a7f7c]{display:block;font-size:14px}.search-icon[data-v-797a7f7c]{margin:8px}@media (max-width: 767px){.search-icon[data-v-797a7f7c]{display:none}}.search-input[data-v-797a7f7c]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-797a7f7c]{padding:6px 4px}}.search-actions[data-v-797a7f7c]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-797a7f7c]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-797a7f7c]{display:none}}.search-actions button[data-v-797a7f7c]{padding:8px}.search-actions button[data-v-797a7f7c]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-797a7f7c]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-797a7f7c]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-797a7f7c]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-797a7f7c]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-797a7f7c]{display:none}}.search-keyboard-shortcuts kbd[data-v-797a7f7c]{background:#8080801a;border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-797a7f7c]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-797a7f7c]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-797a7f7c]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-797a7f7c]{margin:8px}}.titles[data-v-797a7f7c]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-797a7f7c]{display:flex;align-items:center;gap:4px}.title.main[data-v-797a7f7c]{font-weight:500}.title-icon[data-v-797a7f7c]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-797a7f7c]{opacity:.5}.result.selected[data-v-797a7f7c]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-797a7f7c]{position:relative}.excerpt[data-v-797a7f7c]{opacity:50%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;margin-top:4px}.result.selected .excerpt[data-v-797a7f7c]{opacity:1}.excerpt[data-v-797a7f7c] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-797a7f7c] mark,.excerpt[data-v-797a7f7c] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-797a7f7c] .vp-code-group .tabs{display:none}.excerpt[data-v-797a7f7c] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-797a7f7c]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-797a7f7c]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-797a7f7c],.result.selected .title-icon[data-v-797a7f7c]{color:var(--vp-c-brand-1)!important}.no-results[data-v-797a7f7c]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-797a7f7c]{flex:none} diff --git a/components/i18n-link.html b/components/i18n-link.html new file mode 100644 index 0000000..a9b4c90 --- /dev/null +++ b/components/i18n-link.html @@ -0,0 +1,29 @@ + + + + + + 🌍 <i18n-link> Component | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/components/i18n-switcher.html b/components/i18n-switcher.html new file mode 100644 index 0000000..cfbed7b --- /dev/null +++ b/components/i18n-switcher.html @@ -0,0 +1,38 @@ + + + + + + 🌍 <i18n-switcher> Component | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

Here’s the updated documentation for the <i18n-switcher> component, reflecting the transition to using inline styles with support for dynamic customization through props:


🌍 <i18n-switcher> Component

The <i18n-switcher> component in Nuxt I18n Micro provides a user-friendly dropdown interface for switching between different locales in your application. This component is highly customizable, allowing seamless integration with your application's design and layout.

⚙️ Props

customLabels

  • Type: Record<string, string>
  • Default: {}
  • Description: Allows you to define custom labels for each locale, which will be displayed instead of the locale codes.
  • Example:
    vue
    <i18n-switcher :customLabels="{ en: 'English', fr: 'Français' }"></i18n-switcher>

customWrapperStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to override the default styles applied to the wrapper <div> that contains the locale switcher.
  • Example:
    vue
    <i18n-switcher :customWrapperStyle="{ backgroundColor: '#f8f9fa', padding: '10px' }"></i18n-switcher>

customButtonStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to customize the styles applied to the button element that toggles the dropdown menu.
  • Example:
    vue
    <i18n-switcher :customButtonStyle="{ backgroundColor: '#007bff', color: '#fff', borderRadius: '4px' }"></i18n-switcher>

customDropdownStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Sets the custom styles for the <ul> element that contains the list of locales.
  • Example:
    vue
    <i18n-switcher :customDropdownStyle="{ border: '1px solid #007bff', boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }"></i18n-switcher>

customItemStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Applies custom styles to each <li> element representing a locale option.
  • Example:
    vue
    <i18n-switcher :customItemStyle="{ margin: '5px 0', padding: '5px' }"></i18n-switcher>

customLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Allows you to customize the styles applied to the <NuxtLink> elements used to switch between locales.
  • Example:
    vue
    <i18n-switcher :customLinkStyle="{ padding: '8px 16px', color: '#333', textDecoration: 'none' }"></i18n-switcher>

customActiveLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Sets the custom styles for the currently active locale, usually to highlight or indicate the selected option.
  • Example:
    vue
    <i18n-switcher :customActiveLinkStyle="{ color: 'green', fontWeight: 'bold', backgroundColor: '#f0f0f0' }"></i18n-switcher>

customDisabledLinkStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Applies custom styles to disable the link for the current locale, preventing users from selecting it.
  • Example:
    vue
    <i18n-switcher :customDisabledLinkStyle="{ color: 'gray', cursor: 'not-allowed' }"></i18n-switcher>

customIconStyle

  • Type: CSSProperties
  • Default: {}
  • Description: Defines custom styles for the icon that indicates the dropdown state, such as rotating the icon when the dropdown is opened or closed.
  • Example:
    vue
    <i18n-switcher :customIconStyle="{ fontSize: '20px', color: '#007bff' }"></i18n-switcher>

🛠️ Example Usages

Basic Usage

vue
<template>
+  <i18n-switcher />
+</template>

This renders a locale switcher with default styling and behavior.

Custom Labels and Inline Styles

vue
<template>
+  <i18n-switcher
+    :customLabels="{ en: 'English', fr: 'Français' }"
+    :customWrapperStyle="{ backgroundColor: '#f8f9fa', padding: '10px' }"
+    :customButtonStyle="{ backgroundColor: '#007bff', color: '#fff', borderRadius: '4px' }"
+    :customDropdownStyle="{ border: '1px solid #007bff', boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }"
+    :customItemStyle="{ margin: '5px 0', padding: '5px' }"
+    :customLinkStyle="{ padding: '8px 16px', color: '#333', textDecoration: 'none' }"
+    :customActiveLinkStyle="{ color: 'green', fontWeight: 'bold', backgroundColor: '#f0f0f0' }"
+    :customDisabledLinkStyle="{ color: 'gray', cursor: 'not-allowed' }"
+    :customIconStyle="{ fontSize: '20px', color: '#007bff' }"
+  />
+</template>

This example demonstrates a fully customized locale switcher with custom labels and inline styles.

🎨 Styles Overview

The <i18n-switcher> component comes with basic styles defined using inline styles that can easily be overridden by passing custom styles via props. Here’s a brief overview of the default styling:

  • Wrapper: Controls the positioning of the dropdown.
  • Button: Styles the dropdown toggle button.
  • Dropdown: Styles the dropdown list.
  • Items: Styles each item in the list.
  • Links: Styles the links inside each item.
  • Icon: Styles the dropdown indicator icon.

You can customize these styles by passing custom styles through the respective props, ensuring that the locale switcher integrates seamlessly into your application's UI.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/components/i18n-t.html b/components/i18n-t.html new file mode 100644 index 0000000..c10dfe6 --- /dev/null +++ b/components/i18n-t.html @@ -0,0 +1,54 @@ + + + + + + 🌍 <i18n-t> Component | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🌍 <i18n-t> Component

The <i18n-t> component in Nuxt I18n Micro is a flexible translation component that supports dynamic content insertion via slots. It allows you to interpolate translations with custom Vue components or HTML content, enabling advanced localization scenarios.

⚙️ Props

keypath

  • Type: string
  • Required: Yes
  • Description: Defines the key path to the translation string in your localization files.
  • Example:
    vue
    <i18n-t keypath="feedback.text" />

plural

  • Type: number | string
  • Optional: Yes
  • Description: Specifies a number for pluralization rules.
  • Example:
    vue
    <i18n-t keypath="items" :plural="itemCount" />

tag

  • Type: string
  • Optional: Yes
  • Default: 'span'
  • Description: Specifies the HTML tag to wrap the translated content.
  • Example:
    vue
    <i18n-t keypath="feedback.text" tag="div" />

params

  • Type: Record<string, string | number | boolean>
  • Optional: Yes
  • Description: Provides parameters for interpolating dynamic values in the translation.
  • Example:
    vue
    <i18n-t keypath="user.greeting" :params="{ name: userName }" />

defaultValue

  • Type: string
  • Optional: Yes
  • Description: The default value to use if the translation key is not found.
  • Example:
    vue
    <i18n-t keypath="nonExistentKey" defaultValue="Fallback text"></i18n-t>

html

  • Type: boolean
  • Optional: Yes
  • Default: false
  • Description: Enables the rendering of the translation as raw HTML.
  • Example:
    vue
    <i18n-t keypath="feedback.text" html />

hideIfEmpty

  • Type: boolean
  • Optional: Yes
  • Default: false
  • Description: If true, the component will not render anything if the translation is empty.
  • Example:
    vue
    <i18n-t keypath="optionalMessage" :hideIfEmpty="true"></i18n-t>

customPluralRule

  • Type: (value: string, count: number, locale: string) => string
  • Optional: Yes
  • Description: A function that allows you to define custom pluralization logic. Useful if the default pluralization rules do not fit your specific needs.
  • Example:
    vue
    <i18n-t
    +  keypath="items"
    +  :plural="itemCount"
    +  :customPluralRule="(key, count, locale, getTranslation) => {
    +    const translation = getTranslation(key, {})
    +    if (!translation) {
    +      return null
    +    }
    +    return count === 1 ? 'no items' : `${count} ${translation}`;
    +  }"
    +></i18n-t>

🛠️ Example Usages

Basic Usage

vue
<i18n-t keypath="feedback.text" />

This renders the translation for feedback.text within a <span> tag.

Using Slots for Dynamic Content

The <i18n-t> component supports the use of slots to dynamically insert Vue components or other content into specific parts of the translation.

vue
<i18n-t keypath="feedback.text">
+  <template #link>
+    <nuxt-link :to="{ name: 'index' }">
+      <i18n-t keypath="feedback.link" />
+    </nuxt-link>
+  </template>
+</i18n-t>

In this example, the {link} placeholder in the feedback.text translation string is replaced by the <nuxt-link> component, which itself contains another translation component.

Pluralization

vue
<i18n-t keypath="items.count" :plural="itemCount" />

This automatically applies pluralization rules based on the itemCount value.

🚀 Additional Features

Default Slot

If no specific slot is provided, the translation can be customized via the default slot, which provides the entire translated string:

vue
<i18n-t keypath="welcome.message">
+  <template #default="{ translation }">
+    {{ translation.replace('Nuxt', 'Vue') }}
+  </template>
+</i18n-t>

Conditional Rendering

Render nothing if the translation string is empty by using the hideIfEmpty prop.

vue
<i18n-t keypath="optionalMessage" :hideIfEmpty="true"></i18n-t>

Custom Pluralization Rule

Use a custom function to handle pluralization.

vue
<i18n-t
+  keypath="items"
+  :plural="itemCount"
+  :customPluralRule="(key, value, count, locale) => {
+    return count === 1 ? 'One item' : `${count} items`;
+  }}"
+></i18n-t>

Advanced Example with Slots

Utilize slots to customize how the translation content is rendered.

vue
<i18n-t keypath="welcomeMessage">
+  <template #default="{ translation }">
+    <strong>{{ translation }}</strong>
+  </template>
+</i18n-t>

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/composables/useI18n.html b/composables/useI18n.html new file mode 100644 index 0000000..021e913 --- /dev/null +++ b/composables/useI18n.html @@ -0,0 +1,46 @@ + + + + + + 🛠️ useI18n Composable | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🛠️ useI18n Composable

The useI18n composable in Nuxt I18n Micro is designed to provide an easy and efficient way to access internationalization functionalities within your Nuxt application. It offers a variety of methods to handle localization, translation, and route management based on the current locale.

All methods can be accessed both with and without the $ prefix for convenience.

⚙️ Return Values

The useI18n composable returns an object containing several key methods and properties for managing internationalization:

$getLocale

  • Type: () => string
  • Description: Returns the current locale of the application.
  • Example:
    js
    const { $getLocale } = useI18n()
    +const locale = $getLocale()
    +console.log(locale) // e.g., 'en'

🌍 $getLocaleName

Version introduced: v1.28.0

  • Type: () => string | null
  • Description: Returns the current locale name from displayName config.
  • Example:
typescript
const locale = $getLocaleName()
+// Output: 'English'

$getLocales

  • Type: () => Locale[]
  • Description: Returns an array of all available locales in the application.
  • Example:
    js
    const { $getLocales } = useI18n()
    +const locales = $getLocales()
    +console.log(locales) // e.g., [{ code: 'en', iso: 'en-US' }, { code: 'fr', iso: 'fr-FR' }]

$t

  • Type: <T extends Record<string, string | number | boolean>>(key: string, params?: T, defaultValue?: string) => string | number | boolean | Translations | PluralTranslations | unknown[] | unknown | null
  • Description: Translates a given key to the corresponding localized string, optionally replacing placeholders with provided parameters and falling back to a default value if the key is not found.
  • Example:
    js
    const { $t } = useI18n()
    +const greeting = $t('hello', { name: 'John' }, 'Hello!')
    +console.log(greeting) // e.g., 'Hello, John'

$tc

  • Type: (key: string, count: number, defaultValue?: string) => string
  • Description: Translates a given key with pluralization based on the provided count, optionally falling back to a default value if the key is not found.
  • Example:
    js
    const { $tc } = useI18n()
    +const message = $tc('apples', 3, '3 apples')
    +console.log(message) // e.g., '3 apples'

$has

  • Type: (key: string) => boolean
  • Description: Checks if a translation key exists for the current locale.
  • Example:
    js
    const { $has } = useI18n()
    +const exists = $has('hello')
    +console.log(exists) // e.g., true

$mergeTranslations

  • Type: (newTranslations: Translations) => void
  • Description: Merges additional translations into the existing ones for the current locale.
  • Example:
    js
    const { $mergeTranslations } = useI18n()
    +$mergeTranslations({
    +  hello: 'Hello World',
    +})

$switchLocale

  • Type: (locale: string) => void
  • Description: Switches the application's locale to the specified locale.
  • Example:
    js
    const { $switchLocale } = useI18n()
    +$switchLocale('fr')

$localeRoute

  • Type: (to: RouteLocationRaw, locale?: string) => RouteLocationRaw
  • Description: Generates a localized route based on the specified route and optionally the specified locale.
  • Example:
    js
    const { $localeRoute } = useI18n()
    +const route = $localeRoute('/about', 'fr')

$loadPageTranslations

  • Type: (locale: string, routeName: string) => Promise<void>
  • Description: Loads translations for the specified page and locale, enabling lazy-loading of translations.
  • Example:
    js
    const { $loadPageTranslations } = useI18n()
    +await $loadPageTranslations('fr', 'home')

🛠️ Example Usages

Basic Locale Retrieval

Retrieve the current locale of the application.

js
const { $getLocale } = useI18n()
+const locale = $getLocale()

Translation with Parameters

Translate a string with dynamic parameters, with a fallback default value.

js
const { $t } = useI18n()
+const welcomeMessage = $t('welcome', { name: 'Jane' }, 'Welcome!')

Switching Locales

Switch the application to a different locale.

js
const { $switchLocale } = useI18n()
+$switchLocale('de')

Generating a Localized Route

Generate a route localized to the current or specified locale.

js
const { $localeRoute } = useI18n()
+const route = $localeRoute('/about', 'fr')

Loading Page-Specific Translations

Lazy-load translations for a specific page and locale.

js
const { $loadPageTranslations } = useI18n()
+await $loadPageTranslations('de', 'dashboard')

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/composables/useLocaleHead.html b/composables/useLocaleHead.html new file mode 100644 index 0000000..2575ed5 --- /dev/null +++ b/composables/useLocaleHead.html @@ -0,0 +1,44 @@ + + + + + + 🌍 useLocaleHead Composable | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🌍 useLocaleHead Composable

The useLocaleHead composable is a utility in Nuxt I18n Micro that helps you manage SEO attributes and HTML meta tags for localized routes. It dynamically generates attributes for the lang and dir of the HTML document and creates meta and link tags to improve the SEO of your localized content.

⚙️ Options

The useLocaleHead composable accepts an options object to customize its behavior:

addDirAttribute

  • Type: boolean
  • Default: true
  • Description: If true, adds the dir attribute to the HTML document based on the current locale's direction (ltr or rtl).
  • Example:
    js
    const head = useLocaleHead({ addDirAttribute: false })

identifierAttribute

  • Type: string
  • Default: 'id'
  • Description: Specifies the attribute used to identify the generated meta and link tags. This is useful for differentiating tags when inspecting the document head.
  • Example:
    js
    const head = useLocaleHead({ identifierAttribute: 'data-i18n' })

addSeoAttributes

  • Type: boolean
  • Default: true
  • Description: If true, includes SEO-related meta and link tags, such as og:locale, og:url, and hreflang attributes for alternate languages.
  • Example:
    js
    const head = useLocaleHead({ addSeoAttributes: false })

baseUrl

  • Type: string
  • Default: '/'
  • Description: The base URL of your application, used to generate canonical and alternate URLs for SEO purposes.
  • Example:
    js
    const head = useLocaleHead({ baseUrl: 'https://example.com' })

🛠️ Return Values

The useLocaleHead composable returns an object with htmlAttrs, meta, and link properties, which can be directly used in the <head> section of your Nuxt application.

htmlAttrs

  • Type: Record<string, string>
  • Description: Contains attributes to be added to the <html> tag, such as lang and dir.
  • Example:
    js
    const { htmlAttrs } = useLocaleHead()
    +console.log(htmlAttrs)
    +// Output: { lang: 'en-US', dir: 'ltr' }

meta

  • Type: Array<Record<string, string>>
  • Description: Contains meta tags for SEO, including Open Graph locale tags and alternate locales.
  • Example:
    js
    const { meta } = useLocaleHead()
    +console.log(meta)
    +// Output: [{ id: 'i18n-og', property: 'og:locale', content: 'en-US' }, ...]
  • Type: Array<Record<string, string>>
  • Description: Contains link tags for canonical URLs and alternate language versions of the page.
  • Example:
    js
    const { link } = useLocaleHead()
    +console.log(link)
    +// Output: [{ id: 'i18n-can', rel: 'canonical', href: 'https://example.com/about' }, ...]

🛠️ Example Usages

Basic Usage

Generate locale-specific head attributes with default options.

js
const head = useLocaleHead()

Customize Identifier Attribute

Use a custom identifier attribute for the generated tags.

js
const head = useLocaleHead({ identifierAttribute: 'data-i18n' })

Disable SEO Attributes

Generate head attributes without adding SEO-related meta and link tags.

js
const head = useLocaleHead({ addSeoAttributes: false })

Specify a Base URL

Set a custom base URL for canonical and alternate URLs.

js
const head = useLocaleHead({ baseUrl: 'https://mywebsite.com' })

🚀 Additional Features

When addSeoAttributes is enabled, the composable automatically generates the following tags:

  • og:locale for the current locale.
  • og:url for the canonical URL of the page.
  • og:locale:alternate for alternate language versions.
  • rel="canonical" and rel="alternate" links for SEO optimization.

Dynamic Locale and Direction

The composable dynamically determines the lang and dir attributes based on the current route's locale, ensuring that your HTML document is correctly configured for international users.

Handling Localized Routes

If your routes are prefixed with locale codes (e.g., /en/about), the composable intelligently adjusts the full path for generating URLs, ensuring that SEO attributes are accurate and relevant.

This composable simplifies the process of optimizing your Nuxt application for international audiences, ensuring that your site is well-prepared for global search engines and users.

🛠️ Example Usage

The following example demonstrates how to use the useLocaleHead composable within a Vue component with default settings:

vue
<script setup>
+const head = useLocaleHead({
+  addDirAttribute: true,
+  identifierAttribute: 'id',
+  addSeoAttributes: true,
+})
+
+useHead(head)
+</script>
+
+<template>
+  <div>
+    
+  </div>
+</template>

Explanation of the Code

  • useLocaleHead Composable: This composable is called in the <script setup> section and returns an object containing htmlAttrs, meta, and link.

  • <html> Tag: The lang and dir attributes for the HTML document are dynamically determined based on the current locale and are applied to the <html> tag.

  • <head> Section:

    • Meta Tags: SEO-related meta tags are generated, including og:locale, og:url, and rel="canonical" and rel="alternate" tags to specify alternate language versions of the page.
    • Link Tags: Canonical links and links to alternate language versions are included.
  • <body> Section: The main content of the page is displayed here. In this example, a simple header and paragraph are used.

📝 Notes

  1. Attributes: The attributes used (lang, dir, rel, href, hreflang, property, content) are extracted from the object returned by useLocaleHead.

  2. SEO Tags Generation: If the addSeoAttributes option is set to true, the composable automatically generates SEO tags for the current locale.

  3. Base URL: You can set your custom base URL using the baseUrl option to correctly generate canonical and alternate links.

This example demonstrates how easy it is to integrate useLocaleHead into your application's components to ensure correct SEO attributes and improve the search engine indexing of localized pages.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/examples.html b/examples.html new file mode 100644 index 0000000..5c8e0dc --- /dev/null +++ b/examples.html @@ -0,0 +1,269 @@ + + + + + + 📚 Nuxt I18n Micro Examples and Usage | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

📚 Nuxt I18n Micro Examples and Usage

This section provides various examples demonstrating how to use Nuxt I18n Micro in your Nuxt.js application. You'll see how to switch locales, use the <i18n-link>, <i18n-switcher>, and <i18n-t> components, and dynamically handle translation keys.

🛠️ Basic Setup

Here's a basic setup to get started with Nuxt I18n Micro:

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: false, displayName: 'English' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr', disabled: false, displayName: 'Français' },
+      { code: 'de', iso: 'de-DE', dir: 'ltr', disabled: false, displayName: 'Deutsch' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

🌍 Locale Switching

Switching Locales Programmatically

This example demonstrates how to switch locales programmatically using buttons:

vue
<template>
+  <div>
+    <p>Current Locale: {{ $getLocale() }}</p>
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale.code"
+        :disabled="locale.code === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ $t(locale.code) }}
+      </button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>

Example JSON for Locale Switching

json
{
+  "en": "English",
+  "fr": "Français",
+  "de": "Deutsch"
+}

Using <i18n-switcher> Component

The <i18n-switcher> component provides a dropdown for locale switching with customizable labels:

vue
<template>
+  <div>
+    <i18n-switcher
+      :custom-labels="{ en: 'English', fr: 'Français', de: 'Deutsch' }"
+    />
+  </div>
+</template>

The <i18n-link> component automatically handles locale-specific routing:

vue
<template>
+  <div>
+    <i18n-link to="/about">{{ $t('about') }}</i18n-link>
+    <i18n-link :to="{ name: 'index' }">{{ $t('home') }}</i18n-link>
+  </div>
+</template>
+
+<script setup>
+  import { useNuxtApp } from '#imports'
+
+  const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>
json
{
+  "about": "About Us",
+  "home": "Home"
+}
vue
<template>
+  <div>
+    <i18n-link to="/about" activeClass="current">About Us</i18n-link>
+  </div>
+</template>

The same JSON file can be used as in the previous example for this scenario.

📝 Rendering Dynamic Keys from Translation Files

In some scenarios, you may want to iterate over dynamic keys stored within your translation files and render their values conditionally. The example below demonstrates how to achieve this using Nuxt I18n Micro.

Example: Rendering Dynamic Keys

This example fetches an array of keys from a specific translation path (in this case, dynamic) and iterates over them. Each key is checked for its existence using $has before rendering its value with $t.

vue
<template>
+  <div>
+    <div
+      v-for="key in $t('dynamic')"
+      :key="key"
+    >
+      <p>{{ key }}: <span v-if="$has(key)">{{ $t(key) }}</span></p>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $t, $has } = useNuxtApp()
+</script>

Example Translation File (en.json)

json
{
+  "dynamic": ["key1", "key2", "key3"],
+  "key1": "This is the first key's value",
+  "key2": "This is the second key's value",
+  "key3": "This is the third key's value"
+}

Example: Rendering Dynamic Keys from an Object

In this example, we handle an object stored within your translation file. We fetch and iterate over the keys of the object, dynamically rendering both the key names and their associated values.

vue
<template>
+  <div>
+    <div v-for="(value, key) in $t('dynamicObject')" :key="key">
+      <p>{{ key }}: {{ value }}</p>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $t } = useNuxtApp()
+</script>

Example Translation File (en.json)

json
{
+  "dynamicObject": {
+    "title": "Welcome to our site",
+    "description": "This is a brief description of our services.",
+    "footerNote": "Thank you for visiting!"
+  }
+}

🌟 Using <i18n-t> for Translations with Slots and Interpolation

The <i18n-t> component is useful for rendering translations with dynamic content and HTML tags:

vue
<template>
+  <i18n-t keypath="greeting" tag="h1">
+    <template #default="{ translation }">
+      <strong>{{ translation.replace('page', 'page replace') }}</strong> <i>!!!</i>
+    </template>
+  </i18n-t>
+</template>

Example JSON for <i18n-t>

json
{
+  "greeting": "Welcome to the page"
+}

With Interpolation

vue
<template>
+  <i18n-t keypath="welcome" :params="{ username: 'Alice', unreadCount: 5 }"></i18n-t>
+</template>

Example JSON for Interpolation

json
{
+  "welcome": "Hello {username}, you have {unreadCount} unread messages."
+}

📝 Comprehensive Example with Nested Sections

Here's a complex structure demonstrating multiple translation uses within a single page:

vue
<template>
+  <div>
+    <h1>{{ $t('mainHeader') }}</h1>
+
+    <nav>
+      <ul>
+        <li><a href="#">{{ $t('nav.home') }}</a></li>
+        <li><a href="#">{{ $t('nav.about') }}</a></li>
+        <li><a href="#">{{ $t('nav.services') }}</a></li>
+        <li><a href="#">{{ $t('nav.contact') }}</a></li>
+      </ul>
+    </nav>
+
+    <section>
+      <h2>{{ $t('section1.header') }}</h2>
+      <p>{{ $t('section1.intro') }}</p>
+
+      <div>
+        <h3>{{ $t('section1.subsection1.header') }}</h3>
+        <p>{{ $t('section1.subsection1.content') }}</p>
+      </div>
+
+      <div>
+        <h3>{{ $t('section1.subsection2.header') }}</h3>
+        <ul>
+          <li>{{ $t('section1.subsection2.item1') }}</li>
+          <li>{{ $t('section1.subsection2.item2') }}</li>
+          <li>{{ $t('section1.subsection2.item3') }}</li>
+        </ul>
+      </div>
+    </section>
+
+    <footer>
+      <h4>{{ $t('footer.contact.header') }}</h4>
+      <address>
+        {{ $t('footer.contact.address') }}<br>
+        {{ $t('footer.contact.city') }}<br>
+        {{ $t('footer.contact.phone') }}
+      </address>
+    </footer>
+
+    <div>
+      <button
+        v-for="locale in $getLocales()"
+        :key="locale.code"
+        :disabled="locale.code === $getLocale()"
+        @click="() => $switchLocale(locale.code)"
+      >
+        Switch to {{ locale.code }}
+      </button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $t } = useNuxtApp()
+</script>

Example JSON for Nested Sections

json
{
+  "mainHeader": "Welcome to Our Services",
+  "nav": {
+    "home": "Home",
+    "about": "About Us",
+    "services": "Services",
+    "contact": "Contact"
+  },
+  "section1": {
+    "header": "Our Expertise",
+    "intro": "We provide a wide range of services to meet your needs.",
+    "subsection1": {
+      "header": "Consulting",
+      "content": "Our team offers expert consulting services in various domains."
+    },
+    "subsection2": {
+      "header": "Development",
+      "item1":
+
+ "Web Development",
+      "item2": "Mobile Apps",
+      "item3": "Custom Software"
+    }
+  },
+  "footer": {
+    "contact": {
+      "header": "Contact Us",
+      "address": "123 Main Street",
+      "city": "Anytown, USA",
+      "phone": "+1 (555) 123-4567"
+    }
+  }
+}

🌟 Using $tc for Pluralization

The $tc function in Nuxt I18n Micro handles pluralization based on the count and locale settings. This is useful for dynamically adjusting messages that involve counts, such as items, notifications, or other entities that can vary in number.

Example: Using $tc for Pluralization

In the following example, we display a message indicating the number of apples using $tc. The translation key handles multiple plural forms based on the count provided.

vue
<template>
+  <div>
+    <!-- Display a pluralized message about the number of apples -->
+    <p>{{ $tc('apples', 0) }}</p>  <!-- Outputs: no apples -->
+    <p>{{ $tc('apples', 1) }}</p>  <!-- Outputs: one apple -->
+    <p>{{ $tc('apples', 10) }}</p> <!-- Outputs: 10 apples -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $tc } = useNuxtApp()
+</script>

Example JSON for Pluralization

Here's how you can define the translation in your JSON file to handle different plural forms:

json
{
+  "apples": "no apples | one apple | {count} apples"
+}

Explanation

  • $tc('apples', 0): Returns the first form, used when the count is zero ("no apples").
  • $tc('apples', 1): Returns the second form, used when the count is one ("one apple").
  • $tc('apples', 10): Returns the third form with the count value, used when the count is two or more ("10 apples").

Additional Example with More Complex Pluralization

If your application needs to handle more complex pluralization rules (e.g., specific cases for zero, one, two, few, many, other), you can extend the translation strings accordingly:

json
{
+  "apples": "no apples | one apple | two apples | a few apples | many apples | {count} apples"
+}
  • $tc('apples', 2): Could be set up to return "two apples".
  • $tc('apples', 3): Could return "a few apples", depending on the rules defined for the count.

🌐 Using $tn for Number Formatting

The $tn function formats numbers according to the current locale using the Intl.NumberFormat API. This is useful for displaying numbers in a way that matches the user's regional settings, such as currency, percentages, or other number formats.

Example: Using $tn for Number Formatting

vue
<template>
+  <div>
+    <!-- Format a number as currency -->
+    <p>{{ $tn(1234567.89, { style: 'currency', currency: 'USD' }) }}</p> <!-- Outputs: $1,234,567.89 in 'en-US' locale -->
+
+    <!-- Format a number with custom options -->
+    <p>{{ $tn(0.567, { style: 'percent', minimumFractionDigits: 1 }) }}</p> <!-- Outputs: 56.7% in 'en-US' locale -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $tn } = useNuxtApp()
+</script>

Example JSON for Number Formatting (No JSON needed for number formatting directly)

🗓️ Using $td for Date and Time Formatting

The $td function formats dates and times according to the current locale using the Intl.DateTimeFormat API. This is useful for displaying dates and times in formats that are familiar to the user based on their locale settings.

Example: Using $td for Date and Time Formatting

vue
<template>
+  <div>
+    <!-- Format a date with full options -->
+    <p>{{ $td(new Date(), { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) }}</p> <!-- Outputs: "Friday, September 1, 2023" in 'en-US' locale -->
+
+    <!-- Format a date with time -->
+    <p>{{ $td(new Date(), { hour: '2-digit', minute: '2-digit', second: '2-digit' }) }}</p> <!-- Outputs: "10:15:30 AM" in 'en-US' locale -->
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $td } = useNuxtApp()
+</script>

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/cli.html b/guide/cli.html new file mode 100644 index 0000000..61ea8c7 --- /dev/null +++ b/guide/cli.html @@ -0,0 +1,40 @@ + + + + + + 🌐 nuxt-i18n-micro-cli Guide | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🌐 nuxt-i18n-micro-cli Guide

📖 Introduction

nuxt-i18n-micro-cli is a command-line tool designed to streamline the localization and internationalization process in Nuxt.js projects using the nuxt-i18n module. It provides utilities to extract translation keys from your codebase, manage translation files, synchronize translations across locales, and automate the translation process using external translation services.

This guide will walk you through installing, configuring, and using nuxt-i18n-micro-cli to effectively manage your project's translations.

🔧 Installation and Setup

📦 Installing nuxt-i18n-micro-cli

Install nuxt-i18n-micro-cli globally using npm:

bash
npm install -g nuxt-i18n-micro-cli

This will make the i18n-micro command available globally on your system.

🛠 Initializing in Your Project

After installing, you can run i18n-micro commands in your Nuxt.js project directory.

Ensure that your project is set up with nuxt-i18n and has the necessary configuration in nuxt.config.js.

📄 Common Arguments

  • --cwd: Specify the current working directory (defaults to .).
  • --logLevel: Set the log level (silent, info, verbose).
  • --translationDir: Directory containing JSON translation files (default: locales).

📋 Commands

📊 stats Command

Description: The stats command is used to display translation statistics for each locale in your Nuxt.js project. It helps you understand the progress of your translations by showing how many keys are translated compared to the total number of keys available.

Usage:

bash
i18n-micro stats [options]

Options:

  • --full: Display combined translations statistics only (default: false).

Example:

bash
i18n-micro stats --full

🌍 translate Command

Description: The translate command automatically translates missing keys using external translation services. This command simplifies the translation process by leveraging APIs from services like Google Translate, DeepL, and others to fill in missing translations.

Usage:

bash
i18n-micro translate [options]

Options:

  • --service: Translation service to use (e.g., google, deepl, yandex). If not specified, the command will prompt you to select one.
  • --token: API key corresponding to the chosen translation service. If not provided, you will be prompted to enter it.
  • --options: Additional options for the translation service, provided as key:value pairs, separated by commas (e.g., model:gpt-3.5-turbo,max_tokens:1000).
  • --replace: Translate all keys, replacing existing translations (default: false).

Example:

bash
i18n-micro translate --service deepl --token YOUR_DEEPL_API_KEY

🌐 Supported Translation Services

The translate command supports multiple translation services. Some of the supported services are:

  • Google Translate (google)
  • DeepL (deepl)
  • Yandex Translate (yandex)
  • OpenAI (openai)
  • Azure Translator (azure)
  • IBM Watson (ibm)
  • Baidu Translate (baidu)
  • LibreTranslate (libretranslate)
  • MyMemory (mymemory)
  • Lingva Translate (lingvatranslate)
  • Papago (papago)
  • Tencent Translate (tencent)
  • Systran Translate (systran)
  • Yandex Cloud Translate (yandexcloud)
  • ModernMT (modernmt)
  • Lilt (lilt)
  • Unbabel (unbabel)
  • Reverso Translate (reverso)

⚙️ Service Configuration

Some services require specific configurations or API keys. When using the translate command, you can specify the service and provide the required --token (API key) and additional --options if needed.

For example:

bash
i18n-micro translate --service openai --token YOUR_OPENAI_API_KEY --options openaiModel:gpt-3.5-turbo,max_tokens:1000

🛠️ extract Command

Description: Extracts translation keys from your codebase and organizes them by scope.

Usage:

bash
i18n-micro extract [options]

Options:

  • --prod, -p: Run in production mode.

Example:

bash
i18n-micro extract

🔄 sync Command

Description: Synchronizes translation files across locales, ensuring all locales have the same keys.

Usage:

bash
i18n-micro sync [options]

Example:

bash
i18n-micro sync

validate Command

Description: Validates translation files for missing or extra keys compared to the reference locale.

Usage:

bash
i18n-micro validate [options]

Example:

bash
i18n-micro validate

🧹 clean Command

Description: Removes unused translation keys from translation files.

Usage:

bash
i18n-micro clean [options]

Example:

bash
i18n-micro clean

📤 import Command

Description: Converts PO files back to JSON format and saves them in the translation directory.

Usage:

bash
i18n-micro import [options]

Options:

  • --potsDir: Directory containing PO files (default: pots).

Example:

bash
i18n-micro import --potsDir pots

📥 export Command

Description: Exports translations to PO files for external translation management.

Usage:

bash
i18n-micro export [options]

Options:

  • --potsDir: Directory to save PO files (default: pots).

Example:

bash
i18n-micro export --potsDir pots

🗂️ export-csv Command

Description: The export-csv command exports translation keys and values from JSON files, including their file paths, into a CSV format. This command is useful for teams who prefer working with translation data in spreadsheet software.

Usage:

bash
i18n-micro export-csv [options]

Options:

  • --csvDir: Directory where the exported CSV files will be saved.
  • --delimiter: Specify a delimiter for the CSV file (default: ,).

Example:

bash
i18n-micro export-csv --csvDir csv_files

📑 import-csv Command

Description: The import-csv command imports translation data from CSV files, updating the corresponding JSON files. This is useful for applying bulk translation updates from spreadsheets.

Usage:

bash
i18n-micro import-csv [options]

Options:

  • --csvDir: Directory containing the CSV files to be imported.
  • --delimiter: Specify a delimiter used in the CSV file (default: ,).

Example:

bash
i18n-micro import-csv --csvDir csv_files

🧾 diff Command

Description: Compares translation files between the default locale and other locales within the same directory (including subdirectories). The command identifies missing keys and their values in the default locale compared to other locales, making it easier to track translation progress or discrepancies.

Usage:

bash
i18n-micro diff [options]

Example:

bash
i18n-micro diff

🔍 check-duplicates Command

Description: The check-duplicates command checks for duplicate translation values within each locale across all translation files, including both global and page-specific translations. It ensures that different keys within the same language do not share identical translation values, helping maintain clarity and consistency in your translations.

Usage:

bash
i18n-micro check-duplicates [options]

Example:

bash
i18n-micro check-duplicates

How it works:

  • The command checks both global and page-specific translation files for each locale.
  • If a translation value appears in multiple locations (either within global translations or across different pages), it reports the duplicate values along with the file and key where they are found.
  • If no duplicates are found, the command confirms that the locale is free of duplicated translation values.

This command helps ensure that translation keys maintain unique values, preventing accidental repetition within the same locale.

🔄 replace-values Command

Description: The replace-values command allows you to perform bulk replacements of translation values across all locales. It supports both simple text replacements and advanced replacements using regular expressions (regex). You can also use capturing groups in regex patterns and reference them in the replacement string, making it ideal for more complex replacement scenarios.

Usage:

bash
i18n-micro replace-values [options]

Options:

  • --search: The text or regex pattern to search for in translations. This is a required option.
  • --replace: The replacement text to be used for the found translations. This is a required option.
  • --useRegex: Enable search using a regular expression pattern (default: false).

Example 1: Simple replacement

Replace the string "Hello" with "Hi" across all locales:

bash
i18n-micro replace-values --search "Hello" --replace "Hi"

Example 2: Regex replacement

Enable regex search and replace any string starting with "Hello" followed by numbers (e.g., "Hello123") with "Hi" across all locales:

bash
i18n-micro replace-values --search "Hello\\d+" --replace "Hi" --useRegex

Example 3: Using regex capturing groups

Use capturing groups to dynamically insert part of the matched string into the replacement. For example, replace "Hello [name]" with "Hi [name]" while keeping the name intact:

bash
i18n-micro replace-values --search "Hello (\\w+)" --replace "Hi $1" --useRegex

In this case, $1 refers to the first capturing group, which matches the [name] part after "Hello". The replacement will keep the name from the original string.

How it works:

  • The command scans through all translation files (both global and page-specific).
  • When a match is found based on the search string or regex pattern, it replaces the matched text with the provided replacement.
  • When using regex, capturing groups can be used in the replacement string by referencing them with $1, $2, etc.
  • All changes are logged, showing the file path, translation key, and the before/after state of the translation value.

Logging: For each replacement, the command logs details including:

  • Locale and file path
  • The translation key being modified
  • The old value and the new value after replacement
  • If using regex with capturing groups, the logs will show the group matches and how they were replaced.

This allows you to track exactly where and what changes were made during the replacement operation, providing a clear history of modifications across your translation files.

🛠 Examples

  • Extracting translations:

    bash
    i18n-micro extract
  • Translating missing keys using Google Translate:

    bash
    i18n-micro translate --service google --token YOUR_GOOGLE_API_KEY
  • Translating all keys, replacing existing translations:

    bash
    i18n-micro translate --service deepl --token YOUR_DEEPL_API_KEY --replace
  • Validating translation files:

    bash
    i18n-micro validate
  • Cleaning unused translation keys:

    bash
    i18n-micro clean
  • Synchronizing translation files:

    bash
    i18n-micro sync

⚙️ Configuration Guide

nuxt-i18n-micro-cli relies on your Nuxt.js i18n configuration in nuxt.config.js. Ensure you have the nuxt-i18n module installed and configured.

🔑 nuxt.config.js Example

js
export default {
+  modules: ['@nuxtjs/i18n'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US' },
+      { code: 'fr', iso: 'fr-FR' },
+      { code: 'es', iso: 'es-ES' },
+      // Add other locales as needed
+    ],
+    defaultLocale: 'en',
+    vueI18n: {
+      fallbackLocale: 'en',
+    },
+    // Specify the directory where your translation files are stored
+    translationDir: 'locales',
+  },
+};

Ensure that the translationDir matches the directory used by nuxt-i18n-micro-cli (default is locales).

📝 Best Practices

🔑 Consistent Key Naming

Ensure translation keys are consistent and descriptive to avoid confusion and duplication.

🧹 Regular Maintenance

Use the clean command regularly to remove unused translation keys and keep your translation files clean.

🛠 Automate Translation Workflow

Integrate nuxt-i18n-micro-cli commands into your development workflow or CI/CD pipeline to automate extraction, translation, validation, and synchronization of translation files.

🛡️ Secure API Keys

When using translation services that require API keys, ensure your keys are kept secure and not committed to version control systems. Consider using environment variables or secure key management solutions.

📞 Support and Contributions

If you encounter issues or have suggestions for improvements, feel free to contribute to the project or open an issue on the project's repository.


By following this guide, you'll be able to effectively manage translations in your Nuxt.js project using nuxt-i18n-micro-cli, streamlining your internationalization efforts and ensuring a smooth experience for users in different locales.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/contribution.html b/guide/contribution.html new file mode 100644 index 0000000..819c0f8 --- /dev/null +++ b/guide/contribution.html @@ -0,0 +1,28 @@ + + + + + + 🤝 Contribution Guide | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🤝 Contribution Guide

📖 Introduction

Thank you for your interest in contributing to Nuxt I18n Micro! We welcome contributions from the community, whether it's bug fixes, new features, or improvements to the documentation. This guide outlines the steps to help you get started and ensures that your contributions can be easily integrated into the project.

🚀 Getting Started

1. 📚 Familiarize Yourself with the Project

Before making changes, it's a good idea to familiarize yourself with the project's architecture and codebase. Read through the existing documentation and take a look at open issues and pull requests to understand ongoing work and challenges.

2. 🍴 Fork the Repository

  • Navigate to the Nuxt I18n Micro repository.
  • Click the "Fork" button in the upper right corner to create a copy of the repository in your GitHub account.

3. 📥 Clone Your Fork

Clone the forked repository to your local machine:

bash
git clone https://github.com/<your-username>/nuxt-i18n-micro.git
+cd nuxt-i18n-micro

Replace <your-username> with your GitHub username.

4. 🌱 Create a Branch

Create a new branch for your work:

bash
git checkout -b feature/your-feature-name

Use descriptive branch names, such as bugfix/fix-translation-error or feature/add-new-locale-support.

🛠️ Local Development Setup

🛠 Prerequisites

Before you begin, ensure that you have the following installed on your machine:

  • Node.js: v16 or later
  • npm: v7 or later

🚀 Getting Started

1. 📥 Clone the Repository

First, you need to clone the nuxt-i18n-micro repository to your local machine.

bash
git clone https://github.com/s00d/nuxt-i18n-micro.git
+cd nuxt-i18n-micro

2. 📦 Install Dependencies

Next, install the project dependencies using npm.

bash
npm install
+npm run prepack && cd playground && npm run prepare && cd ..

3. 🖥️ Run the Development Server

To start the development server and work on the module, run the following command:

bash
npm run dev

This command will start the Nuxt development server using the playground directory as the testing environment. You can view the app in your browser by navigating to http://localhost:3000.

4. 🏗️ Building the Module

To build the module, use the following command:

bash
npm run prepack

This command prepares the module by building the necessary files, stubbing certain components, and ensuring everything is ready for packaging.

5. 🧹 Linting the Code

To ensure your code adheres to the project's coding standards, run the linter:

bash
npm run lint

If there are any issues, you can attempt to automatically fix them using:

bash
npm run lint:fix

6. ✅ Running Tests

To run the test suite, use the following command:

bash
npm run test

This will run all the Playwright tests to ensure everything is functioning as expected.

7. 🔍 Type Checking

For TypeScript type checking, run:

bash
npm run typecheck

This checks the type definitions to ensure there are no type errors.

8. 📚 Building and Previewing the Documentation

To build and preview the documentation locally, use the following commands:

bash
npm run docs:build
+npm run docs:serve

This will build the documentation and serve it locally, allowing you to view it in your browser.

9. 🎮 Running the Playground

If you want to test your changes in a sample Nuxt application, the playground directory serves as a sandbox environment. Run the following command to start the playground:

bash
npm run dev:build

You can access the playground app at http://localhost:3000.

🔧 Summary of Common Scripts

  • npm run dev: Start the development server using the playground.
  • npm run prepack: Build the module and prepare it for publishing.
  • npm run lint: Run the linter to check for code quality issues.
  • npm run lint:fix: Automatically fix linter issues.
  • npm run test: Run the test suite.
  • npm run typecheck: Check TypeScript types.
  • npm run docs:dev: Start the documentation site in development mode.
  • npm run docs:build: Build the documentation site.
  • npm run docs:serve: Serve the built documentation site locally.
  • npm run dev:build: Build the playground environment.

🚧 Making Changes

1. 💻 Code

  • Make your changes in the codebase according to the project’s architecture.
  • Follow the existing code style and conventions.
  • If you’re adding a new feature, consider writing tests for it.

2. 🧹 Run Linting

Before committing your changes, ensure that your code adheres to the project's coding standards by running the linter:

bash
npm run lint

Fix any linting errors before proceeding.

3. 🧪 Test Your Changes

Make sure your changes work and do not break any existing functionality:

  • Run all tests to ensure there are no errors:
bash
npm run test
  • If you’re fixing a bug, add tests to cover the fix.

4. 📝 Commit Your Changes

To ensure consistency across the project, we use a standardized commit message format. Please follow this format when making commits:

✅ Commit Message Format

Each commit message should be structured as follows:

<type>(<scope>): <short description>

📋 Examples:

  • fix(router): resolve issue with locale switching
  • feat(seo): add automatic og:locale meta tag generation
  • docs(contribution): update contribution guide with commit message format

🛠️ Commit Types:

  • feat: A new feature.
  • fix: A bug fix.
  • docs: Documentation changes or updates.
  • style: Code style or formatting changes (no functional impact).
  • refactor: Code changes that neither fix a bug nor add a feature.
  • test: Adding or updating tests.
  • chore: Miscellaneous tasks, such as updating build scripts or dependencies.

5. 🚀 Push to GitHub

Push your changes to your fork on GitHub:

bash
git push origin feature/your-feature-name

6. 🔄 Create a Pull Request

  • Go to your forked repository on GitHub.
  • Click the "Compare & pull request" button.
  • Ensure your PR targets the main branch of the original repository (s00d/nuxt-i18n-micro).
  • Describe your changes in the PR, and link to any relevant issues.

7. 🕵️‍♂️ Await Feedback

Once your pull request is submitted, a maintainer will review your changes. Be prepared to make adjustments based on feedback. Once approved, your PR will be merged into the main branch.

💡 Contribution Tips

  • 📝 Documentation: If you add or change a feature, ensure that you update the relevant documentation.
  • 🧼 Code Cleanliness: Keep your code clean and follow the project's coding standards.
  • 💬 Respectful Communication: Be respectful and friendly in your communications. We are all working towards the common goal of making Nuxt I18n Micro better.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/crowdin.html b/guide/crowdin.html new file mode 100644 index 0000000..b75590e --- /dev/null +++ b/guide/crowdin.html @@ -0,0 +1,39 @@ + + + + + + 🌐 Crowdin Integration Guide | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🌐 Crowdin Integration Guide

📖 Introduction

Integrating Crowdin into your project streamlines the localization and translation process, making it easier to manage translations across multiple languages and platforms. This guide provides a step-by-step walkthrough on setting up Crowdin with your project, including configuration, uploading sources, and downloading translations.

🔧 Installation and Setup

To get started with Crowdin, you'll need to install the Crowdin CLI globally on your machine and initialize it within your project directory.

📦 Installing Crowdin CLI

First, install the Crowdin CLI globally using npm:

bash
npm install -g @crowdin/cli

🛠 Initializing Crowdin in Your Project

Initialize Crowdin in your project by running:

bash
crowdin init

This command will guide you through the setup process, including setting your project ID, API token, and other configuration details.

🗂️ Configuration Guide

📄 Crowdin Configuration File (crowdin.yml)

The Crowdin configuration file (crowdin.yml) defines how your source files are mapped and where translations should be placed. Below is an example configuration:

yml
"project_id": "YOUR_PROJECT_ID"
+"api_token": "YOUR_API_TOKEN"
+"base_path": "./locales"
+"base_url": "https://api.crowdin.com"
+"preserve_hierarchy": true
+
+files: [
+  {
+    "source": "/en.json",
+    "translation": "/%two_letters_code%.json",
+  },
+  {
+    "source": "/pages/**/en.json",
+    "translation": "/pages/**/%two_letters_code%.json",
+  }
+]

📂 Key Configuration Parameters

  • project_id: Your Crowdin project ID. This identifies the project within Crowdin where translations are managed.
  • api_token: The API token used for authentication. Ensure this token has the correct permissions to upload and download translations.
  • base_path: Specifies the base directory for source files. In this example, translations are stored in the ./locales directory.
  • base_url: The base URL for the Crowdin API.
  • preserve_hierarchy: When set to true, Crowdin will maintain the folder structure of your source files in the project.

📂 Files Configuration

The files section maps your source files to the paths where translations will be stored. For example:

  • Source Path: Defines the location of the original translation files.
  • Translation Path: Specifies where the translated files will be stored in Crowdin. Placeholders like %two_letters_code% are used to dynamically set the language code in the file paths.

⬆️ Uploading Source Files to Crowdin

Once your Crowdin configuration is set up, you can upload your source files using the following command:

bash
crowdin upload sources

This command uploads all specified source files in your configuration to Crowdin, making them available for translation.

⬇️ Downloading Translations from Crowdin

After translations are completed or updated in Crowdin, you can download them to your project using:

bash
crowdin download

This command fetches the latest translations from Crowdin and saves them according to the paths specified in your configuration file.

⚙️ Best Practices

🔑 Consistent Key Naming

Ensure translation keys are consistent across all files to avoid confusion and duplication.

🧹 Regular Maintenance

Periodically review and clean up unused translation keys to keep your files organized and manageable.

🛠 Automate Uploads and Downloads

Integrate the Crowdin CLI commands into your CI/CD pipeline to automate the upload of source files and download of translations, ensuring your translations are always up to date.

By following this guide, you’ll be able to seamlessly integrate Crowdin into your project, ensuring an efficient and organized approach to managing your internationalization efforts.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/custom-locale-routes.html b/guide/custom-locale-routes.html new file mode 100644 index 0000000..1786449 --- /dev/null +++ b/guide/custom-locale-routes.html @@ -0,0 +1,58 @@ + + + + + + 🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🔗 Custom Localized Routes with localeRoutes in Nuxt I18n Micro

📖 Introduction to localeRoutes

The localeRoutes feature in Nuxt I18n Micro allows you to define custom routes for specific locales, offering flexibility and control over the routing structure of your application. This feature is particularly useful when certain locales require different URL structures, tailored paths, or need to follow specific regional or linguistic conventions.

🚀 Primary Use Case of localeRoutes

The primary use case for localeRoutes is to provide distinct routes for different locales, enhancing the user experience by ensuring URLs are intuitive and relevant to the target audience. For example, you might have different paths for English and Russian versions of a page, where the Russian locale follows a localized URL format.

📄 Example: Defining localeRoutes in $defineI18nRoute

Here’s an example of how you might define custom routes for specific locales using localeRoutes in your $defineI18nRoute function:

typescript
$defineI18nRoute({
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for the Russian locale
+    de: '/lokaleseite',   // Custom route path for the German locale
+  },
+})

🔄 How localeRoutes Work

  • Default Behavior: Without localeRoutes, all locales use a common route structure defined by the primary path.
  • Custom Behavior: With localeRoutes, specific locales can have their own routes, overriding the default path with locale-specific routes defined in the configuration.

🌱 Use Cases for localeRoutes

📄 Example: Using localeRoutes in a Page

Here’s a simple Vue component demonstrating the use of $defineI18nRoute with localeRoutes:

vue
<template>
+  <div>
+    <!-- Display greeting message based on the current locale -->
+    <p>{{ $t('greeting') }}</p>
+
+    <!-- Navigation links -->
+    <div>
+      <NuxtLink :to="$localeRoute({ name: 'index' })">
+        Go to Index
+      </NuxtLink>
+      |
+      <NuxtLink :to="$localeRoute({ name: 'about' })">
+        Go to About Page
+      </NuxtLink>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useNuxtApp } from '#imports'
+
+const { $getLocale, $switchLocale, $getLocales, $localeRoute, $t, $defineI18nRoute } = useNuxtApp()
+
+// Define translations and custom routes for specific locales
+$defineI18nRoute({
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for Russian locale
+  },
+})
+</script>

🛠️ Using localeRoutes in Different Contexts

  • Landing Pages: Use custom routes to localize URLs for landing pages, ensuring they align with marketing campaigns.
  • Documentation Sites: Provide distinct routes for each locale to better match the localized content structure.
  • E-commerce Sites: Tailor product or category URLs per locale for improved SEO and user experience.

📝 Best Practices for Using localeRoutes

  • 🚀 Use for Relevant Locales: Apply localeRoutes primarily where the URL structure significantly impacts the user experience or SEO. Avoid overuse for minor differences.
  • 🔧 Maintain Consistency: Keep a consistent routing pattern across locales unless there's a strong reason to deviate. This approach helps in maintaining clarity and reducing complexity.
  • 📚 Document Custom Routes: Clearly document any custom routes you define with localeRoutes, especially in modular applications, to ensure team members understand the routing logic.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/faq.html b/guide/faq.html new file mode 100644 index 0000000..0a0d4f0 --- /dev/null +++ b/guide/faq.html @@ -0,0 +1,43 @@ + + + + + + FAQ: Common Issues & Solutions | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

FAQ: Common Issues & Solutions

❓ What if a route doesn't load?

One common issue when using Nuxt I18n Micro is that some routes might not open as expected. This can happen when the router doesn’t automatically assign a name to a route, particularly in subfolders.

Solution: To fix this, manually define the page’s route name by adding the following to the corresponding Vue file:

javascript
definePageMeta({ name: 'pageName' })

This ensures that the route is properly registered, and the application can navigate to it without issues.


❓ Why is the assets/_locales/ folder added to the server folder?

When deploying to platforms like Netlify, the build process might behave differently compared to local development. This can lead to issues where certain files or folders are not found during server-side rendering (SSR).

To ensure that localization files are available during SSR, the assets/_locales/ folder is added to the server folder. This is a workaround to make sure that the localization files are accessible in the production environment, especially when the build process and runtime environment differ.

Explanation:

  • Build Process: During the build, all translations are cached in the production folder. However, when deploying to platforms like Netlify, the server code is moved to functions, and there might be a separate container where locale files are not accessible.
  • Prerendering: Prerendering does not work when using $fetch in SSR, leading to middleware not finding the localization files.
  • Server Assets: To address this, the localization files are saved in the Nitro server assets during prerendering. In production, they are read from the server assets.

❓ Is Nuxt I18n Micro inspired by vue-i18n? What about features like modifiers?

While Nuxt I18n Micro serves as a performance alternative to nuxt-i18n, it is not directly inspired by vue-i18n. The library was built from scratch to address issues in nuxt-i18n, and while some method names and parameters are similar, the underlying logic is entirely different.

Modifiers: The maintainer experimented with adding modifiers but found that components like <i18n-t> and <i18n-link> effectively cover the same needs. For example:

vue
<template>
+  <i18n-t keypath="feedback.text">
+    <template #link>
+      <nuxt-link :to="{ name: 'index' }">
+        <i18n-t keypath="feedback.link" />
+      </nuxt-link>
+    </template>
+  </i18n-t>
+</template>

Since this approach is flexible and powerful, releasing modifiers was deemed unnecessary for now. However, modifiers may be added in the future if demand arises.


Yes, Nuxt I18n Micro allows you to use NuxtLink or i18nLink in translations through the <i18n-t> component, eliminating the need to split translation strings, which can be especially helpful when dealing with languages that have different grammatical rules or RTL languages.

Example:

json
{
+  "example": "Share your {link} with friends",
+  "link_text": "translation link"
+}
vue
<template>
+  <i18n-t keypath="example">
+    <template #link>
+      <nuxt-link :to="{ name: 'referral' }">
+        <i18n-t keypath="link_text" />
+      </nuxt-link>
+    </template>
+  </i18n-t>
+</template>

This method supports dynamic link creation inside translations while maintaining proper localization structure.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/folder-structure.html b/guide/folder-structure.html new file mode 100644 index 0000000..116e737 --- /dev/null +++ b/guide/folder-structure.html @@ -0,0 +1,67 @@ + + + + + + 📂 Folder Structure Guide | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

📂 Folder Structure Guide

📖 Introduction

Organizing your translation files effectively is essential for maintaining a scalable and efficient internationalization (i18n) system. Nuxt I18n Micro simplifies this process by offering a clear approach to managing global and page-specific translations. This guide will walk you through the recommended folder structure and explain how Nuxt I18n Micro handles these translations.

Nuxt I18n Micro organizes translations into global files and page-specific files within the pages directory. This ensures that only the necessary translation data is loaded when required, optimizing both performance and organization.

🔧 Basic Structure

Here’s a basic example of the folder structure you should follow:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json

📄 Explanation of Structure

1. 🌍 Global Translation Files

  • Path: /locales/{locale}.json (e.g., /locales/en.json)

  • Purpose: These files contain translations that are shared across the entire application. This is useful for common elements like navigation menus, headers, footers, or any text that appears on multiple pages.

    Example Content (/locales/en.json):

    json
    {
    +  "menu": {
    +    "home": "Home",
    +    "about": "About Us",
    +    "contact": "Contact"
    +  },
    +  "footer": {
    +    "copyright": "© 2024 Your Company"
    +  }
    +}

2. 📄 Page-Specific Translation Files

  • Path: /locales/pages/{routeName}/{locale}.json (e.g., /locales/pages/index/en.json)

  • Purpose: These files are used for translations that are specific to individual pages. This allows you to load only the necessary translations when a user visits a particular page, which enhances performance by reducing the amount of data that needs to be loaded.

    Example Content (/locales/pages/index/en.json):

    json
    {
    +  "title": "Welcome to Our Website",
    +  "description": "We offer a wide range of products and services to meet your needs."
    +}

    Example Content (/locales/pages/about/en.json):

    json
    {
    +  "title": "About Us",
    +  "description": "Learn more about our mission, vision, and values."
    +}

📂 Handling Dynamic Routes and Nested Paths

Nuxt I18n Micro automatically transforms dynamic segments and nested paths in routes into a flat folder structure using a specific renaming convention. This ensures that all translations are stored in a consistent and easily accessible manner.

Dynamic Route Translation Folder Structure

When dealing with dynamic routes, such as /products/[id], the module converts the dynamic segment [id] into a static format within the file structure.

Example Folder Structure for Dynamic Routes:

For a route like /products/[id], the translation files would be stored in a folder named products-id:

plaintext
  /locales/pages
+  ├── /products-id
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

Example Folder Structure for Nested Dynamic Routes:

For a nested route like /products/key/[id], the translation files would be stored in a folder named products-key-id:

plaintext
  /locales/pages
+  ├── /products-key-id
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

Example Folder Structure for Multi-Level Nested Routes:

For a more complex nested route like /products/category/[id]/details, the translation files would be stored in a folder named products-category-id-details:

plaintext
  /locales/pages
+  ├── /products-category-id-details
+  │   ├── en.json
+  │   ├── fr.json
+  │   └── ar.json

🛠 Customizing the Directory Structure

If you prefer to store translations in a different directory, Nuxt I18n Micro allows you to customize the directory where translation files are stored. You can configure this in your nuxt.config.ts file.

Example: Customizing the Translation Directory

typescript
export default defineNuxtConfig({
+  i18n: {
+    translationDir: 'i18n' // Custom directory path
+  }
+})

This will instruct Nuxt I18n Micro to look for translation files in the /i18n directory instead of the default /locales directory.

⚙️ How Translations are Loaded

🌍 Dynamic Locale Routes

Nuxt I18n Micro uses dynamic locale routes to load translations efficiently. When a user visits a page, the module determines the appropriate locale and loads the corresponding translation files based on the current route and locale.

For example:

  • Visiting /en/index will load translations from /locales/pages/index/en.json.
  • Visiting /fr/about will load translations from /locales/pages/about/fr.json.

This method ensures that only the necessary translations are loaded, optimizing both server load and client-side performance.

💾 Caching and Pre-rendering

To further enhance performance, Nuxt I18n Micro supports caching and pre-rendering of translation files:

  • Caching: Once a translation file is loaded, it’s cached for subsequent requests, reducing the need to repeatedly fetch the same data.
  • Pre-rendering: During the build process, you can pre-render translation files for all configured locales and routes, allowing them to be served directly from the server without runtime delays.

📝 Best Practices

📂 Use Page-Specific Files Wisely

Leverage page-specific files to avoid bloating global translation files. This keeps each page’s translations lean and fast to load, which is especially important for pages with complex or large content.

🔑 Keep Translation Keys Consistent

Use consistent naming conventions for your translation keys across files. This helps maintain clarity and prevents issues when managing translations, especially as your application grows.

🗂️ Organize Translations by Context

Group related translations together within your files. For example, group all button labels under a buttons key and all form-related texts under a forms key. This not only improves readability but also makes it easier to manage translations across different locales.

🧹 Regularly Clean Up Unused Translations

Over time, your application might accumulate unused translation keys, especially if features are removed or restructured. Periodically review and clean up your translation files to keep them lean and maintainable.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/getting-started.html b/guide/getting-started.html new file mode 100644 index 0000000..4e802c7 --- /dev/null +++ b/guide/getting-started.html @@ -0,0 +1,92 @@ + + + + + + 🌐 Getting Started with Nuxt I18n Micro | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🌐 Getting Started with Nuxt I18n Micro

📖 Overview

Nuxt I18n Micro is a lightweight internationalization module for Nuxt that delivers superior performance compared to traditional solutions. It's designed to reduce build times, memory usage, and server load, making it ideal for high-traffic and large projects.

🤔 Why Choose Nuxt I18n Micro?

Here are some key benefits of using Nuxt I18n Micro:

  • 🚀 High Performance: Significantly reduces build times and memory consumption.
  • 📦 Compact Size: Has minimal impact on your app's bundle size.
  • ⚙️ Efficiency: Optimized for large-scale applications with a focus on memory consumption and server load.

🛠 Installation

To install the module in your Nuxt application, run the following command:

bash
npm install nuxt-i18n-micro

⚙️ Basic Setup

After installation, add the module to your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  modules: [
+    'nuxt-i18n-micro',
+  ],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

📂 Folder Structure

Translation files are organized into global and page-specific directories:

  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json
  • Global Files: Contain translations shared across the entire app.
  • Page-Specific Files: Contain translations unique to specific pages.

⚙️ Module Configuration Options

The Nuxt I18n Micro module provides a range of customizable options to fine-tune your internationalization setup:

🌍 locales

Defines the locales available in your application.

Type: Locale[]

Each locale object includes:

  • code (string, required): A unique identifier for the locale, e.g., 'en' for English.
  • iso (string, optional): The ISO code, e.g., 'en-US', used for the lang attribute in HTML.
  • dir (string, optional): Text direction, either 'rtl' for right-to-left or 'ltr' for left-to-right languages.
  • disabled (boolean, optional): Indicates if the locale should be disabled.

Example:

typescript
locales: [
+  { code: 'en', iso: 'en-US', dir: 'ltr' },
+  { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+  { code: 'ar', iso: 'ar-SA', dir: 'rtl', disabled: false }
+]

🌐 defaultLocale

Sets the default locale if no specific locale is selected by the user.

Type: string

Example:

typescript
defaultLocale: 'en'

🗂 translationDir

Specifies the directory where translation files are stored.

Type: string
Default: 'locales'

Example:

typescript
translationDir: 'i18n' // Custom directory for translation files

🔍 meta

Automatically generates SEO-related meta tags, such as alternate links for different locales.

Type: boolean
Default: true

Example:

typescript
meta: true // Enable automatic SEO meta tags generation

🐛 debug

Enables logging and debugging information during the generation process to help with troubleshooting.

Type: boolean
Default: false

Example:

typescript
debug: true // Enable logging and debugging information

🐛 types

Adds types to the project during the postinstall process. If you encounter issues with types, you can disable this option.

Type: boolean
Default: true

Example:

typescript
types: true

🔗 metaBaseUrl

Sets the base URL for generating SEO-related meta tags like canonical and alternate URLs.

Type: string
Default: '/'

Example:

typescript
metaBaseUrl: 'https://example.com' // Custom base URL for meta tags

🌍 autoDetectLanguage

Automatically detects the user's preferred language based on browser settings and redirects to the appropriate locale.

Type: boolean
Default: false

Example:

typescript
autoDetectLanguage: true // Enable automatic language detection and redirection

🔍 autoDetectPath

Specifies the route path(s) on which the locale auto-detection and switching should occur.

Type: string
Default: "*"

Example:

typescript
autoDetectPath: '/' // Locale detection will only happen on the home route

🔢 plural

Custom function for handling pluralization in translations based on count and locale.

Type: (key: string, translation: unknown, count: number, locale: string) => string

Example:

typescript
export type Getter = (key: string, params?: Record<string, string | number | boolean>, defaultValue?: string) => unknown
+
+{
+  plural: (key: string, count: number, _locale: string, t: Getter) => {
+    const translation = t(key)
+    if (!translation) {
+      return key
+    }
+    const forms = translation.toString().split('|')
+    if (count === 0 && forms.length > 2) {
+      return forms[0].trim() // Case for "no apples"
+    }
+    if (count === 1 && forms.length > 1) {
+      return forms[1].trim() // Case for "one apple"
+    }
+    return (forms.length > 2 ? forms[2].trim() : forms[forms.length - 1].trim()).replace('{count}', count.toString())
+  }
+}

🚦 includeDefaultLocaleRoute

Automatically redirects routes without a locale prefix to the default locale.

Type: boolean
Default: false

Example:

typescript
includeDefaultLocaleRoute: true // Ensure consistency across routes by redirecting to the default locale

🚦 customRegexMatcher

I18n-micro meticulously checks each locale via vue-router route regex. If you have a lot of locales, you can improve pattern matching performances via a custom regex matcher.

Type: string | RegExp
Default: false

Example:

typescript
customRegexMatcher: '[a-z]-[A-Z]'// This matches locales in isoCode (e.g: '/en-US', 'de-DE' etc)

Creates links between different pages' locale files to share translations, reducing duplication.

Type: Record<string, string>

Example:

typescript
routesLocaleLinks: {
+  'products-id': 'products',
+  'about-us': 'about'
+}

🧩 define

Enables or disables the addition of a special define plugin that allows you to use Nuxt's runtime configuration for overriding settings in your translation files.

Type: boolean
Default: true

Example:

typescript
define: false // Disable the define plugin

🔄 disablePageLocales

Allows you to disable page-specific translations, limiting the module to only use global translation files.

Type: boolean
Default: false

Example:

typescript
disablePageLocales: true // Disable page-specific translations, using only global translations

📂 Folder Structure with disablePageLocales: true

When disablePageLocales is enabled, the module will only use the translations defined in the global files located directly under the locales directory. Page-specific translation files (located in /locales/pages) will be ignored.

  /locales
+  ├── en.json
+  ├── fr.json
+  └── ar.json

👀 disableWatcher

Disables the automatic creation of locale files during development.

Type: boolean
Default: false

Example:

typescript
disableWatcher: true // Disables the automatic creation of locale files

🔗 apiBaseUrl

env: NUXT_I18N_APP_BASE_URL

Defines the base URL that the server will use to fetch cached translations. By default, this is set to _locales, but you can change it to any custom path, such as api/_locales, if you want to load translations from a different endpoint.

Type: string
Default: '_locales'

Example:

typescript
apiBaseUrl: 'api/_locales' // Custom URL for fetching cached translations

When set, the module will use the specified URL to request cached translations instead of using the default _locales.

🍪 localeCookie

Specifies the name of the cookie used to store the user's selected locale.

Type: string
Default: 'user-locale'

🌐 fallbackLocale

Specifies a fallback locale to be used when the current locale does not have a specific translation available.

Type: string | undefined
Default: undefined

Example:

typescript
i18n: {
+  locales: [
+    { code: 'en', iso: 'en-US', dir: 'ltr' },
+    { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    { code: 'es', iso: 'es-ES', dir: 'ltr' }
+  ],
+  defaultLocale: 'en',
+  fallbackLocale: 'en', // Use English as a fallback locale
+}

🌐 globalLocaleRoutes

Allows you to define custom localized routes for specific pages. You can specify a custom path for each locale for a given page, or disable localization for certain pages entirely.

Type: Record<string, Record<string, string> | false>

  • Key (string): The name of the page you want to customize or disable localization for.
  • Value:
    • Record<string, string>: A set of locale codes with corresponding custom paths for the page.
    • false: Disable localization for this page entirely. The page will not be localized, and it will remain accessible only through its default path.

This option gives you the flexibility to localize certain pages differently while leaving others unaffected by localization.

Example:

typescript
globalLocaleRoutes: {
+  page2: {
+    en: '/custom-page2-en',
+    de: '/custom-page2-de',
+    ru: '/custom-page2-ru',
+  },
+  unlocalized: false, // Unlocalized page should not be localized
+}

Usage:

In the example above:

  • page2: Custom localized paths are defined for the page page2 in English (en), German (de), and Russian (ru). Instead of following the standard localization pattern (like /en/page2), each locale will have a completely custom URL, such as /en/custom-page2-en for English, /de/custom-page2-de for German, and /ru/custom-page2-ru for Russian.
  • unlocalized: This page will not be localized, so it remains accessible only at /unlocalized, without any locale prefixes or custom paths.

🔄 Caching Mechanism

One of the standout features of Nuxt I18n Micro is its intelligent caching system. When a translation is requested during server-side rendering (SSR), the result is stored in a cache. This means that subsequent requests for the same translation can

retrieve the data from the cache rather than searching through the translation files again. This caching mechanism drastically reduces the time needed to fetch translations and significantly lowers the server's resource consumption.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/layers.html b/guide/layers.html new file mode 100644 index 0000000..62134e0 --- /dev/null +++ b/guide/layers.html @@ -0,0 +1,95 @@ + + + + + + 🗂️ Layers in Nuxt I18n Micro | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🗂️ Layers in Nuxt I18n Micro

📖 Introduction to Layers

Layers in Nuxt I18n Micro allow you to manage and customize localization settings flexibly across different parts of your application. By defining different layers, you can adjust the configuration for various contexts, such as overriding settings for specific sections of your site or creating reusable base configurations that can be extended by other parts of your application.

🛠️ Primary Configuration Layer

The Primary Configuration Layer is where you set up the default localization settings for your entire application. This layer is essential as it defines the global configuration, including the supported locales, default language, and other critical i18n settings.

📄 Example: Defining the Primary Configuration Layer

Here’s an example of how you might define the primary configuration layer in your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en', // The default locale for the entire app
+    translationDir: 'locales', // Directory where translations are stored
+    meta: true, // Automatically generate SEO-related meta tags like `alternate`
+    autoDetectLanguage: true, // Automatically detect and use the user's preferred language
+  },
+})

🌱 Child Layers

Child layers are used to extend or override the primary configuration for specific parts of your application. For instance, you might want to add additional locales or modify the default locale for a particular section of your site. Child layers are especially useful in modular applications where different parts of the application might have different localization requirements.

📄 Example: Extending the Primary Layer in a Child Layer

Suppose you have a section of your site that needs to support additional locales, or you want to disable a particular locale in a certain context. Here’s how you can achieve that by extending the primary configuration layer:

typescript
// basic/nuxt.config.ts (Primary Layer)
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    meta: true,
+    translationDir: 'locales',
+  },
+})
typescript
// extended/nuxt.config.ts (Child Layer)
+export default defineNuxtConfig({
+  extends: '../basic', // Inherit the base configuration from the 'basic' layer
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited from the base layer
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited from the base layer
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Added in the child layer
+    ],
+    defaultLocale: 'fr', // Override the default locale to French for this section
+    autoDetectLanguage: false, // Disable automatic language detection in this section
+  },
+})

🌐 Using Layers in a Modular Application

In a larger, modular Nuxt application, you might have multiple sections, each requiring its own i18n settings. By leveraging layers, you can maintain a clean and scalable configuration structure.

📄 Example: Layered Configuration in a Modular Application

Imagine you have an e-commerce site with distinct sections like the main website, admin panel, and customer support portal. Each section might need a different set of locales or other i18n settings.

Primary Layer (Global Configuration):

typescript
// nuxt.config.ts
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    meta: true,
+    translationDir: 'locales',
+    autoDetectLanguage: true,
+  },
+})

Child Layer for Admin Panel:

typescript
// admin/nuxt.config.ts
+export default defineNuxtConfig({
+  extends: '../nuxt.config', // Inherit the global settings
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited
+      { code: 'es', iso: 'es-ES', dir: 'ltr' }, // Specific to the admin panel
+    ],
+    defaultLocale: 'en',
+    meta: false, // Disable automatic meta generation in the admin panel
+  },
+})

Child Layer for Customer Support Portal:

typescript
// support/nuxt.config.ts
+export default defineNuxtConfig({
+  extends: '../nuxt.config', // Inherit the global settings
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-EN', dir: 'ltr' }, // Inherited
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Inherited
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Specific to the support portal
+    ],
+    defaultLocale: 'de', // Default to German in the support portal
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

In this modular example:

  • Each section (admin, support) has its own i18n settings, but they all inherit the base configuration.
  • The admin panel adds Spanish (es) as a locale and disables meta tag generation.
  • The support portal adds German (de) as a locale and defaults to German for the user interface.

📝 Best Practices for Using Layers

  • 🔧 Keep the Primary Layer Simple: The primary layer should contain the most commonly used settings that apply globally across your application. Keep it straightforward to ensure consistency.
  • ⚙️ Use Child Layers for Specific Customizations: Only override or extend settings in child layers when necessary. This approach avoids unnecessary complexity in your configuration.
  • 📚 Document Your Layers: Clearly document the purpose and specifics of each layer in your project. This will help maintain clarity and make it easier for others (or future you) to understand the configuration.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/migration.html b/guide/migration.html new file mode 100644 index 0000000..96bfa08 --- /dev/null +++ b/guide/migration.html @@ -0,0 +1,59 @@ + + + + + + 🔄 Migration from nuxt-i18n to Nuxt I18n Micro | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🔄 Migration from nuxt-i18n to Nuxt I18n Micro

📖 Introduction

Migrating from nuxt-i18n to Nuxt I18n Micro can significantly improve the performance of your Nuxt application, especially in high-traffic environments or projects with large translation files. This guide provides a step-by-step approach to help you smoothly transition from nuxt-i18n to Nuxt I18n Micro.

🚀 Why Migrate?

The Nuxt I18n Micro module offers several advantages over the traditional nuxt-i18n:

  • ⚡ Improved Performance: Faster build times, lower memory usage, and smaller bundle sizes.
  • 🔧 Simplified Configuration: A more streamlined setup process with fewer moving parts.
  • 📉 Better Resource Management: Optimized handling of large translation files and reduced server load.

🔍 Key Differences

Before you begin the migration process, it’s essential to understand the key differences between nuxt-i18n and Nuxt I18n Micro:

  • 🌐 Route Management: Nuxt I18n Micro uses dynamic regex-based routing, generating only two routes regardless of the number of locales, unlike nuxt-i18n which creates a separate route for each locale.
  • 🗂️ Translation Files: Only JSON files are supported in Nuxt I18n Micro. The translations are split into global and page-specific files, which are auto-generated in development mode if not present.
  • 📈 SEO Integration: Nuxt I18n Micro offers built-in SEO optimization with automatic meta tag generation and support for hreflang tags.

🛠️ Step-by-Step Migration

1. 🛠️ Install Nuxt I18n Micro

First, add Nuxt I18n Micro to your Nuxt project:

bash
npm install nuxt-i18n-micro

2. 🔄 Update Configuration

Replace your existing nuxt-i18n configuration in nuxt.config.ts with the Nuxt I18n Micro configuration. Here’s an example:

Before (nuxt-i18n):

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US' },
+      { code: 'fr', iso: 'fr-FR' },
+    ],
+    defaultLocale: 'en',
+    vueI18n: './i18n.config.js',
+  },
+})

After (Nuxt I18n Micro):

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

3. 🗂️ Reorganize Translation Files

Move your translation files to the locales directory. Ensure they are in JSON format and organized by locale. For example:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json

If you are using <nuxt-link> for navigation, replace it with <NuxtLink> to ensure compatibility with the new module.

Before:

vue
<nuxt-link :to="{ name: 'index' }">Home</nuxt-link>

After:

vue
<NuxtLink :to="$localeRoute({ name: 'index' })">Home</NuxtLink>
+<!-- or -->
+<i18n-link :to="{ name: 'index' }">Home</i18n-link>

5. 🛠️ Handle SEO Configurations

Ensure that your SEO configurations are updated to take advantage of Nuxt I18n Micro’s automatic meta tag generation. Remove any redundant SEO configurations that were specific to nuxt-i18n.

6. 🧪 Test Your Application

After completing the migration steps, thoroughly test your application to ensure that all translations are loading correctly and that navigation between locales works as expected. Pay special attention to SEO-related tags and ensure that they are generated as intended.

🛡️ Common Issues and Troubleshooting

❌ Translation Files Not Loading

Ensure that your translation files are in the correct directory and follow the JSON format. Also, confirm that the translationDir option in your configuration matches the location of your translation files.

⚠️ Route Not Found Errors

Check that the routes are correctly set up in your application and that the locales array in the configuration includes all necessary locale codes.

🏷️ Missing SEO Tags

If SEO tags are not being generated, verify that the meta option is enabled in your configuration and that each locale has a valid iso code.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/multi-domain-locales.html b/guide/multi-domain-locales.html new file mode 100644 index 0000000..e34e469 --- /dev/null +++ b/guide/multi-domain-locales.html @@ -0,0 +1,68 @@ + + + + + + 🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🌍 Setting Up Multi-Domain Locales with Nuxt I18n Micro Using Layers

📝 Introduction

By leveraging layers in Nuxt I18n Micro, you can create a flexible and maintainable multi-domain localization setup. This approach not only simplifies domain management by eliminating the need for complex functionalities but also allows for efficient load distribution and reduced project complexity. By running separate projects for different locales, your application can easily scale and adapt to varying locale requirements across multiple domains, offering a robust and scalable solution for global applications.

🎯 Objective

To create a setup where different domains serve specific locales by customizing configurations in child layers. This method leverages Nuxt's layering system, allowing you to maintain a base configuration while extending or modifying it for each domain.

🛠 Steps to Implement Multi-Domain Locales

1. Create the Base Layer

Start by creating a base configuration layer that includes all the common locale settings for your application. This configuration will serve as the foundation for other domain-specific configurations.

Base Layer Configuration

Create the base configuration file base/nuxt.config.ts:

typescript
// base/nuxt.config.ts
+
+export default defineNuxtConfig({
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'de', iso: 'de-DE', dir: 'ltr' },
+      { code: 'es', iso: 'es-ES', dir: 'ltr' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+    autoDetectLanguage: true,
+  },
+})

2. Create Domain-Specific Child Layers

For each domain, create a child layer that modifies the base configuration to meet the specific requirements of that domain. You can disable locales that are not needed for a specific domain.

Example: Configuration for the French Domain

Create a child layer configuration for the French domain in fr/nuxt.config.ts:

typescript
// fr/nuxt.config.ts
+
+export default defineNuxtConfig({
+  extends: '../base', // Inherit from the base configuration
+
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: true }, // Disable English
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' }, // Add and enable the French locale
+      { code: 'de', iso: 'de-DE', dir: 'ltr', disabled: true }, // Disable German
+      { code: 'es', iso: 'es-ES', dir: 'ltr', disabled: true }, // Disable Spanish
+    ],
+    defaultLocale: 'fr', // Set French as the default locale
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

Example: Configuration for the German Domain

Similarly, create a child layer configuration for the German domain in de/nuxt.config.ts:

typescript
// de/nuxt.config.ts
+
+export default defineNuxtConfig({
+  extends: '../base', // Inherit from the base configuration
+
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr', disabled: true }, // Disable English
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr', disabled: true }, // Disable French
+      { code: 'de', iso: 'de-DE', dir: 'ltr' }, // Use the German locale
+      { code: 'es', iso: 'es-ES', dir: 'ltr', disabled: true }, // Disable Spanish
+    ],
+    defaultLocale: 'de', // Set German as the default locale
+    autoDetectLanguage: false, // Disable automatic language detection
+  },
+})

3. Deploy the Application for Each Domain

Deploy the application with the appropriate configuration for each domain. For example:

  • Deploy the fr layer configuration to fr.example.com.
  • Deploy the de layer configuration to de.example.com.

4. Set Up Multiple Projects for Different Locales

For each locale and domain, you'll need to run a separate instance of the application. This ensures that each domain serves the correct locale configuration, optimizing the load distribution and simplifying the project's structure. By running multiple projects tailored to each locale, you can maintain a clean separation between configurations and reduce the complexity of the overall setup.

5. Configure Routing Based on Domain

Ensure that your routing is configured to direct users to the correct project based on the domain they are accessing. This will ensure that each domain serves the appropriate locale, enhancing user experience and maintaining consistency across different regions.

6. Deploy and Verify

After configuring the layers and deploying them to their respective domains, ensure each domain is serving the correct locale. Test the application thoroughly to confirm that the correct locale is loaded depending on the domain.

📝 Best Practices

  • Keep Base Configuration Generic: The base configuration should cover general settings applicable to all domains.
  • Isolate Domain-Specific Logic: Keep domain-specific configurations in their respective layers to maintain clarity and separation of concerns.

🎉 Conclusion

By leveraging layers in Nuxt I18n Micro, you can create a flexible and maintainable multi-domain localization setup. This approach not only eliminates the need for complex domain management functionalities but also allows you to distribute the load efficiently and reduce project complexity. Running separate projects for different locales ensures that your application can scale easily and adapt to different locale requirements across various domains, providing a robust and scalable solution for global applications.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/per-component-translations.html b/guide/per-component-translations.html new file mode 100644 index 0000000..9d84cf8 --- /dev/null +++ b/guide/per-component-translations.html @@ -0,0 +1,79 @@ + + + + + + 📖 Per-Component Translations in Nuxt I18n Micro | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

📖 Per-Component Translations in Nuxt I18n Micro

Overview

Per-Component Translations in Nuxt I18n Micro allows developers to define translations directly within specific components or pages of a Nuxt application using the $defineI18nRoute function. This approach is ideal for managing localized content that is unique to individual components, providing a more modular and maintainable method for handling translations.

$defineI18nRoute Function

The $defineI18nRoute function configures route behavior based on the current locale, offering a versatile solution to:

  • Control access to specific routes based on available locales.
  • Provide translations for specific locales.
  • Set custom routes for different locales.

Method Signature

typescript
$defineI18nRoute(routeDefinition: { 
+  locales?: string[] | Record<string, Record<string, TranslationObject>>, 
+  localeRoutes?: Record<string, string> 
+})

Parameters

  • locales: Defines which locales are available for the route. This can be:

    • An array of strings, where each string is an available locale (e.g., ['en', 'fr', 'de']).
    • An object where each key is a locale code, and the value is an object containing translations or an empty object if no translations are needed.
  • localeRoutes: Allows custom routes for specific locales. Each key represents a locale code, and the value is the custom route path for that locale. This is useful for scenarios where different locales require unique routing.

Example Usage

typescript
$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+    de: { greeting: 'Hallo', farewell: 'Auf Wiedersehen' },
+  },
+  localeRoutes: {
+    ru: '/localesubpage', // Custom route path for the Russian locale
+  },
+})

Use Cases

  1. Controlling Access Based on Locales: Define which locales are allowed for specific routes to ensure users only see content relevant to their language.

    typescript
    import { useNuxtApp } from '#imports'
    +
    +const { $defineI18nRoute } = useNuxtApp()
    +
    +$defineI18nRoute({
    +  locales: ['en', 'fr', 'de'] // Only these locales are allowed for this route
    +})
  2. Providing Translations for Locales: Use the locales object to provide specific translations for each route, enhancing the user experience by delivering content in the user's preferred language.

    typescript
    import { useNuxtApp } from '#imports'
    +
    +const { $defineI18nRoute } = useNuxtApp()
    +
    +$defineI18nRoute({
    +  locales: {
    +    en: { greeting: 'Hello', farewell: 'Goodbye' },
    +    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
    +    de: { greeting: 'Hallo', farewell: { aaa: { bbb: "Auf Wiedersehen" } } },
    +    ru: {} // Russian locale is allowed but no translations are provided
    +  }
    +})
  3. Custom Routing for Locales: Define custom paths for specific locales using the localeRoutes property. This allows you to create unique navigational flows or URL structures for different languages or regions.

Best Practices

  • Keep Translations Close to Components: Define translations directly within the relevant component to keep localized content organized and maintainable.
  • Use Locale Objects for Flexibility: Utilize the object format for the locales property when specific translations or access control based on locales are required.
  • Document Custom Routes: Clearly document any custom routes set for different locales to maintain clarity and simplify development and maintenance.

Here's an example of a Vue page using defineI18nRoute for per-component translations:

Example: Vue Page with Per-Component Translations

Below is an example of how to use $defineI18nRoute within a Vue component to handle translations and custom routing based on locale.

vue
<template>
+  <div>
+    <h1>{{ t('greeting') }}</h1>
+    <p>{{ t('farewell') }}</p>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useNuxtApp } from '#imports'
+
+// Access the $defineI18nRoute function from Nuxt's context
+const { $defineI18nRoute, $t: t } = useNuxtApp()
+
+// Define i18n route with translations for specific locales
+$defineI18nRoute({
+  locales: {
+    en: { greeting: 'Hello', farewell: 'Goodbye' },
+    fr: { greeting: 'Bonjour', farewell: 'Au revoir' },
+    de: { greeting: 'Hallo', farewell: 'Auf Wiedersehen' },
+    ru: { greeting: 'Привет', farewell: 'До свидания' },
+  },
+  localeRoutes: {
+    ru: '/ru-specific-path', // Custom route path for the Russian locale
+    fr: '/fr-specific-path'  // Custom route path for the French locale
+  }
+})
+</script>

Explanation

  • Component-Level Translations: The translations are defined directly in the component using the locales property of $defineI18nRoute. This keeps translations closely tied to the component, making them easy to manage and update.
  • Custom Routing: The localeRoutes property is used to set specific paths for different locales. This allows for unique navigational flows based on the user's language preference.

This setup enables the component to display localized greetings and farewells based on the current locale, and it also allows for custom routes tailored to specific locales, enhancing the user experience by delivering content in the preferred language and structure.

Summary

The Per-Component Translations feature, powered by the $defineI18nRoute function, offers a powerful and flexible way to manage localization within your Nuxt application. By allowing localized content and routing to be defined at the component level, it helps create a highly customized and user-friendly experience tailored to the language and regional preferences of your audience.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/performance-results.html b/guide/performance-results.html new file mode 100644 index 0000000..da4618c --- /dev/null +++ b/guide/performance-results.html @@ -0,0 +1,24 @@ + + + + + + Performance Test Results | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

Performance Test Results

Project Information

Description:

This performance test compares two implementations of internationalization: i18n-micro and i18n. The main focus of the test is to evaluate build times, memory usage, CPU usage, and the performance of the server under stress (e.g., how many requests can be handled and how efficiently). The i18n-micro implementation shows slightly lower overall script execution times. This difference is attributed to its ability to handle more requests, which requires additional time for processing.

Important Note:

It is essential to recognize that the example used in this test is not entirely representative of the intended usage pattern for i18n-micro. The example simplifies the translation structure by consolidating all translations into a single file. However, i18n-micro is optimized for scenarios where translations are organized on a per-page basis. This approach allows for more granular control and efficiency, particularly in large-scale applications. The current setup is used merely for demonstration purposes and may not fully showcase the potential performance benefits of i18n-micro in real-world applications.


Build Performance for ./test/fixtures/i18n-micro

  • Build Time: 6.29 seconds
  • Max CPU Usage: 185.60%
  • Min CPU Usage: 84.60%
  • Average CPU Usage: 146.67%
  • Max Memory Usage: 1082.77 MB
  • Min Memory Usage: 172.28 MB
  • Average Memory Usage: 511.04 MB

Build Performance for ./test/fixtures/i18n

  • Build Time: 88.02 seconds
  • Max CPU Usage: 384.40%
  • Min CPU Usage: 84.70%
  • Average CPU Usage: 144.63%
  • Max Memory Usage: 9610.03 MB
  • Min Memory Usage: 196.80 MB
  • Average Memory Usage: 3642.73 MB

⏱️ Build Time and Resource Consumption

i18n
  • Build Time: 88.02 seconds
  • Max CPU Usage: 384.40%
  • Max Memory Usage: 9610.03 MB
i18n-micro
  • Build Time: 6.29 seconds
  • Max CPU Usage: 185.60%
  • Max Memory Usage: 1082.77 MB

Performance Comparison

  • i18n-micro: 6.29 seconds, Max Memory: 1082.77 MB, Max CPU: 185.60%
  • i18n: 88.02 seconds, Max Memory: 9610.03 MB, Max CPU: 384.40%
  • Time Difference: -81.73 seconds
  • Memory Difference: -8527.27 MB
  • CPU Usage Difference: -198.80%

Stress Test with Artillery for ./test/fixtures/i18n

  • Max CPU Usage: 155.10%
  • Min CPU Usage: 0.00%
  • Average CPU Usage: 95.97%
  • Max Memory Usage: 801.61 MB
  • Min Memory Usage: 49.72 MB
  • Average Memory Usage: 592.90 MB
  • Stress Test Time: 69.38 seconds
  • Average Response Time: 439.40 ms
  • Min Response Time: 1.00 ms
  • Max Response Time: 2994.00 ms
  • Requests per Second: 281.00
  • Error Rate: 0.00%

Stress Test with Artillery for ./test/fixtures/i18n-micro

  • Max CPU Usage: 130.70%
  • Min CPU Usage: 0.00%
  • Average CPU Usage: 91.83%
  • Max Memory Usage: 344.05 MB
  • Min Memory Usage: 48.22 MB
  • Average Memory Usage: 288.08 MB
  • Stress Test Time: 68.58 seconds
  • Average Response Time: 364.80 ms
  • Min Response Time: 0.00 ms
  • Max Response Time: 2483.00 ms
  • Requests per Second: 311.00
  • Error Rate: 0.00%

Comparison between i18n and i18n-micro

  • Max Memory Used Difference: -457.56 MB
  • Min Memory Used Difference: -1.50 MB
  • Avg Memory Used Difference: -304.82 MB
  • Max CPU Usage Difference: -24.40%
  • Min CPU Usage Difference: 0.00%
  • Avg CPU Usage Difference: -4.14%
  • Stress Test Time Difference: 0.00 seconds
  • Average Response Time Difference: -74.60 ms
  • Min Response Time Difference: -1.00 ms
  • Max Response Time Difference: -511.00 ms
  • Requests Per Second Difference: 30.00
  • Error Rate Difference: 0.00%

📊 Detailed Performance Analysis

🔍 Test Logic Explanation

The performance tests conducted for Nuxt I18n Micro and nuxt-i18n are designed to simulate real-world usage scenarios. Below is an overview of the key aspects of the test methodology:

  1. Build Time: Measures the time required to build the project, focusing on how efficiently each module handles large translation files.
  2. CPU Usage: Tracks the CPU load during the build and stress tests to assess the impact on server resources.
  3. Memory Usage: Monitors memory consumption to determine how each module manages memory, especially under high load.
  4. Stress Testing: Simulates a series of requests to evaluate the server's ability to handle concurrent traffic. The test is divided into two phases:
  • Warm-up Phase: Over 6 seconds, one request per second is sent to each of the specified URLs, with a maximum of 6 users, to ensure that the server is ready for the main test.
  • Main Test Phase: For 60 seconds, the server is subjected to 60 requests per second, spread across various endpoints, to measure response times, error rates, and overall throughput under load.

🛠 Why This Approach?

The chosen testing methodology is designed to reflect the scenarios that developers are likely to encounter in production environments. By focusing on build time, CPU and memory usage, and server performance under load, the tests provide a comprehensive view of how each module will perform in a large-scale, high-traffic application.

Nuxt I18n Micro is optimized for:

  • Faster Build Times: By reducing the overhead during the build process.
  • Lower Resource Consumption: Minimizing CPU and memory usage, making it suitable for resource-constrained environments.
  • Better Handling of Large Projects: With a focus on scalability, ensuring that applications remain responsive even as they grow.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/performance.html b/guide/performance.html new file mode 100644 index 0000000..702ac32 --- /dev/null +++ b/guide/performance.html @@ -0,0 +1,24 @@ + + + + + + 🚀 Performance Guide | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🚀 Performance Guide

📖 Introduction

Nuxt I18n Micro is designed with performance in mind, offering a significant improvement over traditional internationalization (i18n) modules like nuxt-i18n. This guide provides an in-depth look at the performance benefits of using Nuxt I18n Micro, and how it compares to other solutions.

🤔 Why Focus on Performance?

In large-scale projects and high-traffic environments, performance bottlenecks can lead to slow build times, increased memory usage, and poor server response times. These issues become more pronounced with complex i18n setups involving large translation files. Nuxt I18n Micro was built to address these challenges head-on by optimizing for speed, memory efficiency, and minimal impact on your application’s bundle size.

📊 Performance Comparison

We conducted a series of tests to demonstrate the performance improvements that Nuxt I18n Micro brings to the table. Below is a detailed comparison between Nuxt I18n Micro and the traditional nuxt-i18n module, based on identical conditions with a 10MB translation file on the same hardware.

⏱️ Build Time and Resource Consumption

Nuxt I18n
  • Total Size: 54.7 MB (3.31 MB gzip)
  • Max CPU Usage: 391.4%
  • Max Memory Usage: 8305 MB
  • Elapsed Time: 1m 31s

Nuxt I18n Micro

  • Total Size: 1.93 MB (473 kB gzip) — 96% smaller
  • Max CPU Usage: 220.1% — 44% lower
  • Max Memory Usage: 655 MB — 92% less memory
  • Elapsed Time: 0m 5s — 94% faster

🌐 Server Performance Under Load

We also tested server performance by simulating 10,000 requests to each module.

Nuxt I18n
  • Requests per Second: 49.05 [#/sec] (mean)
  • Time per Request: 611.599 ms (mean)
  • Max Memory Usage: 703.73 MB

Nuxt I18n Micro

  • Requests per Second: 61.18 [#/sec] (mean) — 25% more requests per second
  • Time per Request: 490.379 ms (mean) — 20% faster
  • Max Memory Usage: 323.00 MB — 54% less memory usage

🔍 Interpretation of Results

These tests clearly indicate that Nuxt I18n Micro offers superior performance across multiple metrics:

  • 🗜️ Smaller Bundle Size: Reduces the overall size of your application bundle, leading to faster load times and better user experience.
  • 🔋 Lower CPU Usage: Decreases the load on your server’s CPU, allowing for more efficient processing of requests.
  • 🧠 Reduced Memory Consumption: Significantly lowers memory usage, minimizing the risk of memory leaks and enabling your application to handle larger workloads.
  • 🕒 Faster Build Times: Drastically reduces build times, which is particularly beneficial during development and CI/CD processes.

⚙️ Key Optimizations

🛠️ Minimalist Design

Nuxt I18n Micro is built around a minimalist architecture, using only 5 components (1 module and 4 plugins). This reduces overhead and simplifies the internal logic, leading to improved performance.

🚦 Efficient Routing

Unlike other i18n modules that generate a separate route for each locale, Nuxt I18n Micro uses dynamic regex-based routing. This approach generates only two routes regardless of the number of locales, significantly reducing the complexity of your routing configuration and speeding up route resolution.

📂 Streamlined Translation Loading

The module supports only JSON files for translations, with a clear separation between global and page-specific files. This ensures that only the necessary translation data is loaded at any given time, further enhancing performance.

💾 Caching and Pre-rendering

To optimize performance, Nuxt I18n Micro implements caching and supports pre-rendering of translation files:

  • 🗄️ Caching: Translations are cached after the initial load, reducing the need for subsequent requests and improving response times.
  • 🏁 Pre-rendering: During the build process, translation files for all configured locales and routes can be pre-rendered. This eliminates the need for runtime requests, ensuring that translations are served quickly and efficiently.

📝 Tips for Maximizing Performance

Here are a few tips to ensure you get the best performance out of Nuxt I18n Micro:

  • 📉 Limit Locale Data: Only include the locales you need in your project to keep the bundle size small.
  • 🗂️ Use Page-Specific Translations: Organize your translation files by page to avoid loading unnecessary data.
  • 💾 Enable Caching: Make use of the caching features to reduce server load and improve response times.
  • 🏁 Leverage Pre-rendering: Pre-render your translations to speed up page loads and reduce runtime overhead.

For detailed results of the performance tests, please refer to the Performance Test Results.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/guide/seo.html b/guide/seo.html new file mode 100644 index 0000000..88d9633 --- /dev/null +++ b/guide/seo.html @@ -0,0 +1,36 @@ + + + + + + 🌐 SEO Guide for Nuxt I18n Micro | Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

🌐 SEO Guide for Nuxt I18n Micro

📖 Introduction

Effective SEO (Search Engine Optimization) is essential for ensuring that your multilingual site is accessible and visible to users worldwide through search engines. Nuxt I18n Micro simplifies the process of managing SEO for multilingual sites by automatically generating essential meta tags and attributes that inform search engines about the structure and content of your site.

This guide explains how Nuxt I18n Micro handles SEO to enhance your site's visibility and user experience without requiring additional configuration.

⚙️ Automatic SEO Handling

🔑 Key SEO Features

When the meta option is enabled in Nuxt I18n Micro, the module automatically manages the following SEO aspects:

  1. 🌍 Language and Direction Attributes:

    • The module sets the lang and dir attributes on the <html> tag according to the current locale and text direction (e.g., ltr for English or rtl for Arabic).
  2. 🔗 Canonical URLs:

    • The module generates a canonical link (<link rel="canonical">) for each page, ensuring that search engines recognize the primary version of the content.
  3. 🌐 Alternate Language Links (hreflang):

    • The module automatically generates <link rel="alternate" hreflang=""> tags for all available locales. This helps search engines understand which language versions of your content are available, improving the user experience for global audiences.
  4. 🔖 Open Graph Metadata:

    • The module generates Open Graph meta tags (og:locale, og:url, etc.) for each locale, which is particularly useful for social media sharing and search engine indexing.

🛠️ Configuration

To enable these SEO features, ensure the meta option is set to true in your nuxt.config.ts file:

typescript
export default defineNuxtConfig({
+  modules: ['nuxt-i18n-micro'],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true, // Enables automatic SEO management
+  },
+})

🎯 Benefits

By enabling the meta option, you benefit from:

  • 📈 Improved Search Engine Rankings: Search engines can better index your site, understanding the relationships between different language versions.
  • 👥 Better User Experience: Users are served the correct language version based on their preferences, leading to a more personalized experience.
  • 🔧 Reduced Manual Configuration: The module handles SEO tasks automatically, freeing you from the need to manually add SEO-related meta tags and attributes.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/hashmap.json b/hashmap.json new file mode 100644 index 0000000..e94af2d --- /dev/null +++ b/hashmap.json @@ -0,0 +1 @@ +{"api_events.md":"D1_p7qRJ","api_methods.md":"CeANTGTe","components_i18n-link.md":"Brr4ULLV","components_i18n-switcher.md":"CZU12ZBI","components_i18n-t.md":"Dn3NUPHA","composables_usei18n.md":"7DLszJoL","composables_uselocalehead.md":"BS009Eh1","examples.md":"dgk20VMv","guide_cli.md":"ZyFjsvrl","guide_contribution.md":"BHsQWQY9","guide_crowdin.md":"DEb4srNU","guide_custom-locale-routes.md":"DeZ1f3q2","guide_faq.md":"Vyfgzyoq","guide_folder-structure.md":"Cky6Juvc","guide_getting-started.md":"-u7BlIMn","guide_layers.md":"Dy4zl8SE","guide_migration.md":"CUupWGuG","guide_multi-domain-locales.md":"BMPCs2fg","guide_per-component-translations.md":"DC4w94aF","guide_performance-results.md":"BbKR1XsP","guide_performance.md":"SXcHzDO5","guide_seo.md":"BpSpRrpu","index.md":"CpgHYvSM"} diff --git a/index.html b/index.html new file mode 100644 index 0000000..f41276d --- /dev/null +++ b/index.html @@ -0,0 +1,50 @@ + + + + + + Nuxt I18n Micro + + + + + + + + + + + + + +
Skip to content

Nuxt I18n Micro

Fast, Simple, and Lightweight Internationalization for Nuxt

Optimize your Nuxt app with a powerful and efficient i18n solution.


✨ Introduction

Nuxt I18n Micro is a fast, simple, and lightweight internationalization (i18n) module for Nuxt. Despite its compact size, it's designed with large projects in mind, offering significant performance improvements over traditional i18n solutions like nuxt-i18n. The module was built from the ground up to be highly efficient, focusing on minimizing build times, reducing server load, and shrinking bundle sizes.

📝 Why Nuxt I18n Micro?

The Nuxt I18n Micro module was created to address critical performance issues found in the original nuxt-i18n module, particularly in high-traffic environments and projects with large translation files. Key issues with nuxt-i18n include:

  • 🚨 High Memory Consumption: Consumes significant memory during both build and runtime, leading to performance bottlenecks.
  • 🐢 Slow Performance: Especially with large translation files, it causes noticeable slowdowns in build times and server response.
  • 💼 Large Bundle Size: Generates a large bundle, negatively impacting application performance.
  • 🐛 Memory Leaks and Bugs: Known for memory leaks and unpredictable behavior under heavy load.

🏁 Performance Comparison

To showcase the efficiency of Nuxt I18n Micro, we conducted tests under identical conditions. Both modules were tested with a 10MB translation file on the same hardware.

⏱️ Build Time and Resource Consumption

Nuxt I18n
  • Total Size: 54.7 MB (3.31 MB gzip)
  • Max CPU Usage: 391.4%
  • Max Memory Usage: 8305 MB
  • Elapsed Time: 0h 1m 31s

Nuxt I18n Micro

  • Total Size: 1.93 MB (473 kB gzip) — 96% smaller
  • Max CPU Usage: 220.1% — 44% lower
  • Max Memory Usage: 655 MB — 92% less memory
  • Elapsed Time: 0h 0m 5s — 94% faster

🌐 Server Performance (10k Requests)

Nuxt I18n
  • Requests per Second: 49.05 [#/sec] (mean)
  • Time per Request: 611.599 ms (mean)
  • Max Memory Usage: 703.73 MB

Nuxt I18n Micro

  • Requests per Second: 61.18 [#/sec] (mean) — 25% more requests per second
  • Time per Request: 490.379 ms (mean) — 20% faster
  • Max Memory Usage: 323.00 MB — 54% less memory usage

These results clearly demonstrate that Nuxt I18n Micro significantly outperforms the original module in every critical area.

🔑 Key Features

  • 🌐 Compact Yet Powerful: Despite its small size, Nuxt I18n Micro is designed for large-scale projects, focusing on performance and efficiency.
  • Optimized Build and Runtime: Reduces build times, memory usage, and server load, making it ideal for high-traffic applications.
  • 🛠️ Minimalist Design: The module is structured around just 5 components (1 module and 4 plugins), making it easy to understand, extend, and maintain.
  • 📏 Efficient Routing: Generates only 2 routes regardless of the number of locales, thanks to dynamic regex-based routing, unlike other i18n modules that generate separate routes for each locale.
  • 🗂 Streamlined Translation Loading: Only JSON files are supported, with translations split between a global file for common texts (e.g., menus) and page-specific files, which are auto-generated in the dev mode if not present.

⚙️ Quick Setup

Install the module in your Nuxt application with:

bash
npm install nuxt-i18n-micro

Then, add it to your nuxt.config.ts:

typescript
export default defineNuxtConfig({
+  modules: [
+    'nuxt-i18n-micro',
+  ],
+  i18n: {
+    locales: [
+      { code: 'en', iso: 'en-US', dir: 'ltr' },
+      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
+      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
+    ],
+    defaultLocale: 'en',
+    translationDir: 'locales',
+    meta: true,
+  },
+})

That's it! You're now ready to use Nuxt I18n Micro in your Nuxt app.

🗂 Folder Structure

Translations are organized into global and page-specific files:

plaintext
  /locales
+  ├── /pages
+  │   ├── /index
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  │   ├── /about
+  │   │   ├── en.json
+  │   │   ├── fr.json
+  │   │   └── ar.json
+  ├── en.json
+  ├── fr.json
+  └── ar.json

Released under the MIT License.

+ + + + \ No newline at end of file