Merge branch 'mealie-next' into fix/shopping-list-only-checkbox-tick-off

This commit is contained in:
Mario Džoić 2025-07-21 16:15:53 +02:00 committed by GitHub
commit ffced131d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 1297 additions and 1283 deletions

View file

@ -12,7 +12,7 @@ repos:
exclude: ^tests/data/
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.12.3
rev: v0.12.4
hooks:
- id: ruff
- id: ruff-format

View file

@ -179,9 +179,15 @@ def inject_nuxt_values():
all_langs = []
for match in locales_dir.glob("*.json"):
lang_string = f'{{ code: "{match.stem}", file: "{match.name.replace(".json", ".ts")}" }},'
match_data = LOCALE_DATA.get(match.stem)
match_dir = match_data.dir if match_data else "ltr"
lang_string = f'{{ code: "{match.stem}", file: "{match.name.replace(".json", ".ts")}", dir: "{match_dir}" }},'
all_langs.append(lang_string)
all_langs.sort()
all_date_locales.sort()
log.debug(f"injecting locales into nuxt config -> {nuxt_config}")
inject_inline(nuxt_config, CodeKeys.nuxt_local_messages, all_langs)
inject_inline(i18n_config, CodeKeys.nuxt_local_dates, all_date_locales)

View file

@ -31,7 +31,7 @@ To deploy mealie on your local network, it is highly recommended to use Docker t
We've gone through a few versions of Mealie v1 deployment targets. We have settled on a single container deployment, and we've begun publishing the nightly container on github containers. If you're looking to move from the old nightly (split containers _or_ the omni image) to the new nightly, there are a few things you need to do:
1. Take a backup just in case!
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.0.1`
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.0.2`
3. Take the external port from the frontend container and set that as the port mapped to port `9000` on the new container. The frontend is now served on port 9000 from the new container, so it will need to be mapped for you to have access.
4. Restart the container

View file

@ -7,7 +7,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.0.1 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.0.2 # (3)
container_name: mealie
restart: always
ports:

View file

@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.0.1 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.0.2 # (3)
container_name: mealie
restart: always
ports:

View file

@ -125,25 +125,20 @@
</v-list-item>
<div v-if="useItems.recipeActions && recipeActions && recipeActions.length">
<v-divider />
<v-list-group @click.stop>
<template #activator="{ props }">
<v-list-item-title v-bind="props">
{{ $t("recipe.recipe-actions") }}
</v-list-item-title>
<v-list-item
v-for="(action, index) in recipeActions"
:key="index"
@click="executeRecipeAction(action)"
>
<template #prepend>
<v-icon color="undefined">
{{ $globals.icons.linkVariantPlus }}
</v-icon>
</template>
<v-list density="compact" class="ma-0 pa-0">
<v-list-item
v-for="(action, index) in recipeActions"
:key="index"
class="pl-6"
@click="executeRecipeAction(action)"
>
<v-list-item-title>
{{ action.title }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-list-group>
<v-list-item-title>
{{ action.title }}
</v-list-item-title>
</v-list-item>
</div>
</v-list>
</v-menu>

View file

@ -3,12 +3,13 @@
v-model="selected"
item-key="id"
show-select
:sort-by="[{ key: 'dateAdded', order: 'desc' }]"
:sort-by="sortBy"
:headers="headers"
:items="recipes"
:items-per-page="15"
class="elevation-0"
:loading="loading"
return-object
>
<template #[`item.name`]="{ item }">
<a
@ -117,7 +118,7 @@ export default defineNuxtComponent({
},
},
},
emits: ["click"],
emits: ["click", "update:modelValue"],
setup(props, context) {
const i18n = useI18n();
const $auth = useMealieAuth();
@ -128,6 +129,9 @@ export default defineNuxtComponent({
set: value => context.emit(INPUT_EVENT, value),
});
// Initialize sort state with default sorting by dateAdded descending
const sortBy = ref([{ key: "dateAdded", order: "desc" }]);
const headers = computed(() => {
const hdrs: Array<{ title: string; value: string; align?: string; sortable?: boolean }> = [];
@ -206,6 +210,7 @@ export default defineNuxtComponent({
return {
selected,
sortBy,
groupSlug,
headers,
formatDate,

View file

@ -7,13 +7,14 @@
<v-card-text>
{{ $t("language-dialog.select-description") }}
<v-autocomplete
v-model="locale"
v-model="selectedLocale"
:items="locales"
item-title="name"
item-value="value"
class="my-3"
hide-details
variant="outlined"
offset
@update:model-value="onLocaleSelect"
>
<template #item="{ item, props }">
<div
@ -59,6 +60,14 @@ export default defineNuxtComponent({
});
const { locales: LOCALES, locale, i18n } = useLocales();
const selectedLocale = ref(locale.value);
const onLocaleSelect = (value: string) => {
if (value && locales.some(l => l.value === value)) {
locale.value = value as any;
}
};
watch(locale, () => {
dialog.value = false; // Close dialog when locale changes
});
@ -72,6 +81,8 @@ export default defineNuxtComponent({
i18n,
locales,
locale,
selectedLocale,
onLocaleSelect,
};
},
});

View file

@ -33,7 +33,7 @@ export const LOCALES = [
{
name: "Svenska (Swedish)",
value: "sv-SE",
progress: 39,
progress: 47,
dir: "ltr",
},
{
@ -57,7 +57,7 @@ export const LOCALES = [
{
name: "Pусский (Russian)",
value: "ru-RU",
progress: 35,
progress: 37,
dir: "ltr",
},
{
@ -75,7 +75,7 @@ export const LOCALES = [
{
name: "Português do Brasil (Brazilian Portuguese)",
value: "pt-BR",
progress: 34,
progress: 36,
dir: "ltr",
},
{
@ -87,13 +87,13 @@ export const LOCALES = [
{
name: "Norsk (Norwegian)",
value: "no-NO",
progress: 37,
progress: 38,
dir: "ltr",
},
{
name: "Nederlands (Dutch)",
value: "nl-NL",
progress: 42,
progress: 44,
dir: "ltr",
},
{
@ -123,7 +123,7 @@ export const LOCALES = [
{
name: "Italiano (Italian)",
value: "it-IT",
progress: 37,
progress: 38,
dir: "ltr",
},
{
@ -135,7 +135,7 @@ export const LOCALES = [
{
name: "Magyar (Hungarian)",
value: "hu-HU",
progress: 39,
progress: 40,
dir: "ltr",
},
{
@ -147,19 +147,19 @@ export const LOCALES = [
{
name: "עברית (Hebrew)",
value: "he-IL",
progress: 37,
progress: 45,
dir: "rtl",
},
{
name: "Galego (Galician)",
value: "gl-ES",
progress: 37,
progress: 38,
dir: "ltr",
},
{
name: "Français (French)",
value: "fr-FR",
progress: 38,
progress: 49,
dir: "ltr",
},
{
@ -189,7 +189,7 @@ export const LOCALES = [
{
name: "Español (Spanish)",
value: "es-ES",
progress: 37,
progress: 40,
dir: "ltr",
},
{
@ -201,31 +201,31 @@ export const LOCALES = [
{
name: "British English",
value: "en-GB",
progress: 22,
progress: 23,
dir: "ltr",
},
{
name: "Ελληνικά (Greek)",
value: "el-GR",
progress: 37,
progress: 38,
dir: "ltr",
},
{
name: "Deutsch (German)",
value: "de-DE",
progress: 55,
progress: 63,
dir: "ltr",
},
{
name: "Dansk (Danish)",
value: "da-DK",
progress: 37,
progress: 38,
dir: "ltr",
},
{
name: "Čeština (Czech)",
value: "cs-CZ",
progress: 37,
progress: 40,
dir: "ltr",
},
{

View file

@ -3,8 +3,6 @@ import { LOCALES } from "./available-locales";
export const useLocales = () => {
const i18n = useI18n();
const { isRtl } = useRtl();
const { current: vuetifyLocale } = useLocale();
const locale = computed<LocaleObject["code"]>({
@ -13,18 +11,21 @@ export const useLocales = () => {
i18n.setLocale(value);
},
});
function updateLocale(lc: LocaleObject["code"]) {
vuetifyLocale.value = lc;
}
// auto update vuetify locale
watch(locale, (lc) => {
vuetifyLocale.value = lc;
});
// auto update rtl
watch(vuetifyLocale, (vl) => {
const currentLocale = LOCALES.find(lc => lc.value === vl);
if (currentLocale) {
isRtl.value = currentLocale.dir === "rtl";
}
updateLocale(lc);
});
// set initial locale
if (i18n.locale.value) {
updateLocale(i18n.locale.value);
};
return {
locale,
locales: LOCALES,

View file

@ -1,47 +1,48 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const datetimeFormats = {
// CODE_GEN_ID: DATE_LOCALES
"tr-TR": require("./lang/dateTimeFormats/tr-TR.json"),
"zh-CN": require("./lang/dateTimeFormats/zh-CN.json"),
"ja-JP": require("./lang/dateTimeFormats/ja-JP.json"),
"en-GB": require("./lang/dateTimeFormats/en-GB.json"),
"af-ZA": require("./lang/dateTimeFormats/af-ZA.json"),
"ar-SA": require("./lang/dateTimeFormats/ar-SA.json"),
"bg-BG": require("./lang/dateTimeFormats/bg-BG.json"),
"ca-ES": require("./lang/dateTimeFormats/ca-ES.json"),
"cs-CZ": require("./lang/dateTimeFormats/cs-CZ.json"),
"da-DK": require("./lang/dateTimeFormats/da-DK.json"),
"de-DE": require("./lang/dateTimeFormats/de-DE.json"),
"el-GR": require("./lang/dateTimeFormats/el-GR.json"),
"en-GB": require("./lang/dateTimeFormats/en-GB.json"),
"en-US": require("./lang/dateTimeFormats/en-US.json"),
"es-ES": require("./lang/dateTimeFormats/es-ES.json"),
"et-EE": require("./lang/dateTimeFormats/et-EE.json"),
"fi-FI": require("./lang/dateTimeFormats/fi-FI.json"),
"fr-BE": require("./lang/dateTimeFormats/fr-BE.json"),
"fr-CA": require("./lang/dateTimeFormats/fr-CA.json"),
"fr-FR": require("./lang/dateTimeFormats/fr-FR.json"),
"gl-ES": require("./lang/dateTimeFormats/gl-ES.json"),
"he-IL": require("./lang/dateTimeFormats/he-IL.json"),
"hr-HR": require("./lang/dateTimeFormats/hr-HR.json"),
"hu-HU": require("./lang/dateTimeFormats/hu-HU.json"),
"is-IS": require("./lang/dateTimeFormats/is-IS.json"),
"it-IT": require("./lang/dateTimeFormats/it-IT.json"),
"ja-JP": require("./lang/dateTimeFormats/ja-JP.json"),
"ko-KR": require("./lang/dateTimeFormats/ko-KR.json"),
"lt-LT": require("./lang/dateTimeFormats/lt-LT.json"),
"lv-LV": require("./lang/dateTimeFormats/lv-LV.json"),
"nl-NL": require("./lang/dateTimeFormats/nl-NL.json"),
"no-NO": require("./lang/dateTimeFormats/no-NO.json"),
"pl-PL": require("./lang/dateTimeFormats/pl-PL.json"),
"pt-BR": require("./lang/dateTimeFormats/pt-BR.json"),
"pt-PT": require("./lang/dateTimeFormats/pt-PT.json"),
"ro-RO": require("./lang/dateTimeFormats/ro-RO.json"),
"sr-SP": require("./lang/dateTimeFormats/sr-SP.json"),
"hr-HR": require("./lang/dateTimeFormats/hr-HR.json"),
"de-DE": require("./lang/dateTimeFormats/de-DE.json"),
"zh-TW": require("./lang/dateTimeFormats/zh-TW.json"),
"af-ZA": require("./lang/dateTimeFormats/af-ZA.json"),
"fr-CA": require("./lang/dateTimeFormats/fr-CA.json"),
"he-IL": require("./lang/dateTimeFormats/he-IL.json"),
"pt-BR": require("./lang/dateTimeFormats/pt-BR.json"),
"cs-CZ": require("./lang/dateTimeFormats/cs-CZ.json"),
"fr-FR": require("./lang/dateTimeFormats/fr-FR.json"),
"ru-RU": require("./lang/dateTimeFormats/ru-RU.json"),
"is-IS": require("./lang/dateTimeFormats/is-IS.json"),
"sk-SK": require("./lang/dateTimeFormats/sk-SK.json"),
"el-GR": require("./lang/dateTimeFormats/el-GR.json"),
"fr-BE": require("./lang/dateTimeFormats/fr-BE.json"),
"da-DK": require("./lang/dateTimeFormats/da-DK.json"),
"hu-HU": require("./lang/dateTimeFormats/hu-HU.json"),
"es-ES": require("./lang/dateTimeFormats/es-ES.json"),
"gl-ES": require("./lang/dateTimeFormats/gl-ES.json"),
"no-NO": require("./lang/dateTimeFormats/no-NO.json"),
"lt-LT": require("./lang/dateTimeFormats/lt-LT.json"),
"en-US": require("./lang/dateTimeFormats/en-US.json"),
"sv-SE": require("./lang/dateTimeFormats/sv-SE.json"),
"ko-KR": require("./lang/dateTimeFormats/ko-KR.json"),
"bg-BG": require("./lang/dateTimeFormats/bg-BG.json"),
"sl-SI": require("./lang/dateTimeFormats/sl-SI.json"),
"sr-SP": require("./lang/dateTimeFormats/sr-SP.json"),
"sv-SE": require("./lang/dateTimeFormats/sv-SE.json"),
"tr-TR": require("./lang/dateTimeFormats/tr-TR.json"),
"uk-UA": require("./lang/dateTimeFormats/uk-UA.json"),
"lv-LV": require("./lang/dateTimeFormats/lv-LV.json"),
"ar-SA": require("./lang/dateTimeFormats/ar-SA.json"),
"nl-NL": require("./lang/dateTimeFormats/nl-NL.json"),
"vi-VN": require("./lang/dateTimeFormats/vi-VN.json"),
"fi-FI": require("./lang/dateTimeFormats/fi-FI.json"),
"zh-CN": require("./lang/dateTimeFormats/zh-CN.json"),
"zh-TW": require("./lang/dateTimeFormats/zh-TW.json"),
// END: DATE_LOCALES
};

View file

@ -0,0 +1,21 @@
{
"short": {
"month": "short",
"day": "numeric",
"weekday": "long"
},
"medium": {
"month": "long",
"day": "numeric",
"weekday": "long",
"year": "numeric"
},
"long": {
"year": "numeric",
"month": "long",
"day": "numeric",
"weekday": "long",
"hour": "numeric",
"minute": "numeric"
}
}

View file

@ -599,10 +599,10 @@
"create-recipe-from-an-image": "Opret opskrift fra et billede",
"create-recipe-from-an-image-description": "Opret en opskrift ved at overføre et billede af den. Mealie vil forsøge at udtrække teksten fra billedet med AI og oprette en opskrift fra det.",
"crop-and-rotate-the-image": "Beskær og roter billedet, så kun teksten er synlig, og det vises i den rigtige retning.",
"create-from-images": "Create from Images",
"create-from-images": "Opret fra billede",
"should-translate-description": "Oversæt opskriften til mit sprog",
"please-wait-image-procesing": "Vent venligst, billedet behandles. Dette kan tage lidt tid.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"please-wait-images-processing": "Vent venligst, billedet behandles. Dette kan tage lidt tid.",
"bulk-url-import": "Import fra flere URL-adresser",
"debug-scraper": "Fejlsøg indlæser",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Opret en opskrift ved at angive navnet. Alle opskrifter skal have unikke navne.",
@ -662,9 +662,9 @@
},
"reset-servings-count": "Nulstil antal serveringer",
"not-linked-ingredients": "Yderligere ingredienser",
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
"upload-another-image": "Upload et andet billede",
"upload-images": "Upload billeder",
"upload-more-images": "Upload flere billeder"
},
"recipe-finder": {
"recipe-finder": "Opskriftssøger",
@ -724,7 +724,7 @@
"backup-restore": "Backup / gendannelse",
"back-restore-description": "Gendannelse af denne sikkerhedskopi vil overskrive alle de aktuelle data i din database og i datamappen og erstatte dem med indholdet af denne sikkerhedskopi. {cannot-be-undone} Hvis gendannelsen lykkes, vil du blive logget ud.",
"cannot-be-undone": "Denne handling kan ikke fortrydes - brug med forsigtighed.",
"postgresql-note": "If you are using PostgreSQL, please review the {backup-restore-process} prior to restoring.",
"postgresql-note": "Hvis du bruger PostgreSQL, så gennemse venligst {backup-restore-process} før du gendanner.",
"backup-restore-process-in-the-documentation": "backup/restoreproces i dokumentationen",
"irreversible-acknowledgment": "Jeg forstår, at denne handling er irreversibel, destruktiv og kan forårsage tab af data",
"restore-backup": "Gendan sikkerhedskopi"

View file

@ -599,10 +599,10 @@
"create-recipe-from-an-image": "Crear receta a partir de una imagen",
"create-recipe-from-an-image-description": "Crea una receta cargando una imagen de ella. Mealie intentará extraer el texto de la imagen usando IA y crear una receta de ella.",
"crop-and-rotate-the-image": "Recortar y rotar la imagen de manera que sólo el texto sea visible, y esté en la orientación correcta.",
"create-from-images": "Create from Images",
"create-from-images": "Crear a partir de imágenes",
"should-translate-description": "Traducir la receta a mi idioma",
"please-wait-image-procesing": "Por favor, espere, la imagen se está procesando. Esto puede tardar un tiempo.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"please-wait-images-processing": "Por favor, espere, las imágenes se están procesando. Esto puede tardar algún tiempo.",
"bulk-url-import": "Importación masiva desde URL",
"debug-scraper": "Depurar analizador",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crear una receta proporcionando el nombre. Todas las recetas deben tener nombres únicos.",
@ -662,9 +662,9 @@
},
"reset-servings-count": "Restablecer contador de porciones",
"not-linked-ingredients": "Ingredientes adicionales",
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
"upload-another-image": "Subir otra imagen",
"upload-images": "Subir imágenes",
"upload-more-images": "Subir más imágenes"
},
"recipe-finder": {
"recipe-finder": "Buscador de recetas",

View file

@ -151,6 +151,7 @@ import {
mdiKnife,
mdiCookie,
mdiBellPlus,
mdiLinkVariantPlus,
} from "@mdi/js";
export const icons = {
@ -236,6 +237,7 @@ export const icons = {
informationOutline: mdiInformationOutline,
informationVariant: mdiInformationVariant,
link: mdiLink,
linkVariantPlus: mdiLinkVariantPlus,
lock: mdiLock,
logout: mdiLogout,
menu: mdiMenu,

View file

@ -175,114 +175,52 @@ export default defineNuxtConfig({
subsets: ["cyrillic-ext", "cyrillic", "greek-ext", "greek", "vietnamese", "latin-ext", "latin"],
},
},
/* auth: {
redirect: {
login: "/login",
logout: "/login",
callback: "/login",
home: "/",
},
cookie: {
prefix: "mealie.auth.",
options: {
expires: 7,
path: "/",
},
},
rewriteRedirects: false,
// Options
strategies: {
local: {
resetOnError: true,
token: {
property: "access_token",
global: true,
// required: true,
// type: 'Bearer'
},
user: {
property: "",
autoFetch: true,
},
endpoints: {
login: {
url: "api/auth/token",
method: "post",
propertyName: "access_token",
},
refresh: { url: "api/auth/refresh", method: "post" },
logout: { url: "api/auth/logout", method: "post" },
user: { url: "api/users/self", method: "get" },
},
},
oidc: {
scheme: "local",
resetOnError: true,
token: {
property: "access_token",
global: true,
},
user: {
property: "",
autoFetch: true,
},
endpoints: {
login: {
url: "api/auth/oauth/callback",
method: "get",
},
logout: { url: "api/auth/logout", method: "post" },
user: { url: "api/users/self", method: "get" },
},
},
},
}, */
i18n: {
locales: [
// CODE_GEN_ID: MESSAGE_LOCALES
{ code: "tr-TR", file: "tr-TR.ts" },
{ code: "zh-CN", file: "zh-CN.ts" },
{ code: "ja-JP", file: "ja-JP.ts" },
{ code: "en-GB", file: "en-GB.ts" },
{ code: "ca-ES", file: "ca-ES.ts" },
{ code: "it-IT", file: "it-IT.ts" },
{ code: "pl-PL", file: "pl-PL.ts" },
{ code: "pt-PT", file: "pt-PT.ts" },
{ code: "ro-RO", file: "ro-RO.ts" },
{ code: "sr-SP", file: "sr-SP.ts" },
{ code: "hr-HR", file: "hr-HR.ts" },
{ code: "de-DE", file: "de-DE.ts" },
{ code: "zh-TW", file: "zh-TW.ts" },
{ code: "af-ZA", file: "af-ZA.ts" },
{ code: "fr-CA", file: "fr-CA.ts" },
{ code: "he-IL", file: "he-IL.ts" },
{ code: "pt-BR", file: "pt-BR.ts" },
{ code: "cs-CZ", file: "cs-CZ.ts" },
{ code: "fr-FR", file: "fr-FR.ts" },
{ code: "ru-RU", file: "ru-RU.ts" },
{ code: "is-IS", file: "is-IS.ts" },
{ code: "sk-SK", file: "sk-SK.ts" },
{ code: "el-GR", file: "el-GR.ts" },
{ code: "fr-BE", file: "fr-BE.ts" },
{ code: "da-DK", file: "da-DK.ts" },
{ code: "hu-HU", file: "hu-HU.ts" },
{ code: "es-ES", file: "es-ES.ts" },
{ code: "gl-ES", file: "gl-ES.ts" },
{ code: "no-NO", file: "no-NO.ts" },
{ code: "lt-LT", file: "lt-LT.ts" },
{ code: "en-US", file: "en-US.ts" },
{ code: "sv-SE", file: "sv-SE.ts" },
{ code: "ko-KR", file: "ko-KR.ts" },
{ code: "bg-BG", file: "bg-BG.ts" },
{ code: "sl-SI", file: "sl-SI.ts" },
{ code: "uk-UA", file: "uk-UA.ts" },
{ code: "et-EE", file: "et-EE.ts" },
{ code: "lv-LV", file: "lv-LV.ts" },
{ code: "ar-SA", file: "ar-SA.ts" },
{ code: "nl-NL", file: "nl-NL.ts" },
{ code: "vi-VN", file: "vi-VN.ts" },
{ code: "fi-FI", file: "fi-FI.ts" },
{ code: "af-ZA", file: "af-ZA.ts", dir: "ltr" },
{ code: "ar-SA", file: "ar-SA.ts", dir: "rtl" },
{ code: "bg-BG", file: "bg-BG.ts", dir: "ltr" },
{ code: "ca-ES", file: "ca-ES.ts", dir: "ltr" },
{ code: "cs-CZ", file: "cs-CZ.ts", dir: "ltr" },
{ code: "da-DK", file: "da-DK.ts", dir: "ltr" },
{ code: "de-DE", file: "de-DE.ts", dir: "ltr" },
{ code: "el-GR", file: "el-GR.ts", dir: "ltr" },
{ code: "en-GB", file: "en-GB.ts", dir: "ltr" },
{ code: "en-US", file: "en-US.ts", dir: "ltr" },
{ code: "es-ES", file: "es-ES.ts", dir: "ltr" },
{ code: "et-EE", file: "et-EE.ts", dir: "ltr" },
{ code: "fi-FI", file: "fi-FI.ts", dir: "ltr" },
{ code: "fr-BE", file: "fr-BE.ts", dir: "ltr" },
{ code: "fr-CA", file: "fr-CA.ts", dir: "ltr" },
{ code: "fr-FR", file: "fr-FR.ts", dir: "ltr" },
{ code: "gl-ES", file: "gl-ES.ts", dir: "ltr" },
{ code: "he-IL", file: "he-IL.ts", dir: "rtl" },
{ code: "hr-HR", file: "hr-HR.ts", dir: "ltr" },
{ code: "hu-HU", file: "hu-HU.ts", dir: "ltr" },
{ code: "is-IS", file: "is-IS.ts", dir: "ltr" },
{ code: "it-IT", file: "it-IT.ts", dir: "ltr" },
{ code: "ja-JP", file: "ja-JP.ts", dir: "ltr" },
{ code: "ko-KR", file: "ko-KR.ts", dir: "ltr" },
{ code: "lt-LT", file: "lt-LT.ts", dir: "ltr" },
{ code: "lv-LV", file: "lv-LV.ts", dir: "ltr" },
{ code: "nl-NL", file: "nl-NL.ts", dir: "ltr" },
{ code: "no-NO", file: "no-NO.ts", dir: "ltr" },
{ code: "pl-PL", file: "pl-PL.ts", dir: "ltr" },
{ code: "pt-BR", file: "pt-BR.ts", dir: "ltr" },
{ code: "pt-PT", file: "pt-PT.ts", dir: "ltr" },
{ code: "ro-RO", file: "ro-RO.ts", dir: "ltr" },
{ code: "ru-RU", file: "ru-RU.ts", dir: "ltr" },
{ code: "sk-SK", file: "sk-SK.ts", dir: "ltr" },
{ code: "sl-SI", file: "sl-SI.ts", dir: "ltr" },
{ code: "sr-SP", file: "sr-SP.ts", dir: "ltr" },
{ code: "sv-SE", file: "sv-SE.ts", dir: "ltr" },
{ code: "tr-TR", file: "tr-TR.ts", dir: "ltr" },
{ code: "uk-UA", file: "uk-UA.ts", dir: "ltr" },
{ code: "vi-VN", file: "vi-VN.ts", dir: "ltr" },
{ code: "zh-CN", file: "zh-CN.ts", dir: "ltr" },
{ code: "zh-TW", file: "zh-TW.ts", dir: "ltr" },
// END: MESSAGE_LOCALES
],
strategy: "no_prefix",

View file

@ -1,6 +1,6 @@
{
"name": "mealie",
"version": "3.0.1",
"version": "3.0.2",
"private": true,
"scripts": {
"dev": "nuxt dev",

View file

@ -126,7 +126,7 @@
<!-- Alias Sub-Dialog -->
<RecipeDataAliasManagerDialog
v-if="editTarget"
:value="aliasManagerDialog"
v-model="aliasManagerDialog"
:data="editTarget"
@submit="updateFoodAlias"
@cancel="aliasManagerDialog = false"

View file

@ -4,7 +4,7 @@
<BaseDialog
v-model="state.createDialog"
:title="$t('data-pages.recipe-actions.new-recipe-action')"
:icon="$globals.icons.primary"
:icon="$globals.icons.linkVariantPlus"
can-submit
@submit="createAction"
>
@ -34,7 +34,7 @@
<!-- Edit Dialog -->
<BaseDialog
v-model="state.editDialog"
:icon="$globals.icons.primary"
:icon="$globals.icons.linkVariantPlus"
:title="$t('data-pages.recipe-actions.edit-recipe-action')"
:submit-text="$t('general.save')"
can-submit
@ -115,7 +115,7 @@
<!-- Data Table -->
<BaseCardSectionTitle
:icon="$globals.icons.primary"
:icon="$globals.icons.linkVariantPlus"
section
:title="$t('data-pages.recipe-actions.recipe-actions-data')"
/>

View file

@ -44,6 +44,7 @@
:title="$t('general.confirm')"
:icon="$globals.icons.alertCircle"
color="error"
can-confirm
@confirm="deleteTag"
>
<v-card-text>

View file

@ -52,6 +52,7 @@
:title="$t('general.confirm')"
:icon="$globals.icons.alertCircle"
color="error"
can-confirm
@confirm="deleteTool"
>
<v-card-text>

View file

@ -19,30 +19,16 @@
v-model="fromUnit"
return-object
:items="store"
item-title="id"
item-title="name"
:label="$t('data-pages.units.source-unit')"
>
<template #chip="{ item }">
{{ item.raw.name }}
</template>
<template #item="{ item }">
{{ item.raw.name }}
</template>
</v-autocomplete>
/>
<v-autocomplete
v-model="toUnit"
return-object
:items="store"
item-title="id"
item-title="name"
:label="$t('data-pages.units.target-unit')"
>
<template #chip="{ item }">
{{ item.raw.name }}
</template>
<template #item="{ item }">
{{ item.raw.name }}
</template>
</v-autocomplete>
/>
<template v-if="canMerge && fromUnit && toUnit">
<div class="text-center">

View file

@ -11,7 +11,7 @@
},
"servings-text": {
"makes": "Realizadas",
"serves": "Personas",
"serves": "Porciones",
"serving": "Porción",
"servings": "Porciones",
"yield": "Ración",

View file

@ -46,20 +46,20 @@
"red onion": {
"aliases": [],
"description": "",
"name": "red onion",
"plural_name": "Červená cibule"
"name": "červená cibule",
"plural_name": "červené cibule"
},
"yellow onion": {
"aliases": [],
"description": "",
"name": "yellow onion",
"name": "žlutá cibule",
"plural_name": "yellow onions"
},
"celery": {
"aliases": [],
"description": "",
"name": "celer",
"plural_name": "Celery"
"plural_name": "celery"
},
"jalapeno": {
"aliases": [],
@ -76,8 +76,8 @@
"shallot": {
"aliases": [],
"description": "",
"name": "shallot",
"plural_name": "shallots"
"name": "šalotka",
"plural_name": "šalotky"
},
"cherry tomato": {
"aliases": [],
@ -95,13 +95,13 @@
"aliases": [],
"description": "",
"name": "špenát",
"plural_name": "spinaches"
"plural_name": "špenát"
},
"sweet corn": {
"aliases": [],
"description": "",
"name": "sweet corn",
"plural_name": "sweet corns"
"name": "sladká kukuřice",
"plural_name": "sladké kukuřice"
},
"chile pepper": {
"aliases": [
@ -228,14 +228,14 @@
"radish": {
"aliases": [],
"description": "",
"name": "radish",
"plural_name": "radishes"
"name": "ředkvička",
"plural_name": "ředkvičky"
},
"red cabbage": {
"aliases": [],
"description": "",
"name": "red cabbage",
"plural_name": "red cabbages"
"name": "červené zelí",
"plural_name": "červené zelí"
},
"artichoke": {
"aliases": [],

View file

@ -4,62 +4,62 @@
"garlic": {
"aliases": [],
"description": "",
"name": "garlic",
"plural_name": "garlics"
"name": "hvidløg",
"plural_name": "hvidløg"
},
"onion": {
"aliases": [],
"description": "",
"name": "onion",
"plural_name": "onions"
"name": "løg",
"plural_name": "løg"
},
"bell pepper": {
"aliases": [],
"description": "",
"name": "bell pepper",
"plural_name": "bell peppers"
"name": "peberfrugt",
"plural_name": "peberfrugter"
},
"carrot": {
"aliases": [],
"description": "",
"name": "carrot",
"plural_name": "carrots"
"name": "gulerod",
"plural_name": "gulerødder"
},
"scallion": {
"aliases": [],
"description": "",
"name": "scallion",
"plural_name": "scallions"
"name": "forårsløg",
"plural_name": "forårsløg"
},
"zucchini": {
"aliases": [],
"description": "",
"name": "zucchini",
"plural_name": "zucchinis"
"name": "squash",
"plural_name": "squash"
},
"potato": {
"aliases": [],
"description": "",
"name": "potato",
"plural_name": "potatoes"
"name": "kartoffel",
"plural_name": "kartofler"
},
"red onion": {
"aliases": [],
"description": "",
"name": "red onion",
"plural_name": "red onions"
"name": "rødløg",
"plural_name": "rødløg"
},
"yellow onion": {
"aliases": [],
"description": "",
"name": "yellow onion",
"plural_name": "yellow onions"
"name": "løg",
"plural_name": "løg"
},
"celery": {
"aliases": [],
"description": "",
"name": "celery",
"plural_name": "celeries"
"name": "selleri",
"plural_name": "selleri"
},
"jalapeno": {
"aliases": [],
@ -70,64 +70,64 @@
"avocado": {
"aliases": [],
"description": "",
"name": "avocado",
"plural_name": "avocados"
"name": "avokado",
"plural_name": "avokadoer"
},
"shallot": {
"aliases": [],
"description": "",
"name": "shallot",
"plural_name": "shallots"
"name": "skalotteløg",
"plural_name": "skalotteløg"
},
"cherry tomato": {
"aliases": [],
"description": "",
"name": "cherry tomato",
"plural_name": "cherry tomatoes"
"name": "cherrytomat",
"plural_name": "cherrytomater"
},
"cucumber": {
"aliases": [],
"description": "",
"name": "cucumber",
"plural_name": "cucumbers"
"name": "agurk",
"plural_name": "agurker"
},
"spinach": {
"aliases": [],
"description": "",
"name": "spinach",
"plural_name": "spinaches"
"name": "spinat",
"plural_name": "spinat"
},
"sweet corn": {
"aliases": [],
"description": "",
"name": "sweet corn",
"plural_name": "sweet corns"
"name": "sød majs",
"plural_name": "sød majs"
},
"chile pepper": {
"aliases": [
"capsicum"
"peberfrugt"
],
"description": "",
"name": "chile pepper",
"plural_name": "chile peppers"
"name": "chilipeber",
"plural_name": "chilipeber"
},
"sweet potato": {
"aliases": [],
"description": "",
"name": "sweet potato",
"plural_name": "sweet potatoes"
"name": "sød kartoffel",
"plural_name": "søde kartofler"
},
"broccoli": {
"aliases": [],
"description": "",
"name": "broccoli",
"plural_name": "broccolis"
"plural_name": "broccoli"
},
"heart of palm": {
"aliases": [],
"description": "",
"name": "heart of palm",
"plural_name": "heart of palms"
"name": "palmehjerte",
"plural_name": "palmehjerter"
},
"baby green": {
"aliases": [],
@ -138,38 +138,38 @@
"pumpkin": {
"aliases": [],
"description": "",
"name": "pumpkin",
"plural_name": "pumpkins"
"name": "græskar",
"plural_name": "græskar"
},
"cauliflower": {
"aliases": [],
"description": "",
"name": "cauliflower",
"plural_name": "cauliflowers"
"name": "blomkål",
"plural_name": "blomkålshoveder"
},
"cabbage": {
"aliases": [],
"description": "",
"name": "cabbage",
"plural_name": "cabbages"
"plural_name": "kålhoveder"
},
"asparagu": {
"aliases": [],
"description": "",
"name": "asparagu",
"plural_name": "asparagus"
"name": "asparges",
"plural_name": "asparges"
},
"kale": {
"aliases": [],
"description": "",
"name": "kale",
"plural_name": "kales"
"name": "grønkål",
"plural_name": "grønkål"
},
"arugula": {
"aliases": [],
"description": "",
"name": "arugula",
"plural_name": "arugulas"
"name": "rucola",
"plural_name": "rucola"
},
"leek": {
"aliases": [],
@ -274,13 +274,13 @@
"aliases": [],
"description": "",
"name": "baby carrot",
"plural_name": "baby carrots"
"plural_name": "babygulerødder"
},
"mixed vegetable": {
"aliases": [],
"description": "",
"name": "mixed vegetable",
"plural_name": "mixed vegetables"
"name": "blandede grøntsager",
"plural_name": "blandede grøntsager"
},
"poblano pepper": {
"aliases": [],
@ -303,38 +303,38 @@
"cayenne pepper": {
"aliases": [],
"description": "",
"name": "cayenne pepper",
"plural_name": "cayenne peppers"
"name": "cayennepeber",
"plural_name": "cayennepeber"
},
"green tomato": {
"aliases": [],
"description": "",
"name": "green tomato",
"plural_name": "green tomatoes"
"name": "grøn tomat",
"plural_name": "grønne tomater"
},
"watercress": {
"aliases": [],
"description": "",
"name": "watercress",
"plural_name": "watercress"
"name": "brøndkarse",
"plural_name": "brøndkarse"
},
"iceberg": {
"aliases": [],
"description": "",
"name": "iceberg",
"plural_name": "icebergs"
"plural_name": "iceberg"
},
"mashed potato": {
"aliases": [],
"description": "",
"name": "mashed potato",
"plural_name": "mashed potatoes"
"name": "kartoffelmos",
"plural_name": "kartoffelmos"
},
"horseradish": {
"aliases": [],
"description": "",
"name": "horseradish",
"plural_name": "horseradishes"
"name": "peberrod",
"plural_name": "peberrod"
},
"chard": {
"aliases": [],
@ -383,14 +383,14 @@
"water chestnut": {
"aliases": [],
"description": "",
"name": "water chestnut",
"plural_name": "water chestnuts"
"name": "vand kastanje",
"plural_name": "vand kastanjer"
},
"turnip": {
"aliases": [],
"description": "",
"name": "turnip",
"plural_name": "turnips"
"name": "majroe",
"plural_name": "majroer"
},
"thai chile pepper": {
"aliases": [],
@ -401,8 +401,8 @@
"bok choy": {
"aliases": [],
"description": "",
"name": "bok choy",
"plural_name": "bok choy"
"name": "pak choi",
"plural_name": "pak choi"
},
"okra": {
"aliases": [],
@ -419,8 +419,8 @@
"corn cob": {
"aliases": [],
"description": "",
"name": "corn cob",
"plural_name": "corn cobs"
"name": "majskolbe",
"plural_name": "majskolber"
},
"radicchio": {
"aliases": [],
@ -505,14 +505,14 @@
"daikon": {
"aliases": [],
"description": "",
"name": "daikon",
"plural_name": "daikons"
"name": "kinaradise",
"plural_name": "kinaradiser"
},
"baby corn": {
"aliases": [],
"description": "",
"name": "baby corn",
"plural_name": "baby corns"
"name": "babymajs",
"plural_name": "babymajs"
},
"broccoli rabe": {
"aliases": [],
@ -577,8 +577,8 @@
"frisee": {
"aliases": [],
"description": "",
"name": "frisee",
"plural_name": "frisees"
"name": "friséesalat",
"plural_name": "friséesalat"
},
"anaheim pepper": {
"aliases": [],
@ -613,8 +613,8 @@
"pea shoot": {
"aliases": [],
"description": "",
"name": "pea shoot",
"plural_name": "pea shoots"
"name": "ærteskud",
"plural_name": "ærteskud"
},
"alfalfa": {
"aliases": [],
@ -628,26 +628,26 @@
"foods": {
"tomato": {
"aliases": [],
"description": "Yes they are a fruit",
"name": "tomato",
"plural_name": "tomatoes"
"description": "Ja de er en frugt",
"name": "tomat",
"plural_name": "tomater"
},
"lemon": {
"aliases": [],
"description": "",
"name": "lemon",
"plural_name": "lemons"
"name": "citron",
"plural_name": "citroner"
},
"lime": {
"aliases": [],
"description": "",
"name": "lime",
"plural_name": "limes"
"name": "limefrugt",
"plural_name": "limefrugter"
},
"apple": {
"aliases": [],
"description": "",
"name": "apple",
"name": "æble",
"plural_name": "apples"
},
"banana": {
@ -696,7 +696,7 @@
"aliases": [],
"description": "",
"name": "coconut",
"plural_name": "coconuts"
"plural_name": "kokosnødder"
},
"craisin": {
"aliases": [],
@ -707,80 +707,80 @@
"pear": {
"aliases": [],
"description": "",
"name": "pear",
"plural_name": "pears"
"name": "pære",
"plural_name": "pærer"
},
"grape": {
"aliases": [],
"description": "",
"name": "grape",
"plural_name": "grapes"
"name": "drue",
"plural_name": "vindruer"
},
"pomegranate": {
"aliases": [],
"description": "",
"name": "pomegranate",
"name": "granatæble",
"plural_name": "pomegranates"
},
"watermelon": {
"aliases": [],
"description": "",
"name": "watermelon",
"plural_name": "watermelons"
"name": "vandmelon",
"plural_name": "vandmeloner"
},
"rhubarb": {
"aliases": [],
"description": "",
"name": "rhubarb",
"plural_name": "rhubarbs"
"name": "rabarber",
"plural_name": "rabarber"
},
"dried apricot": {
"aliases": [],
"description": "",
"name": "dried apricot",
"plural_name": "dried apricots"
"name": "tørret abrikos",
"plural_name": "tørrede abrikoser"
},
"kiwi": {
"aliases": [],
"description": "",
"name": "kiwi",
"plural_name": "kiwis"
"name": "kiwifrugt",
"plural_name": "kiwifrugter"
},
"grapefruit": {
"aliases": [],
"description": "",
"name": "grapefruit",
"plural_name": "grapefruits"
"name": "grapefrugt",
"plural_name": "grapefrugter"
},
"plum": {
"aliases": [],
"description": "",
"name": "plum",
"plural_name": "plums"
"name": "blomme",
"plural_name": "blommer"
},
"fig": {
"aliases": [],
"description": "",
"name": "fig",
"plural_name": "figs"
"name": "figne",
"plural_name": "figner"
},
"apricot": {
"aliases": [],
"description": "",
"name": "apricot",
"plural_name": "apricots"
"name": "abrikos",
"plural_name": "abrikoser"
},
"currant": {
"aliases": [],
"description": "",
"name": "currant",
"plural_name": "currants"
"name": "solbær",
"plural_name": "solbær"
},
"mandarin": {
"aliases": [],
"description": "",
"name": "mandarin",
"plural_name": "mandarins"
"plural_name": "mandariner"
},
"prune": {
"aliases": [],

View file

@ -3724,7 +3724,7 @@
"aliases": [],
"description": "",
"name": "Latik",
"plural_name": "latiks"
"plural_name": "Latik"
},
"rice cream": {
"aliases": [],
@ -4039,8 +4039,8 @@
"ham steak": {
"aliases": [],
"description": "",
"name": "ham steak",
"plural_name": "ham steaks"
"name": "Schinkensteak",
"plural_name": "Schinkensteaks"
},
"venison": {
"aliases": [],
@ -4196,13 +4196,13 @@
"aliases": [],
"description": "",
"name": "Bauchspeck",
"plural_name": "back bacons"
"plural_name": "Rückenspeck"
},
"salt pork": {
"aliases": [],
"description": "",
"name": "Gepökeltes Schweinefleisch",
"plural_name": "salt porks"
"plural_name": "Gepökeltes Schweinefleisch"
},
"veal shank": {
"aliases": [],
@ -4273,8 +4273,8 @@
"ground bison": {
"aliases": [],
"description": "",
"name": "ground bison",
"plural_name": "ground bisons"
"name": "Bison-Hackfleisch",
"plural_name": "Bison-Hackfleisch"
},
"fresh sausage": {
"aliases": [],
@ -4433,8 +4433,8 @@
"turkey bacon": {
"aliases": [],
"description": "",
"name": "Truthahnspeck",
"plural_name": "turkey bacons"
"name": "Putenspeck",
"plural_name": "Putenspeck"
},
"duck": {
"aliases": [],
@ -4469,8 +4469,8 @@
"deli turkey": {
"aliases": [],
"description": "",
"name": "deli turkey",
"plural_name": "deli turkeys"
"name": "Puten-Aufschnitt",
"plural_name": "Puten-Aufschnitt"
},
"smoked turkey": {
"aliases": [],
@ -4482,7 +4482,7 @@
"aliases": [],
"description": "",
"name": "Putenfleisch",
"plural_name": "turkey meats"
"plural_name": "Putenfleisch"
},
"chicken quarter": {
"aliases": [],
@ -4535,8 +4535,8 @@
"turkey pepperoni": {
"aliases": [],
"description": "",
"name": "turkey pepperoni",
"plural_name": "turkey pepperonis"
"name": "Puten-Peperonisalami",
"plural_name": "Puten-Peperonisalami"
},
"turkey ham": {
"aliases": [],
@ -4601,8 +4601,8 @@
"turkey burger": {
"aliases": [],
"description": "",
"name": "turkey burger",
"plural_name": "turkey burgers"
"name": "Puten-Burger",
"plural_name": "Puten-Burger"
},
"chicken andouille": {
"aliases": [],
@ -4619,8 +4619,8 @@
"smoked turkey leg": {
"aliases": [],
"description": "",
"name": "smoked turkey leg",
"plural_name": "smoked turkey legs"
"name": "geräucherte Putenkeule",
"plural_name": "geräucherte Putenkeulen"
},
"chicken italian sausage": {
"aliases": [],
@ -4661,14 +4661,14 @@
"chicken foot": {
"aliases": [],
"description": "",
"name": "chicken foot",
"plural_name": "chicken feet"
"name": "Hühnerfuß",
"plural_name": "Hühnerfüße"
},
"pulled chicken": {
"aliases": [],
"description": "",
"name": "pulled chicken",
"plural_name": "pulled chickens"
"name": "Pulled Chicken",
"plural_name": "Pulled Chicken"
},
"deli chicken": {
"aliases": [],
@ -4679,7 +4679,7 @@
"smoked duck breast": {
"aliases": [],
"description": "",
"name": "smoked duck breast",
"name": "geräucherte Entenbrust",
"plural_name": "smoked duck breasts"
},
"pigeon": {
@ -4715,8 +4715,8 @@
"roast duck": {
"aliases": [],
"description": "",
"name": "roast duck",
"plural_name": "roast ducks"
"name": "Entenbraten",
"plural_name": "Entenbraten"
},
"chicken meatball": {
"aliases": [],
@ -4733,8 +4733,8 @@
"guinea fowl": {
"aliases": [],
"description": "",
"name": "guinea fowl",
"plural_name": "guinea fowls"
"name": "Perlhuhn",
"plural_name": "Perlhühner"
},
"smoked turkey wing": {
"aliases": [],
@ -4787,8 +4787,8 @@
"turkey roast": {
"aliases": [],
"description": "",
"name": "turkey roast",
"plural_name": "turkey roasts"
"name": "Putenbraten",
"plural_name": "Putenbraten"
},
"capon": {
"aliases": [],
@ -4799,8 +4799,8 @@
"smoked turkey bacon": {
"aliases": [],
"description": "",
"name": "smoked turkey bacon",
"plural_name": "smoked turkey bacons"
"name": "geräucherter Putenspeck",
"plural_name": "geräucherter Putenspeck"
},
"chicken bacon": {
"aliases": [],
@ -4811,8 +4811,8 @@
"turkey rissole": {
"aliases": [],
"description": "",
"name": "turkey rissole",
"plural_name": "turkey rissoles"
"name": "Puten-Frikadelle",
"plural_name": "Puten-Frikadellen"
},
"chicken kebab": {
"aliases": [],
@ -4847,26 +4847,26 @@
"duck bacon": {
"aliases": [],
"description": "",
"name": "duck bacon",
"plural_name": "duck bacons"
"name": "Entenspeck",
"plural_name": "Entenspeck"
},
"pulled turkey": {
"aliases": [],
"description": "",
"name": "pulled turkey",
"plural_name": "pulled turkeys"
"name": "Pulled Turkey",
"plural_name": "Pulled Turkey"
},
"chicken gyro": {
"aliases": [],
"description": "",
"name": "chicken gyro",
"plural_name": "chicken gyros"
"name": "Hähnchen-Gyros",
"plural_name": "Hähnchen-Gyros"
},
"chicken patty": {
"aliases": [],
"description": "",
"name": "chicken patty",
"plural_name": "chicken patties"
"name": "Hähnchen-Patty",
"plural_name": "Hähnchen-Patties"
},
"chicken rib": {
"aliases": [],
@ -4877,8 +4877,8 @@
"turkey tail": {
"aliases": [],
"description": "",
"name": "turkey tail",
"plural_name": "turkey tails"
"name": "Truthahnschwanz",
"plural_name": "Truthahnschwänze"
},
"chicken milanesa": {
"aliases": [],
@ -5440,7 +5440,7 @@
"aliases": [],
"description": "",
"name": "Echter Bonito",
"plural_name": "Echte Bonito"
"plural_name": "Echte Boniten"
},
"bottarga": {
"aliases": [],
@ -5469,8 +5469,8 @@
"tiny fish": {
"aliases": [],
"description": "",
"name": "tiny fish",
"plural_name": "tiny fish"
"name": "Kleinfisch",
"plural_name": "Kleinfische"
},
"tuna belly": {
"aliases": [],
@ -5497,20 +5497,20 @@
"shrimp": {
"aliases": [],
"description": "",
"name": "Shrimp",
"plural_name": "Shrimps"
"name": "Garnele",
"plural_name": "Garnelen"
},
"octopuse": {
"aliases": [],
"description": "",
"name": "Tintenfische",
"plural_name": "Tintenfische"
"name": "Oktopus",
"plural_name": "Oktopusse"
},
"prawn": {
"aliases": [],
"description": "",
"name": "Garnele",
"plural_name": "Garnelen"
"name": "Riesengarnele",
"plural_name": "Riesengarnelen"
},
"crab": {
"aliases": [],
@ -5575,8 +5575,8 @@
"octopu": {
"aliases": [],
"description": "",
"name": "octopu",
"plural_name": "octopus"
"name": "Oktopus",
"plural_name": "Oktopusse"
},
"kombu": {
"aliases": [],
@ -5587,116 +5587,116 @@
"dried shrimp": {
"aliases": [],
"description": "",
"name": "dried shrimp",
"plural_name": "dried shrimps"
"name": "getrocknete Garnele",
"plural_name": "getrocknete Garnelen"
},
"bay scallop": {
"aliases": [],
"description": "",
"name": "bay scallop",
"plural_name": "bay scallops"
"name": "Karibik-Kammmuschel",
"plural_name": "Karibik-Kammmuscheln"
},
"wakame": {
"aliases": [],
"description": "",
"name": "wakame",
"plural_name": "wakames"
"name": "Wakame",
"plural_name": "Wakame"
},
"soft-shell crab": {
"aliases": [],
"description": "",
"name": "soft-shell crab",
"plural_name": "soft-shell crabs"
"name": "Butterkrebs",
"plural_name": "Butterkrebse"
},
"scampi": {
"aliases": [],
"description": "",
"name": "scampi",
"plural_name": "scampis"
"name": "Scampi",
"plural_name": "Scampi"
},
"king crab": {
"aliases": [],
"description": "",
"name": "king crab",
"plural_name": "king crabs"
"name": "Königskrabbe",
"plural_name": "Königskrabben"
},
"mixed seafood": {
"aliases": [],
"description": "",
"name": "mixed seafood",
"plural_name": "mixed seafoods"
"name": "gemischte Meeresfrüchte",
"plural_name": "gemischte Meeresfrüchte"
},
"baby squid": {
"aliases": [],
"description": "",
"name": "baby squid",
"plural_name": "baby squids"
"name": "Calamaretti",
"plural_name": "Calamaretti"
},
"squid ink": {
"aliases": [],
"description": "",
"name": "squid ink",
"plural_name": "squid inks"
"name": "Sepiatinte",
"plural_name": "Sepiatinten"
},
"dried prawn": {
"aliases": [],
"description": "",
"name": "dried prawn",
"plural_name": "dried prawns"
"name": "getrocknete Garnele",
"plural_name": "getrocknete Garnelen"
},
"dulse seaweed": {
"aliases": [],
"description": "",
"name": "dulse seaweed",
"plural_name": "dulse seaweeds"
"name": "Lappentang",
"plural_name": "Lappentang"
},
"roasted seaweed": {
"aliases": [],
"description": "",
"name": "roasted seaweed",
"plural_name": "roasted seaweeds"
"name": "gerösteter Seetang",
"plural_name": "gerösteter Seetang"
},
"smoked oyster": {
"aliases": [],
"description": "",
"name": "smoked oyster",
"plural_name": "smoked oysters"
"name": "geräucherte Auster",
"plural_name": "geräucherte Austern"
},
"kelp": {
"aliases": [],
"description": "",
"name": "kelp",
"plural_name": "kelps"
"name": "Seetang",
"plural_name": "Seetang"
},
"kizami nori": {
"aliases": [],
"description": "",
"name": "kizami nori",
"plural_name": "kizami noris"
"name": "Kizami Nori",
"plural_name": "Kizami Nori"
},
"hijiki": {
"aliases": [],
"description": "",
"name": "hijiki",
"plural_name": "hijikis"
"name": "Hijiki",
"plural_name": "Hijiki"
},
"salted shrimp": {
"aliases": [],
"description": "",
"name": "salted shrimp",
"plural_name": "salted shrimps"
"name": "gesalzene Garnele",
"plural_name": "gesalzene Garnelen"
},
"yaki-nori": {
"aliases": [],
"description": "",
"name": "yaki-nori",
"plural_name": "yaki-noris"
"name": "Yaki Nori",
"plural_name": "Yaki Nori"
},
"conch": {
"aliases": [],
"description": "",
"name": "conch",
"plural_name": "conches"
"name": "Meeresschnecke",
"plural_name": "Meeresschnecken"
},
"arame": {
"aliases": [],
@ -5707,8 +5707,8 @@
"calamari steak": {
"aliases": [],
"description": "",
"name": "calamari steak",
"plural_name": "calamari steaks"
"name": "Tintenfischtube",
"plural_name": "Tintenfischtuben"
},
"mud crab": {
"aliases": [],
@ -5761,32 +5761,32 @@
"prepared crab cake": {
"aliases": [],
"description": "",
"name": "prepared crab cake",
"plural_name": "prepared crab cakes"
"name": "Fertig-Crab Cake",
"plural_name": "Fertig-Crab Cakes"
},
"sea lettuce": {
"aliases": [],
"description": "",
"name": "sea lettuce",
"plural_name": "sea lettuces"
"name": "Ulva",
"plural_name": "Ulva"
},
"korean seaweed": {
"aliases": [],
"description": "",
"name": "korean seaweed",
"plural_name": "korean seaweeds"
"name": "Gim",
"plural_name": "Gim"
},
"ogo seaweed": {
"aliases": [],
"description": "",
"name": "ogo seaweed",
"plural_name": "ogo seaweeds"
"name": "Hawai-Rotalge",
"plural_name": "Hawai-Rotalgen"
},
"seaweed caviar": {
"aliases": [],
"description": "",
"name": "seaweed caviar",
"plural_name": "seaweed caviars"
"name": "Algen-Kaviar",
"plural_name": "Algen-Kaviar"
},
"haddock": {
"aliases": [],
@ -5933,8 +5933,8 @@
"panch puran": {
"aliases": [],
"description": "",
"name": "panch puran",
"plural_name": "panch purans"
"name": "Panch Phoron",
"plural_name": "Panch Phoron"
},
"dill": {
"aliases": [],
@ -6023,8 +6023,8 @@
"curry leaf": {
"aliases": [],
"description": "",
"name": "curry leaf",
"plural_name": "curry leaves"
"name": "Curryblatt",
"plural_name": "Curryblätter"
},
"fennel seed": {
"aliases": [],
@ -6035,8 +6035,8 @@
"tarragon": {
"aliases": [],
"description": "",
"name": "tarragon",
"plural_name": "tarragons"
"name": "Estragon",
"plural_name": "Estragon"
},
"saffron": {
"aliases": [],
@ -6047,8 +6047,8 @@
"asafoetida": {
"aliases": [],
"description": "",
"name": "asafoetida",
"plural_name": "asafoetidas"
"name": "Asafoetida",
"plural_name": "Asafoetida"
},
"star anise": {
"aliases": [],
@ -6071,8 +6071,8 @@
"caraway": {
"aliases": [],
"description": "",
"name": "caraway",
"plural_name": "caraways"
"name": "Kümmel",
"plural_name": "Kümmel"
},
"garlic granule": {
"aliases": [],
@ -6107,8 +6107,8 @@
"onion flake": {
"aliases": [],
"description": "",
"name": "onion flake",
"plural_name": "onion flakes"
"name": "Zwiebelflocke",
"plural_name": "Zwiebelflocken"
},
"matcha powder": {
"aliases": [],
@ -6173,8 +6173,8 @@
"chervil": {
"aliases": [],
"description": "",
"name": "chervil",
"plural_name": "chervils"
"name": "Kerbel",
"plural_name": "Kerbel"
},
"lavender": {
"aliases": [],
@ -6185,8 +6185,8 @@
"carom seed": {
"aliases": [],
"description": "",
"name": "carom seed",
"plural_name": "carom seeds"
"name": "Ajowan",
"plural_name": "Ajowan"
},
"mexican oregano": {
"aliases": [],
@ -6215,7 +6215,7 @@
"dried chili": {
"aliases": [],
"description": "",
"name": "dried chili",
"name": "Getrocknete Chili",
"plural_name": "dried chilies"
},
"black cardamom": {
@ -6245,8 +6245,8 @@
"hot paprika": {
"aliases": [],
"description": "",
"name": "hot paprika",
"plural_name": "hot paprikas"
"name": "Scharfe Paprika",
"plural_name": "Scharfe Paprikas"
},
"lemon thyme": {
"aliases": [],
@ -6371,14 +6371,14 @@
"vietnamese mint": {
"aliases": [],
"description": "",
"name": "vietnamese mint",
"name": "Vietnamesische Minze",
"plural_name": "vietnamese mints"
},
"dried orange peel": {
"aliases": [],
"description": "",
"name": "dried orange peel",
"plural_name": "dried orange peels"
"name": "Getrocknete Orangenscheiben",
"plural_name": "Getrocknete Orangenscheiben"
},
"espelette pepper": {
"aliases": [],
@ -6737,7 +6737,7 @@
"aliases": [],
"description": "",
"name": "rice syrup",
"plural_name": "rice syrups"
"plural_name": "Zuckerrohr-Sirup"
},
"manuka honey": {
"aliases": [],
@ -6868,7 +6868,7 @@
"mango syrup": {
"aliases": [],
"description": "",
"name": "mango syrup",
"name": "Mango Sirup",
"plural_name": "mango syrups"
},
"malt syrup": {
@ -7000,7 +7000,7 @@
"chocolate sugar": {
"aliases": [],
"description": "",
"name": "chocolate sugar",
"name": "Schokoladenzucker",
"plural_name": "chocolate sugars"
},
"flavored syrup": {
@ -7118,7 +7118,7 @@
"liquid smoke": {
"aliases": [],
"description": "",
"name": "liquid smoke",
"name": "flüssiger Rauch",
"plural_name": "liquid smokes"
},
"poultry seasoning": {
@ -7665,7 +7665,7 @@
"baking powder": {
"aliases": [],
"description": "",
"name": "baking powder",
"name": "Backpulver",
"plural_name": "baking powders"
},
"baking soda": {
@ -7739,7 +7739,7 @@
"gelatin": {
"aliases": [],
"description": "",
"name": "gelatin",
"name": "Gelatine",
"plural_name": "gelatins"
},
"pastry flour": {
@ -8052,8 +8052,8 @@
"cinnamon chip": {
"aliases": [],
"description": "",
"name": "cinnamon chip",
"plural_name": "cinnamon chips"
"name": "Zimt-Backchip",
"plural_name": "Zimt-Backchips"
},
"agar agar": {
"aliases": [],
@ -8070,14 +8070,14 @@
"matzo meal": {
"aliases": [],
"description": "",
"name": "matzo meal",
"plural_name": "matzo meals"
"name": "Matzemehl",
"plural_name": "Matzemehle"
},
"sago": {
"aliases": [],
"description": "",
"name": "sago",
"plural_name": "sagos"
"name": "Sago",
"plural_name": "Sago"
},
"white baking chocolate": {
"aliases": [],
@ -8088,8 +8088,8 @@
"cassava flour": {
"aliases": [],
"description": "",
"name": "cassava flour",
"plural_name": "cassava flours"
"name": "Maniokmehl",
"plural_name": "Maniokmehle"
},
"whipped cream stabilizer": {
"aliases": [],
@ -8106,8 +8106,8 @@
"vital wheat gluten": {
"aliases": [],
"description": "",
"name": "vital wheat gluten",
"plural_name": "vital wheat glutens"
"name": "Vital Weizengluten",
"plural_name": "Vital Weizenglutene"
},
"baking chip": {
"aliases": [],
@ -8118,74 +8118,74 @@
"meringue powder": {
"aliases": [],
"description": "",
"name": "meringue powder",
"plural_name": "meringue powders"
"name": "Baiser-Pulver",
"plural_name": "Baiser-Pulver"
},
"hazelnut flour": {
"aliases": [],
"description": "",
"name": "hazelnut flour",
"plural_name": "hazelnut flours"
"name": "Haselnussmehl",
"plural_name": "Haselnussmehle"
},
"citric acid": {
"aliases": [],
"description": "",
"name": "citric acid",
"plural_name": "citric acids"
"name": "Zitronensäure",
"plural_name": "Zitronensäuren"
},
"coconut chip": {
"aliases": [],
"description": "",
"name": "coconut chip",
"plural_name": "coconut chips"
"name": "Kokoschip",
"plural_name": "Kokoschips"
},
"quinoa flour": {
"aliases": [],
"description": "",
"name": "quinoa flour",
"plural_name": "quinoa flours"
"name": "Quinoamehl",
"plural_name": "Quinoamehle"
},
"finger millet flour": {
"aliases": [],
"description": "",
"name": "finger millet flour",
"plural_name": "finger millet flours"
"name": "Fingerhirsemehl",
"plural_name": "Fingerhirsemehle"
},
"fondant": {
"aliases": [],
"description": "",
"name": "fondant",
"plural_name": "fondants"
"name": "Fondant",
"plural_name": "Fondants"
},
"mint baking chip": {
"aliases": [],
"description": "",
"name": "mint baking chip",
"plural_name": "mint baking chips"
"name": "Minze-Backchip",
"plural_name": "Minze-Backchips"
},
"angel food cake mix": {
"aliases": [],
"description": "",
"name": "angel food cake mix",
"plural_name": "angel food cake mixes"
"name": "Angel Food Cake-Mischung",
"plural_name": "Angel Food Cake-Mischungen"
},
"white cornmeal": {
"aliases": [],
"description": "",
"name": "white cornmeal",
"plural_name": "white cornmeals"
"name": "weißes Maismehl",
"plural_name": "weiße Maismehle"
},
"millet flour": {
"aliases": [],
"description": "",
"name": "millet flour",
"plural_name": "millet flours"
"name": "Hirsemehl",
"plural_name": "Hirsemehle"
},
"mincemeat": {
"aliases": [],
"description": "",
"name": "mincemeat",
"plural_name": "mincemeats"
"name": "Mincemeat",
"plural_name": "Mincemeats"
},
"gluten-free baking flour": {
"aliases": [],
@ -10294,8 +10294,8 @@
"crispy fried onion": {
"aliases": [],
"description": "",
"name": "crispy fried onion",
"plural_name": "crispy fried onions"
"name": "Röstzwiebel",
"plural_name": "Röstzwiebeln"
},
"matzo": {
"aliases": [],
@ -10444,8 +10444,8 @@
"frozen onion ring": {
"aliases": [],
"description": "",
"name": "frozen onion ring",
"plural_name": "frozen onion rings"
"name": "tiefgefrorener Zwiebelring",
"plural_name": "tiefgefrorene Zwiebelringe"
},
"corn muffin": {
"aliases": [],
@ -10528,8 +10528,8 @@
"prawn cracker": {
"aliases": [],
"description": "",
"name": "prawn cracker",
"plural_name": "prawn crackers"
"name": "Krabbenchip",
"plural_name": "Krabbenchips"
},
"bao bun": {
"aliases": [],
@ -11898,8 +11898,8 @@
"onion marmalade": {
"aliases": [],
"description": "",
"name": "onion marmalade",
"plural_name": "onion marmalades"
"name": "Zwiebelkonfitüre",
"plural_name": "Zwiebelkonfitüren"
},
"giardiniera": {
"aliases": [],
@ -12148,8 +12148,8 @@
"canned tuna": {
"aliases": [],
"description": "",
"name": "canned tuna",
"plural_name": "canned tuna"
"name": "Thunfisch in Dosen",
"plural_name": "Thunfisch in Dosen"
},
"pickle": {
"aliases": [],
@ -12916,8 +12916,8 @@
"turkey gravy": {
"aliases": [],
"description": "",
"name": "turkey gravy",
"plural_name": "turkey gravies"
"name": "Truthahn-Bratensauce",
"plural_name": "Truthahn-Bratensaucen"
},
"stir-fry sauce": {
"aliases": [],
@ -13712,8 +13712,8 @@
"turkey bone broth": {
"aliases": [],
"description": "",
"name": "turkey bone broth",
"plural_name": "turkey bone broths"
"name": "Puten-Knochenbrühe",
"plural_name": "Puten-Knochenbrühe"
},
"anchovy stock": {
"aliases": [],
@ -15647,19 +15647,19 @@
"pepsi": {
"aliases": [],
"description": "",
"name": "pepsi",
"plural_name": "pepsis"
"name": "Pepsi",
"plural_name": "Pepsis"
},
"cherry soda": {
"aliases": [],
"description": "",
"name": "cherry soda",
"plural_name": "cherry sodas"
"name": "Kirschlimonade",
"plural_name": "Kirschlimonaden"
},
"peppermint tea": {
"aliases": [],
"description": "",
"name": "peppermint tea",
"name": "Pfefferminztee",
"plural_name": "peppermint teas"
},
"sports drink": {
@ -15729,8 +15729,8 @@
"protein powder": {
"aliases": [],
"description": "",
"name": "protein powder",
"plural_name": "protein powders"
"name": "Proteinpulver",
"plural_name": "Proteinpulver"
},
"lemon extract": {
"aliases": [],
@ -16155,7 +16155,7 @@
"vitamin d": {
"aliases": [],
"description": "",
"name": "vitamin d",
"name": "Vitamin D",
"plural_name": "vitamin ds"
},
"calcium lactate": {
@ -16233,7 +16233,7 @@
"thc": {
"aliases": [],
"description": "",
"name": "thc",
"name": "THC",
"plural_name": "thcs"
},
"berry powder": {
@ -16299,7 +16299,7 @@
"maltodextrin": {
"aliases": [],
"description": "",
"name": "maltodextrin",
"name": "Maltodextrin",
"plural_name": "maltodextrins"
}
}

View file

@ -4,136 +4,136 @@
"garlic": {
"aliases": [],
"description": "",
"name": "garlic",
"plural_name": "garlics"
"name": "ajo",
"plural_name": "ajos"
},
"onion": {
"aliases": [],
"description": "",
"name": "onion",
"plural_name": "onions"
"name": "cebolla",
"plural_name": "cebollas"
},
"bell pepper": {
"aliases": [],
"description": "",
"name": "bell pepper",
"plural_name": "bell peppers"
"name": "morrón",
"plural_name": "morrones"
},
"carrot": {
"aliases": [],
"description": "",
"name": "carrot",
"plural_name": "carrots"
"name": "zanahoria",
"plural_name": "zanahorias"
},
"scallion": {
"aliases": [],
"description": "",
"name": "scallion",
"plural_name": "scallions"
"name": "cebolletas",
"plural_name": "cebolletas"
},
"zucchini": {
"aliases": [],
"description": "",
"name": "zucchini",
"plural_name": "zucchinis"
"name": "calabacín",
"plural_name": "calabacines"
},
"potato": {
"aliases": [],
"description": "",
"name": "potato",
"plural_name": "potatoes"
"name": "papa",
"plural_name": "papas"
},
"red onion": {
"aliases": [],
"description": "",
"name": "red onion",
"plural_name": "red onions"
"name": "cebolla colorada",
"plural_name": "cebollas coloradas"
},
"yellow onion": {
"aliases": [],
"description": "",
"name": "yellow onion",
"plural_name": "yellow onions"
"name": "cebolla amarilla",
"plural_name": "cebollas amarillas"
},
"celery": {
"aliases": [],
"description": "",
"name": "celery",
"plural_name": "celeries"
"name": "apio",
"plural_name": "apios"
},
"jalapeno": {
"aliases": [],
"description": "",
"name": "jalapeno",
"plural_name": "jalapenoes"
"name": "jalapeño",
"plural_name": "jalapeños"
},
"avocado": {
"aliases": [],
"description": "",
"name": "avocado",
"plural_name": "avocados"
"name": "palta",
"plural_name": "paltas"
},
"shallot": {
"aliases": [],
"description": "",
"name": "shallot",
"plural_name": "shallots"
"name": "cebolleta",
"plural_name": "cebolletas"
},
"cherry tomato": {
"aliases": [],
"description": "",
"name": "cherry tomato",
"plural_name": "cherry tomatoes"
"name": "tomate cherry",
"plural_name": "tomates cherry"
},
"cucumber": {
"aliases": [],
"description": "",
"name": "cucumber",
"plural_name": "cucumbers"
"name": "pepino",
"plural_name": "pepinos"
},
"spinach": {
"aliases": [],
"description": "",
"name": "spinach",
"plural_name": "spinaches"
"name": "espinaca",
"plural_name": "espinacas"
},
"sweet corn": {
"aliases": [],
"description": "",
"name": "sweet corn",
"plural_name": "sweet corns"
"name": "maíz dulce",
"plural_name": "maíz dulce"
},
"chile pepper": {
"aliases": [
"capsicum"
"morrones"
],
"description": "",
"name": "chile pepper",
"plural_name": "chile peppers"
"name": "ají picante",
"plural_name": "ajies picantes"
},
"sweet potato": {
"aliases": [],
"description": "",
"name": "sweet potato",
"plural_name": "sweet potatoes"
"name": "boniato",
"plural_name": "boniatos"
},
"broccoli": {
"aliases": [],
"description": "",
"name": "broccoli",
"plural_name": "broccolis"
"name": "brócoli",
"plural_name": "brócolis"
},
"heart of palm": {
"aliases": [],
"description": "",
"name": "heart of palm",
"plural_name": "heart of palms"
"name": "palmito",
"plural_name": "palmitos"
},
"baby green": {
"aliases": [],
"description": "",
"name": "baby green",
"plural_name": "baby greens"
"name": "hoja tierna",
"plural_name": "hojas tiernas"
},
"pumpkin": {
"aliases": [],
@ -285,38 +285,38 @@
"poblano pepper": {
"aliases": [],
"description": "",
"name": "poblano pepper",
"plural_name": "poblano peppers"
"name": "morrón verde",
"plural_name": "morrones verdes"
},
"sweet pepper": {
"aliases": [],
"description": "",
"name": "sweet pepper",
"plural_name": "sweet peppers"
"name": "pimienta dulce",
"plural_name": "pimientas dulces"
},
"serrano pepper": {
"aliases": [],
"description": "",
"name": "serrano pepper",
"plural_name": "serrano peppers"
"name": "chile serrano",
"plural_name": "chiles serranos"
},
"cayenne pepper": {
"aliases": [],
"description": "",
"name": "cayenne pepper",
"plural_name": "cayenne peppers"
"name": "pimienta de cayena",
"plural_name": "pimienta de cayena"
},
"green tomato": {
"aliases": [],
"description": "",
"name": "green tomato",
"plural_name": "green tomatoes"
"name": "tomate verde",
"plural_name": "tomates verdes"
},
"watercress": {
"aliases": [],
"description": "",
"name": "watercress",
"plural_name": "watercress"
"name": "berro",
"plural_name": "berros"
},
"iceberg": {
"aliases": [],
@ -327,38 +327,38 @@
"mashed potato": {
"aliases": [],
"description": "",
"name": "mashed potato",
"plural_name": "mashed potatoes"
"name": "puré de papa",
"plural_name": "puré de papa"
},
"horseradish": {
"aliases": [],
"description": "",
"name": "horseradish",
"plural_name": "horseradishes"
"name": "rabanito",
"plural_name": "rabanitos"
},
"chard": {
"aliases": [],
"description": "",
"name": "chard",
"plural_name": "chards"
"name": "acelga",
"plural_name": "acelgas"
},
"pimiento": {
"aliases": [],
"description": "",
"name": "pimiento",
"plural_name": "pimientoes"
"name": "ají",
"plural_name": "ajíes"
},
"spaghetti squash": {
"aliases": [],
"description": "",
"name": "spaghetti squash",
"plural_name": "spaghetti squashes"
"name": "cabello de ángel",
"plural_name": "cabellos de ángeles"
},
"butter lettuce": {
"aliases": [],
"description": "",
"name": "butter lettuce",
"plural_name": "butter lettuces"
"name": "lechuga de manteca",
"plural_name": "lechuga de manteca"
},
"hash brown": {
"aliases": [],
@ -371,32 +371,32 @@
"chinese leaves"
],
"description": "",
"name": "napa cabbage",
"plural_name": "napa cabbages"
"name": "repollo",
"plural_name": "repollos"
},
"celeriac": {
"aliases": [],
"description": "",
"name": "celeriac",
"plural_name": "celeriacs"
"name": "apio",
"plural_name": "apios"
},
"water chestnut": {
"aliases": [],
"description": "",
"name": "water chestnut",
"plural_name": "water chestnuts"
"name": "castaño de agua",
"plural_name": "castaños de agua"
},
"turnip": {
"aliases": [],
"description": "",
"name": "turnip",
"plural_name": "turnips"
"name": "nabo",
"plural_name": "nabos"
},
"thai chile pepper": {
"aliases": [],
"description": "",
"name": "thai chile pepper",
"plural_name": "thai chile peppers"
"name": "chile ojo de pájaro",
"plural_name": "chiles ojo de pájaro"
},
"bok choy": {
"aliases": [],
@ -407,31 +407,31 @@
"okra": {
"aliases": [],
"description": "",
"name": "okra",
"plural_name": "okra"
"name": "abelmosco",
"plural_name": "abelmosco"
},
"acorn squash": {
"aliases": [],
"description": "",
"name": "acorn squash",
"plural_name": "acorn squashes"
"name": "calabaza bellota",
"plural_name": "calabazas bellota"
},
"corn cob": {
"aliases": [],
"description": "",
"name": "corn cob",
"plural_name": "corn cobs"
"name": "maíz",
"plural_name": "maíces"
},
"radicchio": {
"aliases": [],
"description": "",
"name": "radicchio",
"plural_name": "radicchio"
"name": "repollo colorado",
"plural_name": "repollo colorado"
},
"pearl onion": {
"aliases": [],
"description": "",
"name": "pearl onion",
"name": "cebolla perla",
"plural_name": "pearl onions"
},
"tenderstem broccoli": {
@ -566,55 +566,55 @@
"aliases": [],
"description": "",
"name": "fresno chile",
"plural_name": "fresno chiles"
"plural_name": "chile fresno"
},
"delicata squash": {
"aliases": [],
"description": "",
"name": "delicata squash",
"plural_name": "delicata squashes"
"name": "calabaza delicata",
"plural_name": "calabazas delicata"
},
"frisee": {
"aliases": [],
"description": "",
"name": "frisee",
"plural_name": "frisees"
"name": "lechuga rizada",
"plural_name": "lechuga rizada"
},
"anaheim pepper": {
"aliases": [],
"description": "",
"name": "anaheim pepper",
"plural_name": "anaheim peppers"
"name": "chile anaheim",
"plural_name": "chile anaheim"
},
"cres": {
"aliases": [],
"description": "",
"name": "cres",
"plural_name": "cress"
"name": "brote",
"plural_name": "brotes"
},
"broccoli slaw": {
"aliases": [],
"description": "",
"name": "broccoli slaw",
"plural_name": "broccoli slaws"
"name": "brócoli",
"plural_name": "brócolis"
},
"arbol chile pepper": {
"aliases": [],
"description": "",
"name": "arbol chile pepper",
"plural_name": "arbol chile peppers"
"name": "pimienta de arbol",
"plural_name": "pimienta de arbol"
},
"golden beet": {
"aliases": [],
"description": "",
"name": "golden beet",
"plural_name": "golden beets"
"name": "remolacha dorada",
"plural_name": "remolacha dorada"
},
"pea shoot": {
"aliases": [],
"description": "",
"name": "pea shoot",
"plural_name": "pea shoots"
"name": "brote de guisante",
"plural_name": "brotes de guisante"
},
"alfalfa": {
"aliases": [],
@ -628,27 +628,27 @@
"foods": {
"tomato": {
"aliases": [],
"description": "Yes they are a fruit",
"name": "tomato",
"plural_name": "tomatoes"
"description": "Sí, son una fruta",
"name": "tomate",
"plural_name": "tomates"
},
"lemon": {
"aliases": [],
"description": "",
"name": "lemon",
"plural_name": "lemons"
"name": "limón",
"plural_name": "limones"
},
"lime": {
"aliases": [],
"description": "",
"name": "lime",
"plural_name": "limes"
"name": "lima",
"plural_name": "limas"
},
"apple": {
"aliases": [],
"description": "",
"name": "apple",
"plural_name": "apples"
"name": "manzana",
"plural_name": "manzanas"
},
"banana": {
"aliases": [],
@ -659,62 +659,62 @@
"orange": {
"aliases": [],
"description": "",
"name": "orange",
"plural_name": "oranges"
"name": "naranja",
"plural_name": "naranjas"
},
"raisin": {
"aliases": [],
"description": "",
"name": "raisin",
"plural_name": "raisins"
"name": "pasa",
"plural_name": "pasas"
},
"pineapple": {
"aliases": [],
"description": "",
"name": "pineapple",
"plural_name": "pineapples"
"name": "piña",
"plural_name": "piñas"
},
"mango": {
"aliases": [],
"description": "",
"name": "mango",
"plural_name": "mangoes"
"plural_name": "mangos"
},
"peach": {
"aliases": [],
"description": "",
"name": "peach",
"plural_name": "peaches"
"name": "durazno",
"plural_name": "duraznos"
},
"date": {
"aliases": [],
"description": "",
"name": "date",
"plural_name": "dates"
"name": "fecha",
"plural_name": "fechas"
},
"coconut": {
"aliases": [],
"description": "",
"name": "coconut",
"plural_name": "coconuts"
"name": "coco",
"plural_name": "cocos"
},
"craisin": {
"aliases": [],
"description": "",
"name": "craisin",
"plural_name": "craisins"
"name": "arándano rojo",
"plural_name": "arándanos rojos"
},
"pear": {
"aliases": [],
"description": "",
"name": "pear",
"plural_name": "pears"
"name": "pera",
"plural_name": "peras"
},
"grape": {
"aliases": [],
"description": "",
"name": "grape",
"plural_name": "grapes"
"name": "uva",
"plural_name": "uvas"
},
"pomegranate": {
"aliases": [],
@ -869,128 +869,128 @@
"melon": {
"aliases": [],
"description": "",
"name": "melon",
"plural_name": "melons"
"name": "melón",
"plural_name": "melones"
},
"tangerine": {
"aliases": [],
"description": "",
"name": "tangerine",
"plural_name": "tangerines"
"name": "mandarina",
"plural_name": "mandarinas"
},
"dried mango": {
"aliases": [],
"description": "",
"name": "dried mango",
"plural_name": "dried mangoes"
"name": "mango seco",
"plural_name": "mangos secos"
},
"dried apple": {
"aliases": [],
"description": "",
"name": "dried apple",
"plural_name": "dried apples"
"name": "manzana seca",
"plural_name": "manzanas secas"
},
"quince": {
"aliases": [],
"description": "",
"name": "quince",
"plural_name": "quinces"
"name": "membrillo",
"plural_name": "membrillos"
},
"guava": {
"aliases": [],
"description": "",
"name": "guava",
"plural_name": "guavas"
"name": "guayaba",
"plural_name": "guayabas"
},
"banana chip": {
"aliases": [],
"description": "",
"name": "banana chip",
"plural_name": "banana chips"
"name": "chip de banana",
"plural_name": "chips de banana"
},
"kumquat": {
"aliases": [],
"description": "",
"name": "kumquat",
"plural_name": "kumquats"
"name": "naranjo enano",
"plural_name": "naranjos enanos"
},
"jackfruit": {
"aliases": [],
"description": "",
"name": "jackfruit",
"plural_name": "jackfruits"
"name": "yaca",
"plural_name": "yaca"
},
"dragon fruit": {
"aliases": [],
"description": "",
"name": "dragon fruit",
"plural_name": "dragon fruits"
"name": "fruta del dragón",
"plural_name": "frutas del dragón"
},
"mixed fruit": {
"aliases": [],
"description": "",
"name": "mixed fruit",
"plural_name": "mixed fruits"
"name": "fruta mixta",
"plural_name": "frutas mixtas"
},
"asian pear": {
"aliases": [],
"description": "",
"name": "asian pear",
"plural_name": "asian pears"
"name": "pera asiática",
"plural_name": "peras asiáticas"
},
"lychee": {
"aliases": [],
"description": "",
"name": "lychee",
"plural_name": "lychees"
"name": "lichi",
"plural_name": "lichis"
},
"young coconut": {
"aliases": [],
"description": "",
"name": "young coconut",
"plural_name": "young coconuts"
"name": "coco joven",
"plural_name": "cocos jóvenes"
},
"kaffir lime": {
"aliases": [],
"description": "",
"name": "kaffir lime",
"plural_name": "kaffir limes"
"name": "lima kaffir",
"plural_name": "limas kaffir"
},
"star fruit": {
"aliases": [],
"description": "",
"name": "star fruit",
"plural_name": "star fruits"
"name": "carambola",
"plural_name": "carambolas"
},
"green papaya": {
"aliases": [],
"description": "",
"name": "green papaya",
"plural_name": "green papayas"
"name": "papaya verde",
"plural_name": "papayas verdes"
},
"pomelo": {
"aliases": [],
"description": "",
"name": "pomelo",
"plural_name": "pomeloes"
"plural_name": "pomelos"
},
"chestnut puree": {
"aliases": [],
"description": "",
"name": "chestnut puree",
"plural_name": "chestnut purees"
"name": "puré de castañas",
"plural_name": "puré de castañas"
},
"prickly pear": {
"aliases": [],
"description": "",
"name": "prickly pear",
"plural_name": "prickly pears"
"name": "pera espinosa",
"plural_name": "peras espinosas"
},
"calamansi": {
"aliases": [],
"description": "",
"name": "calamansi",
"plural_name": "calamansis"
"name": "calamondín",
"plural_name": "calamondines"
},
"yuzu": {
"aliases": [],
@ -1007,14 +1007,14 @@
"apple chip": {
"aliases": [],
"description": "",
"name": "apple chip",
"plural_name": "apple chips"
"name": "chip de manzana",
"plural_name": "chips de manzana"
},
"mixed peel": {
"aliases": [],
"description": "",
"name": "mixed peel",
"plural_name": "mixed peels"
"name": "cáscara mixta",
"plural_name": "cáscara mixta"
},
"kokum": {
"aliases": [],
@ -1169,14 +1169,14 @@
"fig leaf": {
"aliases": [],
"description": "",
"name": "fig leaf",
"plural_name": "fig leaves"
"name": "hoja de higuera",
"plural_name": "hojas de higuera"
},
"freeze-dried pineapple": {
"aliases": [],
"description": "",
"name": "freeze-dried pineapple",
"plural_name": "freeze-dried pineapples"
"name": "piña secada por congelación",
"plural_name": "piñas secadas por congelación"
},
"pluot": {
"aliases": [],
@ -1193,26 +1193,26 @@
"hog plum": {
"aliases": [],
"description": "",
"name": "hog plum",
"plural_name": "hog plums"
"name": "ciruela de cerdo",
"plural_name": "ciruelas de cerdo"
},
"bergamot orange": {
"aliases": [],
"description": "",
"name": "bergamot orange",
"plural_name": "bergamot oranges"
"name": "bergamota",
"plural_name": "bergamotas"
},
"luo han guo": {
"aliases": [],
"description": "",
"name": "luo han guo",
"plural_name": "luo han guos"
"name": "fruto del monje",
"plural_name": "frutos del monje"
},
"mamey": {
"aliases": [],
"description": "",
"name": "mamey",
"plural_name": "mameys"
"name": "mamao",
"plural_name": "mamaos"
},
"sapote": {
"aliases": [],
@ -1223,14 +1223,14 @@
"green ume plum": {
"aliases": [],
"description": "",
"name": "green ume plum",
"plural_name": "green ume plums"
"name": "ciruela verde",
"plural_name": "ciruelas verdes"
},
"kiwano": {
"aliases": [],
"description": "",
"name": "kiwano",
"plural_name": "kiwanoes"
"plural_name": "kiwanos"
}
}
},
@ -1239,26 +1239,26 @@
"button mushroom": {
"aliases": [],
"description": "",
"name": "button mushroom",
"plural_name": "button mushrooms"
"name": "champiñón",
"plural_name": "champiñones"
},
"shiitake mushroom": {
"aliases": [],
"description": "",
"name": "shiitake mushroom",
"plural_name": "shiitake mushrooms"
"name": "hongo shiitake",
"plural_name": "hongos shiitake"
},
"portobello mushroom": {
"aliases": [],
"description": "",
"name": "portobello mushroom",
"plural_name": "portobello mushrooms"
"name": "hongo portobello",
"plural_name": "hongos portobello"
},
"wild mushroom": {
"aliases": [],
"description": "",
"name": "wild mushroom",
"plural_name": "wild mushrooms"
"name": "hongos silvestre",
"plural_name": "hongos silvestre"
},
"porcini": {
"aliases": [],
@ -1269,56 +1269,56 @@
"mixed mushroom": {
"aliases": [],
"description": "",
"name": "mixed mushroom",
"plural_name": "mixed mushrooms"
"name": "hongos mixtos",
"plural_name": "hongos mixtos"
},
"oyster mushroom": {
"aliases": [],
"description": "",
"name": "oyster mushroom",
"plural_name": "oyster mushrooms"
"name": "champiñón blanco",
"plural_name": "champiñón blanco"
},
"chestnut mushroom": {
"aliases": [],
"description": "",
"name": "chestnut mushroom",
"plural_name": "chestnut mushrooms"
"name": "champiñón de castaño",
"plural_name": "champiñones de castaño"
},
"enoki mushroom": {
"aliases": [],
"description": "",
"name": "enoki mushroom",
"plural_name": "enoki mushrooms"
"name": "hongo enoki",
"plural_name": "hongos enoki"
},
"black fungu": {
"aliases": [],
"description": "",
"name": "black fungu",
"plural_name": "black fungus"
"name": "hongo negro",
"plural_name": "hongos negros"
},
"black truffle": {
"aliases": [],
"description": "",
"name": "black truffle",
"plural_name": "black truffles"
"name": "trufa negra",
"plural_name": "trufas negras"
},
"morel mushroom": {
"aliases": [],
"description": "",
"name": "morel mushroom",
"plural_name": "morel mushrooms"
"name": "hongo morel",
"plural_name": "hongos morel"
},
"field mushroom": {
"aliases": [],
"description": "",
"name": "field mushroom",
"plural_name": "field mushrooms"
"name": "hongo de campo",
"plural_name": "hongos de campo"
},
"king oyster mushroom": {
"aliases": [],
"description": "",
"name": "king oyster mushroom",
"plural_name": "king oyster mushrooms"
"name": "hongo de ostra rey",
"plural_name": "hongos de ostra rey"
},
"shimeji mushroom": {
"aliases": [],
@ -1477,56 +1477,56 @@
"cherry": {
"aliases": [],
"description": "",
"name": "cherry",
"plural_name": "cherries"
"name": "cereza",
"plural_name": "cerezas"
},
"blackberry": {
"aliases": [],
"description": "",
"name": "blackberry",
"plural_name": "blackberries"
"name": "mora",
"plural_name": "moras"
},
"berry mix": {
"aliases": [],
"description": "",
"name": "berry mix",
"plural_name": "berry mixes"
"name": "mix de baya",
"plural_name": "mix de bayas"
},
"maraschino cherry": {
"aliases": [],
"description": "",
"name": "maraschino cherry",
"plural_name": "maraschino cherries"
"name": "cereza maraschino",
"plural_name": "cerezas maraschino"
},
"dried cherry": {
"aliases": [],
"description": "",
"name": "dried cherry",
"plural_name": "dried cherries"
"name": "cereza seca",
"plural_name": "cerezas secas"
},
"juniper berry": {
"aliases": [],
"description": "",
"name": "juniper berry",
"plural_name": "juniper berries"
"name": "baya de enebro",
"plural_name": "bayas de enebro"
},
"sour cherry": {
"aliases": [],
"description": "",
"name": "sour cherry",
"plural_name": "sour cherries"
"name": "cereza agria",
"plural_name": "cerezas agrias"
},
"goji berry": {
"aliases": [],
"description": "",
"name": "goji berry",
"plural_name": "goji berries"
"name": "baya goji",
"plural_name": "bayas goji"
},
"dried blueberry": {
"aliases": [],
"description": "",
"name": "dried blueberry",
"plural_name": "dried blueberries"
"name": "arándano seco",
"plural_name": "arándanos secos"
},
"freeze-dried strawberry": {
"aliases": [],

View file

@ -1901,8 +1901,8 @@
"candlenut": {
"aliases": [],
"description": "",
"name": "candlenut",
"plural_name": "candlenuts"
"name": "kemirinoot",
"plural_name": "kemirinoten"
},
"peanut brittle": {
"aliases": [],
@ -1919,14 +1919,14 @@
"honey-roasted almond": {
"aliases": [],
"description": "",
"name": "honey-roasted almond",
"plural_name": "honey-roasted almonds"
"name": "geroosterde amandel met honing",
"plural_name": "geroosterde amandels met honing"
},
"toasted nut": {
"aliases": [],
"description": "",
"name": "toasted nut",
"plural_name": "toasted nuts"
"name": "geroosterde noot",
"plural_name": "geroosterde noten"
},
"chironji": {
"aliases": [],
@ -1937,8 +1937,8 @@
"honey-roasted pecan": {
"aliases": [],
"description": "",
"name": "honey-roasted pecan",
"plural_name": "honey-roasted pecans"
"name": "geroosterde pecannoot met honing",
"plural_name": "geroosterde pecannoten met honing"
},
"tigernut": {
"aliases": [],
@ -2088,13 +2088,13 @@
"aliases": [],
"description": "",
"name": "pecorino",
"plural_name": "pecorinoes"
"plural_name": "pecorino's"
},
"gruyere": {
"aliases": [],
"description": "",
"name": "gruyere",
"plural_name": "gruyeres"
"name": "gruyère",
"plural_name": "gruyères"
},
"mascarpone": {
"aliases": [],
@ -2190,7 +2190,7 @@
"aliases": [],
"description": "",
"name": "halloumi",
"plural_name": "halloumis"
"plural_name": "halloumi's"
},
"chevre": {
"aliases": [],
@ -2226,7 +2226,7 @@
"aliases": [],
"description": "",
"name": "burrata",
"plural_name": "burratas"
"plural_name": "burrata's"
},
"havarti": {
"aliases": [],
@ -2243,8 +2243,8 @@
"grana-padano": {
"aliases": [],
"description": "",
"name": "grana-padano",
"plural_name": "grana-padanoes"
"name": "grana padano",
"plural_name": "grana padano's"
},
"muenster": {
"aliases": [],
@ -2328,7 +2328,7 @@
"aliases": [],
"description": "",
"name": "kaaspoeder",
"plural_name": "cheese powders"
"plural_name": "kaaspoeders"
},
"fromage blanc": {
"aliases": [],
@ -2406,7 +2406,7 @@
"aliases": [],
"description": "",
"name": "comté",
"plural_name": "comtés"
"plural_name": "comté's"
},
"graviera": {
"aliases": [],
@ -2424,7 +2424,7 @@
"aliases": [],
"description": "",
"name": "scamorza",
"plural_name": "scamorzas"
"plural_name": "scamorza's"
},
"cambozola": {
"aliases": [],
@ -2613,20 +2613,20 @@
"butter": {
"aliases": [],
"description": "",
"name": "butter",
"plural_name": "butter"
"name": "boter",
"plural_name": "boters"
},
"egg": {
"aliases": [],
"description": "",
"name": "egg",
"plural_name": "eggs"
"name": "ei",
"plural_name": "eieren"
},
"milk": {
"aliases": [],
"description": "",
"name": "milk",
"plural_name": "milks"
"name": "melk",
"plural_name": "melk"
},
"heavy cream": {
"aliases": [],
@ -2637,8 +2637,8 @@
"sour cream": {
"aliases": [],
"description": "",
"name": "sour cream",
"plural_name": "sour creams"
"name": "zure room",
"plural_name": "zure room"
},
"buttermilk": {
"aliases": [],
@ -2649,26 +2649,26 @@
"yogurt": {
"aliases": [],
"description": "",
"name": "yogurt",
"plural_name": "yogurts"
"name": "yoghurt",
"plural_name": "yoghurts"
},
"greek yogurt": {
"aliases": [],
"description": "",
"name": "greek yogurt",
"plural_name": "greek yogurts"
"name": "griekse yoghurt",
"plural_name": "griekse yoghurts"
},
"cream": {
"aliases": [],
"description": "",
"name": "cream",
"plural_name": "creams"
"name": "room",
"plural_name": "room"
},
"whipped cream": {
"aliases": [],
"description": "",
"name": "whipped cream",
"plural_name": "whipped creams"
"name": "slagroom",
"plural_name": "slagroom"
},
"ghee": {
"aliases": [
@ -2687,8 +2687,8 @@
"condensed milk": {
"aliases": [],
"description": "",
"name": "condensed milk",
"plural_name": "condensed milks"
"name": "gecondenseerde melk",
"plural_name": "gecondenseerde melk"
},
"half and half": {
"aliases": [],
@ -2705,8 +2705,8 @@
"ice cream": {
"aliases": [],
"description": "",
"name": "ice cream",
"plural_name": "ice creams"
"name": "roomijs",
"plural_name": "roomijsjes"
},
"margarine": {
"aliases": [],
@ -2717,20 +2717,20 @@
"creme fraiche": {
"aliases": [],
"description": "",
"name": "creme fraiche",
"plural_name": "creme fraiches"
"name": "crème fraîche",
"plural_name": "crème fraîches"
},
"frosting": {
"aliases": [],
"description": "",
"name": "frosting",
"plural_name": "frostings"
"name": "glazuur",
"plural_name": "glazuren"
},
"milk powder": {
"aliases": [],
"description": "",
"name": "milk powder",
"plural_name": "milk powders"
"name": "melkpoeder",
"plural_name": "melkpoeders"
},
"curd": {
"aliases": [],
@ -2765,8 +2765,8 @@
"chocolate frosting": {
"aliases": [],
"description": "",
"name": "chocolate frosting",
"plural_name": "chocolate frostings"
"name": "chocolade glazuur",
"plural_name": "chocolade glazuren"
},
"kefir": {
"aliases": [],
@ -2783,8 +2783,8 @@
"chocolate milk": {
"aliases": [],
"description": "",
"name": "chocolate milk",
"plural_name": "chocolate milks"
"name": "chocolade melk",
"plural_name": "chocolade melk"
},
"liquid egg substitute": {
"aliases": [],
@ -2849,8 +2849,8 @@
"goat milk": {
"aliases": [],
"description": "",
"name": "goat milk",
"plural_name": "goat milks"
"name": "geitenmelk",
"plural_name": "geitenmelk"
},
"cheese curd": {
"aliases": [],
@ -2861,8 +2861,8 @@
"sour milk": {
"aliases": [],
"description": "",
"name": "sour milk",
"plural_name": "sour milks"
"name": "zure melk",
"plural_name": "zure melk"
},
"ganache": {
"aliases": [],
@ -2879,14 +2879,14 @@
"duck egg": {
"aliases": [],
"description": "",
"name": "duck egg",
"plural_name": "duck eggs"
"name": "eendenei",
"plural_name": "eendeneieren"
},
"salted egg": {
"aliases": [],
"description": "",
"name": "salted egg",
"plural_name": "salted eggs"
"name": "gezout ei",
"plural_name": "gezoute eieren"
},
"skyr": {
"aliases": [],
@ -3077,8 +3077,8 @@
"sheep milk": {
"aliases": [],
"description": "",
"name": "sheep milk",
"plural_name": "sheep milks"
"name": "schapenmelk",
"plural_name": "schapenmelk"
},
"starter culture": {
"aliases": [],
@ -3095,8 +3095,8 @@
"ostrich egg": {
"aliases": [],
"description": "",
"name": "ostrich egg",
"plural_name": "ostrich eggs"
"name": "struisvogelei",
"plural_name": "struisvogeleieren"
},
"vanilla milk": {
"aliases": [],
@ -3135,14 +3135,14 @@
"coconut milk": {
"aliases": [],
"description": "",
"name": "coconut milk",
"plural_name": "coconut milks"
"name": "kokosmelk",
"plural_name": "kokosmelk"
},
"almond milk": {
"aliases": [],
"description": "",
"name": "almond milk",
"plural_name": "almond milks"
"name": "amandelmelk",
"plural_name": "amandelmelk"
},
"almond butter": {
"aliases": [],
@ -3177,8 +3177,8 @@
"soy milk": {
"aliases": [],
"description": "",
"name": "soy milk",
"plural_name": "soy milks"
"name": "sojamelk",
"plural_name": "sojamelk"
},
"extra firm tofu": {
"aliases": [],

View file

@ -4,313 +4,313 @@
"garlic": {
"aliases": [],
"description": "",
"name": "garlic",
"plural_name": "garlics"
"name": "чеснок",
"plural_name": "чеснока"
},
"onion": {
"aliases": [],
"description": "",
"name": "onion",
"plural_name": "onions"
"name": "лук",
"plural_name": "лука"
},
"bell pepper": {
"aliases": [],
"description": "",
"name": "bell pepper",
"plural_name": "bell peppers"
"name": "болгарский перец",
"plural_name": "болгарских перца"
},
"carrot": {
"aliases": [],
"description": "",
"name": "carrot",
"plural_name": "carrots"
"name": "морковь",
"plural_name": "моркови"
},
"scallion": {
"aliases": [],
"description": "",
"name": "scallion",
"plural_name": "scallions"
"name": "зелёный лук",
"plural_name": "зелёного лука"
},
"zucchini": {
"aliases": [],
"description": "",
"name": "цукини",
"plural_name": "zucchinis"
"plural_name": "цукини"
},
"potato": {
"aliases": [],
"description": "",
"name": "potato",
"plural_name": "potatoes"
"name": "картофель",
"plural_name": "картофеля"
},
"red onion": {
"aliases": [],
"description": "",
"name": "red onion",
"plural_name": "red onions"
"name": "красный лук",
"plural_name": "красного лука"
},
"yellow onion": {
"aliases": [],
"description": "",
"name": "yellow onion",
"plural_name": "yellow onions"
"name": "жёлтый лук",
"plural_name": "жёлтого лука"
},
"celery": {
"aliases": [],
"description": "",
"name": "celery",
"plural_name": "celeries"
"name": "сельдерей",
"plural_name": "сельдерея"
},
"jalapeno": {
"aliases": [],
"description": "",
"name": "jalapeno",
"plural_name": "jalapenoes"
"name": "халапеньо",
"plural_name": "халапеньо"
},
"avocado": {
"aliases": [],
"description": "",
"name": "avocado",
"plural_name": "avocados"
"name": "авокадо",
"plural_name": "авокадо"
},
"shallot": {
"aliases": [],
"description": "",
"name": "shallot",
"plural_name": "shallots"
"name": "шалот",
"plural_name": "шалот"
},
"cherry tomato": {
"aliases": [],
"description": "",
"name": "cherry tomato",
"plural_name": "cherry tomatoes"
"name": "помидор Черри",
"plural_name": "помидоры Черри"
},
"cucumber": {
"aliases": [],
"description": "",
"name": "cucumber",
"plural_name": "cucumbers"
"name": "огурец",
"plural_name": "огурцы"
},
"spinach": {
"aliases": [],
"description": "",
"name": "spinach",
"plural_name": "spinaches"
"name": "шпинат",
"plural_name": "шпинат"
},
"sweet corn": {
"aliases": [],
"description": "",
"name": "sweet corn",
"plural_name": "sweet corns"
"name": "сладкая кукуруза",
"plural_name": "сладкая кукуруза"
},
"chile pepper": {
"aliases": [
"capsicum"
"стручковый перец"
],
"description": "",
"name": "chile pepper",
"plural_name": "chile peppers"
"name": "перец чили",
"plural_name": "перца чили"
},
"sweet potato": {
"aliases": [],
"description": "",
"name": "sweet potato",
"plural_name": "sweet potatoes"
"name": "батат",
"plural_name": "батат"
},
"broccoli": {
"aliases": [],
"description": "",
"name": "broccoli",
"plural_name": "broccolis"
"name": "брокколи",
"plural_name": "брокколи"
},
"heart of palm": {
"aliases": [],
"description": "",
"name": "heart of palm",
"plural_name": "heart of palms"
"name": "сердце пальмы",
"plural_name": "сердец пальмы"
},
"baby green": {
"aliases": [],
"description": "",
"name": "baby green",
"plural_name": "baby greens"
"name": "молодая зелень",
"plural_name": "молодая зелень"
},
"pumpkin": {
"aliases": [],
"description": "",
"name": "pumpkin",
"plural_name": "pumpkins"
"name": "тыква",
"plural_name": "тыквы"
},
"cauliflower": {
"aliases": [],
"description": "",
"name": "cauliflower",
"plural_name": "cauliflowers"
"name": "цветная капуста",
"plural_name": "цветной капусты"
},
"cabbage": {
"aliases": [],
"description": "",
"name": "cabbage",
"plural_name": "cabbages"
"name": "капуста",
"plural_name": "капуста"
},
"asparagu": {
"aliases": [],
"description": "",
"name": "asparagu",
"plural_name": "asparagus"
"name": "спаржа",
"plural_name": "спаржа"
},
"kale": {
"aliases": [],
"description": "",
"name": "kale",
"plural_name": "kales"
"name": "кудрявая капуста",
"plural_name": "кудрявая капуста"
},
"arugula": {
"aliases": [],
"description": "",
"name": "arugula",
"plural_name": "arugulas"
"name": "руккола",
"plural_name": "руккола"
},
"leek": {
"aliases": [],
"description": "",
"name": "leek",
"plural_name": "leeks"
"name": "лук-порей",
"plural_name": "лук-порей"
},
"eggplant": {
"aliases": [],
"description": "",
"name": "eggplant",
"plural_name": "eggplants"
"name": "баклажан",
"plural_name": "баклажаны"
},
"lettuce": {
"aliases": [],
"description": "",
"name": "lettuce",
"plural_name": "lettuces"
"name": "салат - латук",
"plural_name": "салат - латук"
},
"butternut squash": {
"aliases": [],
"description": "",
"name": "butternut squash",
"plural_name": "butternut squashes"
"name": "мускатная тыква",
"plural_name": "мускатная тыква"
},
"romaine": {
"aliases": [],
"description": "",
"name": "romaine",
"plural_name": "romaines"
"name": "римский салат",
"plural_name": "римский салат"
},
"beetroot": {
"aliases": [],
"description": "",
"name": "beetroot",
"plural_name": "beetroots"
"name": "свёкла",
"plural_name": "свёклы"
},
"brussels sprout": {
"aliases": [],
"description": "",
"name": "brussels sprout",
"plural_name": "brussels sprouts"
"name": "брюссельская капуста",
"plural_name": "брюссельская капуста"
},
"fennel": {
"aliases": [],
"description": "",
"name": "fennel",
"plural_name": "fennels"
"name": "фенхель",
"plural_name": "фенхель"
},
"sun dried tomato": {
"aliases": [],
"description": "",
"name": "sun dried tomato",
"plural_name": "sun dried tomatoes"
"name": "вяленый помидор",
"plural_name": "вяленые помидоры"
},
"radish": {
"aliases": [],
"description": "",
"name": "radish",
"plural_name": "radishes"
"name": "редис",
"plural_name": "редис"
},
"red cabbage": {
"aliases": [],
"description": "",
"name": "red cabbage",
"plural_name": "red cabbages"
"name": "красная капуста",
"plural_name": "красная капуста"
},
"artichoke": {
"aliases": [],
"description": "",
"name": "artichoke",
"plural_name": "artichokes"
"name": "артишок",
"plural_name": "артишоки"
},
"new potato": {
"aliases": [],
"description": "",
"name": "new potato",
"plural_name": "new potatoes"
"name": "молодой картофель",
"plural_name": "молодой картофель"
},
"summer squash": {
"aliases": [
"courgette",
"gem squash"
"кабачок",
"гем-сквош"
],
"description": "",
"name": "summer squash",
"plural_name": "summer squashes"
"name": "молодой кабачок",
"plural_name": "молодой кабачок"
},
"mixed green": {
"aliases": [],
"description": "",
"name": "mixed green",
"plural_name": "mixed greens"
"name": "смешанная зелень",
"plural_name": "смешанная зелень"
},
"parsnip": {
"aliases": [],
"description": "",
"name": "parsnip",
"plural_name": "parsnips"
"name": "пастернак",
"plural_name": "пастернаки"
},
"baby carrot": {
"aliases": [],
"description": "",
"name": "baby carrot",
"plural_name": "baby carrots"
"name": "беби-морковь",
"plural_name": "беби-морковь"
},
"mixed vegetable": {
"aliases": [],
"description": "",
"name": "mixed vegetable",
"plural_name": "mixed vegetables"
"name": "овощная смесь",
"plural_name": "овощная смесь"
},
"poblano pepper": {
"aliases": [],
"description": "",
"name": "poblano pepper",
"plural_name": "poblano peppers"
"name": "перец поблано",
"plural_name": "перец поблано"
},
"sweet pepper": {
"aliases": [],
"description": "",
"name": "sweet pepper",
"plural_name": "sweet peppers"
"name": "сладкий перец",
"plural_name": "сладкие перцы"
},
"serrano pepper": {
"aliases": [],
"description": "",
"name": "serrano pepper",
"plural_name": "serrano peppers"
"name": "перец серрано",
"plural_name": "перец серрано"
},
"cayenne pepper": {
"aliases": [],
"description": "",
"name": "cayenne pepper",
"plural_name": "cayenne peppers"
"name": "кайенский перец",
"plural_name": "кайенский перец"
},
"green tomato": {
"aliases": [],
"description": "",
"name": "green tomato",
"plural_name": "green tomatoes"
"name": "зелёный томат",
"plural_name": "зелёные томаты"
},
"watercress": {
"aliases": [],
@ -321,76 +321,76 @@
"iceberg": {
"aliases": [],
"description": "",
"name": "iceberg",
"plural_name": "icebergs"
"name": "салат айсберг",
"plural_name": "салат айсберг"
},
"mashed potato": {
"aliases": [],
"description": "",
"name": "mashed potato",
"plural_name": "mashed potatoes"
"name": "картофельное пюре",
"plural_name": "картофельное пюре"
},
"horseradish": {
"aliases": [],
"description": "",
"name": "horseradish",
"plural_name": "horseradishes"
"name": "хрен",
"plural_name": "хрен"
},
"chard": {
"aliases": [],
"description": "",
"name": "chard",
"plural_name": "chards"
"name": "мангольд",
"plural_name": "мангольд"
},
"pimiento": {
"aliases": [],
"description": "",
"name": "pimiento",
"plural_name": "pimientoes"
"name": "пимиенто",
"plural_name": "пимиенто"
},
"spaghetti squash": {
"aliases": [],
"description": "",
"name": "spaghetti squash",
"plural_name": "spaghetti squashes"
"name": "тыква-спагетти",
"plural_name": "тыква-спагетти"
},
"butter lettuce": {
"aliases": [],
"description": "",
"name": "butter lettuce",
"plural_name": "butter lettuces"
"name": "баттерхед",
"plural_name": "баттерхед"
},
"hash brown": {
"aliases": [],
"description": "",
"name": "hash brown",
"plural_name": "hash browns"
"name": "хашбраун",
"plural_name": "хашбраун"
},
"napa cabbage": {
"aliases": [
"chinese leaves"
"китайские листья"
],
"description": "",
"name": "napa cabbage",
"plural_name": "napa cabbages"
"name": "пекинская капуста",
"plural_name": "пекинская капуста"
},
"celeriac": {
"aliases": [],
"description": "",
"name": "celeriac",
"plural_name": "celeriacs"
"name": "корень сельдерея",
"plural_name": "корень сельдерея"
},
"water chestnut": {
"aliases": [],
"description": "",
"name": "water chestnut",
"plural_name": "water chestnuts"
"name": "болотница сладкая",
"plural_name": "болотница сладкая"
},
"turnip": {
"aliases": [],
"description": "",
"name": "turnip",
"plural_name": "turnips"
"name": "репа",
"plural_name": "репа"
},
"thai chile pepper": {
"aliases": [],
@ -450,153 +450,153 @@
"aliases": [],
"description": "",
"name": "leaf lettuce",
"plural_name": "leaf lettuces"
"plural_name": "листовой салат"
},
"pepperoncini": {
"aliases": [],
"description": "",
"name": "pepperoncini",
"plural_name": "pepperoncinis"
"name": "пеперончини",
"plural_name": "пеперончини"
},
"baby bok choy": {
"aliases": [],
"description": "",
"name": "baby bok choy",
"plural_name": "baby bok choys"
"name": "молодой бок‑чой",
"plural_name": "молодой бок‑чой"
},
"jicama": {
"aliases": [],
"description": "",
"name": "jicama",
"plural_name": "jicamas"
"name": "хикама",
"plural_name": "хикама"
},
"endive": {
"aliases": [],
"description": "",
"name": "endive",
"plural_name": "endives"
"name": "эндивий(цикорий-салатный)",
"plural_name": "эндивий(цикорий-салатный)"
},
"habanero pepper": {
"aliases": [],
"description": "",
"name": "habanero pepper",
"plural_name": "habanero peppers"
"name": "перец хабанеро",
"plural_name": "перец хабанеро"
},
"corn husk": {
"aliases": [
"maize"
"кукуруза"
],
"description": "",
"name": "corn husk",
"plural_name": "corn husks"
"name": "кукурузная шелуха",
"plural_name": "кукурузная шелуха"
},
"collard green": {
"aliases": [],
"description": "",
"name": "collard green",
"plural_name": "collard greens"
"name": "листовая капуста",
"plural_name": "листовая капуста"
},
"french-fried onion": {
"aliases": [],
"description": "",
"name": "french-fried onion",
"plural_name": "french-fried onions"
"name": "хрустящий жареный лук",
"plural_name": "хрустящий жареный лук"
},
"daikon": {
"aliases": [],
"description": "",
"name": "daikon",
"plural_name": "daikons"
"name": "дайкон",
"plural_name": "дайкон"
},
"baby corn": {
"aliases": [],
"description": "",
"name": "baby corn",
"plural_name": "baby corns"
"name": "молодая кукуруза",
"plural_name": "молодая кукуруза"
},
"broccoli rabe": {
"aliases": [],
"description": "",
"name": "broccoli rabe",
"plural_name": "broccoli rabes"
"name": "рапини",
"plural_name": "рапини"
},
"rutabaga": {
"aliases": [],
"description": "",
"name": "rutabaga",
"plural_name": "rutabagas"
"name": "брюква",
"plural_name": "брюква"
},
"belgian endive": {
"aliases": [],
"description": "",
"name": "belgian endive",
"plural_name": "belgian endives"
"name": "витлуф",
"plural_name": "витлуф"
},
"yam": {
"aliases": [],
"description": "",
"name": "yam",
"plural_name": "yams"
"name": "ямс",
"plural_name": "ямс"
},
"ancho chile pepper": {
"aliases": [],
"description": "",
"name": "ancho chile pepper",
"plural_name": "ancho chile peppers"
"name": "перец анчо",
"plural_name": "перец анчо"
},
"microgreen": {
"aliases": [],
"description": "",
"name": "microgreen",
"plural_name": "microgreens"
"name": "микрозелень",
"plural_name": "микрозелень"
},
"boston lettuce": {
"aliases": [],
"description": "",
"name": "boston lettuce",
"plural_name": "boston lettuces"
"name": "салат Бостон",
"plural_name": "салат Бостон"
},
"kohlrabi": {
"aliases": [],
"description": "",
"name": "kohlrabi",
"plural_name": "kohlrabis"
"name": "кольраби",
"plural_name": "кольраби"
},
"fresno chile": {
"aliases": [],
"description": "",
"name": "fresno chile",
"plural_name": "fresno chiles"
"name": "чили Фресно",
"plural_name": "чили Фресно"
},
"delicata squash": {
"aliases": [],
"description": "",
"name": "delicata squash",
"plural_name": "delicata squashes"
"name": "деликатная тыква",
"plural_name": "деликатная тыква"
},
"frisee": {
"aliases": [],
"description": "",
"name": "frisee",
"plural_name": "frisees"
"name": "фрисе",
"plural_name": "фрисе"
},
"anaheim pepper": {
"aliases": [],
"description": "",
"name": "anaheim pepper",
"plural_name": "anaheim peppers"
"name": "перец анахайм",
"plural_name": "перец анахайм"
},
"cres": {
"aliases": [],
"description": "",
"name": "cres",
"plural_name": "cress"
"name": "кресс-салат",
"plural_name": "кресс-салат"
},
"broccoli slaw": {
"aliases": [],
"description": "",
"name": "broccoli slaw",
"plural_name": "broccoli slaws"
"name": "брокколи слоу",
"plural_name": "брокколи слоу"
},
"arbol chile pepper": {
"aliases": [],
@ -750,156 +750,156 @@
"aliases": [],
"description": "",
"name": "grapefruit",
"plural_name": "grapefruits"
"plural_name": "грейпфрут"
},
"plum": {
"aliases": [],
"description": "",
"name": "plum",
"plural_name": "plums"
"name": "слива",
"plural_name": "сливы"
},
"fig": {
"aliases": [],
"description": "",
"name": "fig",
"plural_name": "figs"
"name": "инжир",
"plural_name": "инжир"
},
"apricot": {
"aliases": [],
"description": "",
"name": "apricot",
"plural_name": "apricots"
"name": "абрикос",
"plural_name": "абрикосы"
},
"currant": {
"aliases": [],
"description": "",
"name": "currant",
"plural_name": "currants"
"name": "смородина",
"plural_name": "смородина"
},
"mandarin": {
"aliases": [],
"description": "",
"name": "mandarin",
"plural_name": "mandarins"
"name": "мандарин",
"plural_name": "мандарины"
},
"prune": {
"aliases": [],
"description": "",
"name": "prune",
"plural_name": "prunes"
"name": "чернослив",
"plural_name": "чернослив"
},
"cantaloupe": {
"aliases": [],
"description": "",
"name": "cantaloupe",
"plural_name": "cantaloupes"
"name": "канталупа",
"plural_name": "канталупа"
},
"sultana": {
"aliases": [],
"description": "",
"name": "sultana",
"plural_name": "sultanas"
"name": "кишмиш Султанина",
"plural_name": "кишмиш Султанина"
},
"passion fruit": {
"aliases": [],
"description": "",
"name": "passion fruit",
"plural_name": "passion fruits"
"name": "маракуйя",
"plural_name": "маракуйя"
},
"papaya": {
"aliases": [],
"description": "",
"name": "papaya",
"plural_name": "papayas"
"name": "папайя",
"plural_name": "папайя"
},
"tamarind": {
"aliases": [],
"description": "",
"name": "tamarind",
"plural_name": "tamarinds"
"name": "тамаринд",
"plural_name": "тамаринд"
},
"nectarine": {
"aliases": [],
"description": "",
"name": "nectarine",
"plural_name": "nectarines"
"name": "нектарин",
"plural_name": "нектарины"
},
"dried fig": {
"aliases": [],
"description": "",
"name": "dried fig",
"plural_name": "dried figs"
"name": "сушёный инжир",
"plural_name": "сушёный инжир"
},
"chestnut": {
"aliases": [],
"description": "",
"name": "chestnut",
"plural_name": "chestnuts"
"name": "каштан",
"plural_name": "каштаны"
},
"meyer lemon": {
"aliases": [],
"description": "",
"name": "meyer lemon",
"plural_name": "meyer lemons"
"name": "мейер лимон",
"plural_name": "мейер лимоны"
},
"honeydew melon": {
"aliases": [],
"description": "",
"name": "honeydew melon",
"plural_name": "honeydew melons"
"name": "медовая дыня",
"plural_name": "медовые дыни"
},
"dried fruit": {
"aliases": [],
"description": "",
"name": "dried fruit",
"plural_name": "dried fruits"
"name": "сухофрукт",
"plural_name": "сухофрукты"
},
"clementine": {
"aliases": [],
"description": "",
"name": "clementine",
"plural_name": "clementines"
"name": "клементин",
"plural_name": "клементин"
},
"persimmon": {
"aliases": [],
"description": "",
"name": "persimmon",
"plural_name": "persimmons"
"name": "хурма персимон",
"plural_name": "хурма персимон"
},
"melon": {
"aliases": [],
"description": "",
"name": "melon",
"plural_name": "melons"
"name": "дыня",
"plural_name": "дыни"
},
"tangerine": {
"aliases": [],
"description": "",
"name": "tangerine",
"plural_name": "tangerines"
"name": "танжерин",
"plural_name": "танжерины"
},
"dried mango": {
"aliases": [],
"description": "",
"name": "dried mango",
"plural_name": "dried mangoes"
"name": "сушёное манго",
"plural_name": "сушёное манго"
},
"dried apple": {
"aliases": [],
"description": "",
"name": "dried apple",
"plural_name": "dried apples"
"name": "сушёное яблоко",
"plural_name": "сушёные яблоки"
},
"quince": {
"aliases": [],
"description": "",
"name": "quince",
"plural_name": "quinces"
"name": "айва",
"plural_name": "айва"
},
"guava": {
"aliases": [],
"description": "",
"name": "guava",
"name": "гуава",
"plural_name": "guavas"
},
"banana chip": {

View file

@ -1,6 +1,8 @@
import html
import json
import pathlib
from dataclasses import dataclass
from typing import Any
from bs4 import BeautifulSoup
from fastapi import Depends, FastAPI, Response
@ -24,6 +26,9 @@ class MetaTag:
property_name: str
content: str
def __post_init__(self):
self.content = escape(self.content) # escape HTML to prevent XSS attacks
class SPAStaticFiles(StaticFiles):
async def get_response(self, path: str, scope):
@ -42,6 +47,17 @@ __app_settings = get_app_settings()
__contents = ""
def escape(content: Any) -> Any:
if isinstance(content, str):
return html.escape(content)
elif isinstance(content, list | tuple | set):
return [escape(item) for item in content]
elif isinstance(content, dict):
return {escape(k): escape(v) for k, v in content.items()}
else:
return content
def inject_meta(contents: str, tags: list[MetaTag]) -> str:
soup = BeautifulSoup(contents, "lxml")
scraped_meta_tags = soup.find_all("meta")
@ -80,15 +96,13 @@ def content_with_meta(group_slug: str, recipe: Recipe) -> str:
# Inject meta tags
recipe_url = f"{__app_settings.BASE_URL}/g/{group_slug}/r/{recipe.slug}"
if recipe.image:
image_url = (
f"{__app_settings.BASE_URL}/api/media/recipes/{recipe.id}/images/original.webp?version={recipe.image}"
)
image_url = f"{__app_settings.BASE_URL}/api/media/recipes/{recipe.id}/images/original.webp?version={escape(recipe.image)}"
else:
image_url = "https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/icons/android-chrome-512x512.png"
ingredients: list[str] = []
if recipe.settings.disable_amount: # type: ignore
ingredients = [i.note for i in recipe.recipe_ingredient if i.note]
ingredients = [escape(i.note) for i in recipe.recipe_ingredient if i.note]
else:
for ing in recipe.recipe_ingredient:
@ -102,25 +116,30 @@ def content_with_meta(group_slug: str, recipe: Recipe) -> str:
if ing.note:
s += f"{ing.note}"
ingredients.append(s)
ingredients.append(escape(s))
nutrition: dict[str, str | None] = recipe.nutrition.model_dump(by_alias=True) if recipe.nutrition else {}
for k, v in nutrition.items():
if v:
nutrition[k] = escape(v)
as_schema_org = {
as_schema_org: dict[str, Any] = {
"@context": "https://schema.org",
"@type": "Recipe",
"name": recipe.name,
"description": recipe.description,
"name": escape(recipe.name),
"description": escape(recipe.description),
"image": [image_url],
"datePublished": recipe.created_at,
"prepTime": recipe.prep_time,
"cookTime": recipe.cook_time,
"totalTime": recipe.total_time,
"recipeYield": recipe.recipe_yield_display,
"prepTime": escape(recipe.prep_time),
"cookTime": escape(recipe.cook_time),
"totalTime": escape(recipe.total_time),
"recipeYield": escape(recipe.recipe_yield_display),
"recipeIngredient": ingredients,
"recipeInstructions": [i.text for i in recipe.recipe_instructions] if recipe.recipe_instructions else [],
"recipeCategory": [c.name for c in recipe.recipe_category] if recipe.recipe_category else [],
"keywords": [t.name for t in recipe.tags] if recipe.tags else [],
"recipeInstructions": [escape(i.text) for i in recipe.recipe_instructions]
if recipe.recipe_instructions
else [],
"recipeCategory": [escape(c.name) for c in recipe.recipe_category] if recipe.recipe_category else [],
"keywords": [escape(t.name) for t in recipe.tags] if recipe.tags else [],
"nutrition": nutrition,
}

387
poetry.lock generated
View file

@ -14,14 +14,14 @@ files = [
[[package]]
name = "alembic"
version = "1.16.2"
version = "1.16.4"
description = "A database migration tool for SQLAlchemy."
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "alembic-1.16.2-py3-none-any.whl", hash = "sha256:5f42e9bd0afdbd1d5e3ad856c01754530367debdebf21ed6894e34af52b3bb03"},
{file = "alembic-1.16.2.tar.gz", hash = "sha256:e53c38ff88dadb92eb22f8b150708367db731d58ad7e9d417c9168ab516cbed8"},
{file = "alembic-1.16.4-py3-none-any.whl", hash = "sha256:b05e51e8e82efc1abd14ba2af6392897e145930c3e0a2faf2b0da2f7f7fd660d"},
{file = "alembic-1.16.4.tar.gz", hash = "sha256:efab6ada0dd0fae2c92060800e0bf5c1dc26af15a10e02fb4babff164b4725e2"},
]
[package.dependencies]
@ -126,14 +126,14 @@ files = [
[[package]]
name = "authlib"
version = "1.6.0"
version = "1.6.1"
description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients."
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "authlib-1.6.0-py2.py3-none-any.whl", hash = "sha256:91685589498f79e8655e8a8947431ad6288831d643f11c55c2143ffcc738048d"},
{file = "authlib-1.6.0.tar.gz", hash = "sha256:4367d32031b7af175ad3a323d571dc7257b7099d55978087ceae4a0d88cd3210"},
{file = "authlib-1.6.1-py2.py3-none-any.whl", hash = "sha256:e9d2031c34c6309373ab845afc24168fe9e93dc52d252631f52642f21f5ed06e"},
{file = "authlib-1.6.1.tar.gz", hash = "sha256:4dffdbb1460ba6ec8c17981a4c67af7d8af131231b5a36a88a1e8c80c111cdfd"},
]
[package.dependencies]
@ -478,79 +478,79 @@ markers = {main = "platform_system == \"Windows\" or sys_platform == \"win32\""}
[[package]]
name = "coverage"
version = "7.9.1"
version = "7.9.2"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "coverage-7.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc94d7c5e8423920787c33d811c0be67b7be83c705f001f7180c7b186dcf10ca"},
{file = "coverage-7.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16aa0830d0c08a2c40c264cef801db8bc4fc0e1892782e45bcacbd5889270509"},
{file = "coverage-7.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf95981b126f23db63e9dbe4cf65bd71f9a6305696fa5e2262693bc4e2183f5b"},
{file = "coverage-7.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f05031cf21699785cd47cb7485f67df619e7bcdae38e0fde40d23d3d0210d3c3"},
{file = "coverage-7.9.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb4fbcab8764dc072cb651a4bcda4d11fb5658a1d8d68842a862a6610bd8cfa3"},
{file = "coverage-7.9.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0f16649a7330ec307942ed27d06ee7e7a38417144620bb3d6e9a18ded8a2d3e5"},
{file = "coverage-7.9.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cea0a27a89e6432705fffc178064503508e3c0184b4f061700e771a09de58187"},
{file = "coverage-7.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e980b53a959fa53b6f05343afbd1e6f44a23ed6c23c4b4c56c6662bbb40c82ce"},
{file = "coverage-7.9.1-cp310-cp310-win32.whl", hash = "sha256:70760b4c5560be6ca70d11f8988ee6542b003f982b32f83d5ac0b72476607b70"},
{file = "coverage-7.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:a66e8f628b71f78c0e0342003d53b53101ba4e00ea8dabb799d9dba0abbbcebe"},
{file = "coverage-7.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95c765060e65c692da2d2f51a9499c5e9f5cf5453aeaf1420e3fc847cc060582"},
{file = "coverage-7.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba383dc6afd5ec5b7a0d0c23d38895db0e15bcba7fb0fa8901f245267ac30d86"},
{file = "coverage-7.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37ae0383f13cbdcf1e5e7014489b0d71cc0106458878ccde52e8a12ced4298ed"},
{file = "coverage-7.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69aa417a030bf11ec46149636314c24c8d60fadb12fc0ee8f10fda0d918c879d"},
{file = "coverage-7.9.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a4be2a28656afe279b34d4f91c3e26eccf2f85500d4a4ff0b1f8b54bf807338"},
{file = "coverage-7.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:382e7ddd5289f140259b610e5f5c58f713d025cb2f66d0eb17e68d0a94278875"},
{file = "coverage-7.9.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e5532482344186c543c37bfad0ee6069e8ae4fc38d073b8bc836fc8f03c9e250"},
{file = "coverage-7.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a39d18b3f50cc121d0ce3838d32d58bd1d15dab89c910358ebefc3665712256c"},
{file = "coverage-7.9.1-cp311-cp311-win32.whl", hash = "sha256:dd24bd8d77c98557880def750782df77ab2b6885a18483dc8588792247174b32"},
{file = "coverage-7.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:6b55ad10a35a21b8015eabddc9ba31eb590f54adc9cd39bcf09ff5349fd52125"},
{file = "coverage-7.9.1-cp311-cp311-win_arm64.whl", hash = "sha256:6ad935f0016be24c0e97fc8c40c465f9c4b85cbbe6eac48934c0dc4d2568321e"},
{file = "coverage-7.9.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8de12b4b87c20de895f10567639c0797b621b22897b0af3ce4b4e204a743626"},
{file = "coverage-7.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5add197315a054e92cee1b5f686a2bcba60c4c3e66ee3de77ace6c867bdee7cb"},
{file = "coverage-7.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:600a1d4106fe66f41e5d0136dfbc68fe7200a5cbe85610ddf094f8f22e1b0300"},
{file = "coverage-7.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a876e4c3e5a2a1715a6608906aa5a2e0475b9c0f68343c2ada98110512ab1d8"},
{file = "coverage-7.9.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81f34346dd63010453922c8e628a52ea2d2ccd73cb2487f7700ac531b247c8a5"},
{file = "coverage-7.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:888f8eee13f2377ce86d44f338968eedec3291876b0b8a7289247ba52cb984cd"},
{file = "coverage-7.9.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9969ef1e69b8c8e1e70d591f91bbc37fc9a3621e447525d1602801a24ceda898"},
{file = "coverage-7.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:60c458224331ee3f1a5b472773e4a085cc27a86a0b48205409d364272d67140d"},
{file = "coverage-7.9.1-cp312-cp312-win32.whl", hash = "sha256:5f646a99a8c2b3ff4c6a6e081f78fad0dde275cd59f8f49dc4eab2e394332e74"},
{file = "coverage-7.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:30f445f85c353090b83e552dcbbdad3ec84c7967e108c3ae54556ca69955563e"},
{file = "coverage-7.9.1-cp312-cp312-win_arm64.whl", hash = "sha256:af41da5dca398d3474129c58cb2b106a5d93bbb196be0d307ac82311ca234342"},
{file = "coverage-7.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:31324f18d5969feef7344a932c32428a2d1a3e50b15a6404e97cba1cc9b2c631"},
{file = "coverage-7.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0c804506d624e8a20fb3108764c52e0eef664e29d21692afa375e0dd98dc384f"},
{file = "coverage-7.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef64c27bc40189f36fcc50c3fb8f16ccda73b6a0b80d9bd6e6ce4cffcd810bbd"},
{file = "coverage-7.9.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4fe2348cc6ec372e25adec0219ee2334a68d2f5222e0cba9c0d613394e12d86"},
{file = "coverage-7.9.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34ed2186fe52fcc24d4561041979a0dec69adae7bce2ae8d1c49eace13e55c43"},
{file = "coverage-7.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:25308bd3d00d5eedd5ae7d4357161f4df743e3c0240fa773ee1b0f75e6c7c0f1"},
{file = "coverage-7.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73e9439310f65d55a5a1e0564b48e34f5369bee943d72c88378f2d576f5a5751"},
{file = "coverage-7.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37ab6be0859141b53aa89412a82454b482c81cf750de4f29223d52268a86de67"},
{file = "coverage-7.9.1-cp313-cp313-win32.whl", hash = "sha256:64bdd969456e2d02a8b08aa047a92d269c7ac1f47e0c977675d550c9a0863643"},
{file = "coverage-7.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:be9e3f68ca9edb897c2184ad0eee815c635565dbe7a0e7e814dc1f7cbab92c0a"},
{file = "coverage-7.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:1c503289ffef1d5105d91bbb4d62cbe4b14bec4d13ca225f9c73cde9bb46207d"},
{file = "coverage-7.9.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0b3496922cb5f4215bf5caaef4cf12364a26b0be82e9ed6d050f3352cf2d7ef0"},
{file = "coverage-7.9.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9565c3ab1c93310569ec0d86b017f128f027cab0b622b7af288696d7ed43a16d"},
{file = "coverage-7.9.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2241ad5dbf79ae1d9c08fe52b36d03ca122fb9ac6bca0f34439e99f8327ac89f"},
{file = "coverage-7.9.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bb5838701ca68b10ebc0937dbd0eb81974bac54447c55cd58dea5bca8451029"},
{file = "coverage-7.9.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a25f814591a8c0c5372c11ac8967f669b97444c47fd794926e175c4047ece"},
{file = "coverage-7.9.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2d04b16a6062516df97969f1ae7efd0de9c31eb6ebdceaa0d213b21c0ca1a683"},
{file = "coverage-7.9.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7931b9e249edefb07cd6ae10c702788546341d5fe44db5b6108a25da4dca513f"},
{file = "coverage-7.9.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52e92b01041151bf607ee858e5a56c62d4b70f4dac85b8c8cb7fb8a351ab2c10"},
{file = "coverage-7.9.1-cp313-cp313t-win32.whl", hash = "sha256:684e2110ed84fd1ca5f40e89aa44adf1729dc85444004111aa01866507adf363"},
{file = "coverage-7.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:437c576979e4db840539674e68c84b3cda82bc824dd138d56bead1435f1cb5d7"},
{file = "coverage-7.9.1-cp313-cp313t-win_arm64.whl", hash = "sha256:18a0912944d70aaf5f399e350445738a1a20b50fbea788f640751c2ed9208b6c"},
{file = "coverage-7.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f424507f57878e424d9a95dc4ead3fbdd72fd201e404e861e465f28ea469951"},
{file = "coverage-7.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:535fde4001b2783ac80865d90e7cc7798b6b126f4cd8a8c54acfe76804e54e58"},
{file = "coverage-7.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02532fd3290bb8fa6bec876520842428e2a6ed6c27014eca81b031c2d30e3f71"},
{file = "coverage-7.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56f5eb308b17bca3bbff810f55ee26d51926d9f89ba92707ee41d3c061257e55"},
{file = "coverage-7.9.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfa447506c1a52271f1b0de3f42ea0fa14676052549095e378d5bff1c505ff7b"},
{file = "coverage-7.9.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9ca8e220006966b4a7b68e8984a6aee645a0384b0769e829ba60281fe61ec4f7"},
{file = "coverage-7.9.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:49f1d0788ba5b7ba65933f3a18864117c6506619f5ca80326b478f72acf3f385"},
{file = "coverage-7.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:68cd53aec6f45b8e4724c0950ce86eacb775c6be01ce6e3669fe4f3a21e768ed"},
{file = "coverage-7.9.1-cp39-cp39-win32.whl", hash = "sha256:95335095b6c7b1cc14c3f3f17d5452ce677e8490d101698562b2ffcacc304c8d"},
{file = "coverage-7.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:e1b5191d1648acc439b24721caab2fd0c86679d8549ed2c84d5a7ec1bedcc244"},
{file = "coverage-7.9.1-pp39.pp310.pp311-none-any.whl", hash = "sha256:db0f04118d1db74db6c9e1cb1898532c7dcc220f1d2718f058601f7c3f499514"},
{file = "coverage-7.9.1-py3-none-any.whl", hash = "sha256:66b974b145aa189516b6bf2d8423e888b742517d37872f6ee4c5be0073bd9a3c"},
{file = "coverage-7.9.1.tar.gz", hash = "sha256:6cf43c78c4282708a28e466316935ec7489a9c487518a77fa68f716c67909cec"},
{file = "coverage-7.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:66283a192a14a3854b2e7f3418d7db05cdf411012ab7ff5db98ff3b181e1f912"},
{file = "coverage-7.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4e01d138540ef34fcf35c1aa24d06c3de2a4cffa349e29a10056544f35cca15f"},
{file = "coverage-7.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f22627c1fe2745ee98d3ab87679ca73a97e75ca75eb5faee48660d060875465f"},
{file = "coverage-7.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b1c2d8363247b46bd51f393f86c94096e64a1cf6906803fa8d5a9d03784bdbf"},
{file = "coverage-7.9.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c10c882b114faf82dbd33e876d0cbd5e1d1ebc0d2a74ceef642c6152f3f4d547"},
{file = "coverage-7.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:de3c0378bdf7066c3988d66cd5232d161e933b87103b014ab1b0b4676098fa45"},
{file = "coverage-7.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1e2f097eae0e5991e7623958a24ced3282676c93c013dde41399ff63e230fcf2"},
{file = "coverage-7.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28dc1f67e83a14e7079b6cea4d314bc8b24d1aed42d3582ff89c0295f09b181e"},
{file = "coverage-7.9.2-cp310-cp310-win32.whl", hash = "sha256:bf7d773da6af9e10dbddacbf4e5cab13d06d0ed93561d44dae0188a42c65be7e"},
{file = "coverage-7.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:0c0378ba787681ab1897f7c89b415bd56b0b2d9a47e5a3d8dc0ea55aac118d6c"},
{file = "coverage-7.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a7a56a2964a9687b6aba5b5ced6971af308ef6f79a91043c05dd4ee3ebc3e9ba"},
{file = "coverage-7.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:123d589f32c11d9be7fe2e66d823a236fe759b0096f5db3fb1b75b2fa414a4fa"},
{file = "coverage-7.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:333b2e0ca576a7dbd66e85ab402e35c03b0b22f525eed82681c4b866e2e2653a"},
{file = "coverage-7.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:326802760da234baf9f2f85a39e4a4b5861b94f6c8d95251f699e4f73b1835dc"},
{file = "coverage-7.9.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19e7be4cfec248df38ce40968c95d3952fbffd57b400d4b9bb580f28179556d2"},
{file = "coverage-7.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0b4a4cb73b9f2b891c1788711408ef9707666501ba23684387277ededab1097c"},
{file = "coverage-7.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2c8937fa16c8c9fbbd9f118588756e7bcdc7e16a470766a9aef912dd3f117dbd"},
{file = "coverage-7.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:42da2280c4d30c57a9b578bafd1d4494fa6c056d4c419d9689e66d775539be74"},
{file = "coverage-7.9.2-cp311-cp311-win32.whl", hash = "sha256:14fa8d3da147f5fdf9d298cacc18791818f3f1a9f542c8958b80c228320e90c6"},
{file = "coverage-7.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:549cab4892fc82004f9739963163fd3aac7a7b0df430669b75b86d293d2df2a7"},
{file = "coverage-7.9.2-cp311-cp311-win_arm64.whl", hash = "sha256:c2667a2b913e307f06aa4e5677f01a9746cd08e4b35e14ebcde6420a9ebb4c62"},
{file = "coverage-7.9.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ae9eb07f1cfacd9cfe8eaee6f4ff4b8a289a668c39c165cd0c8548484920ffc0"},
{file = "coverage-7.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9ce85551f9a1119f02adc46d3014b5ee3f765deac166acf20dbb851ceb79b6f3"},
{file = "coverage-7.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8f6389ac977c5fb322e0e38885fbbf901743f79d47f50db706e7644dcdcb6e1"},
{file = "coverage-7.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff0d9eae8cdfcd58fe7893b88993723583a6ce4dfbfd9f29e001922544f95615"},
{file = "coverage-7.9.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fae939811e14e53ed8a9818dad51d434a41ee09df9305663735f2e2d2d7d959b"},
{file = "coverage-7.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:31991156251ec202c798501e0a42bbdf2169dcb0f137b1f5c0f4267f3fc68ef9"},
{file = "coverage-7.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d0d67963f9cbfc7c7f96d4ac74ed60ecbebd2ea6eeb51887af0f8dce205e545f"},
{file = "coverage-7.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49b752a2858b10580969ec6af6f090a9a440a64a301ac1528d7ca5f7ed497f4d"},
{file = "coverage-7.9.2-cp312-cp312-win32.whl", hash = "sha256:88d7598b8ee130f32f8a43198ee02edd16d7f77692fa056cb779616bbea1b355"},
{file = "coverage-7.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:9dfb070f830739ee49d7c83e4941cc767e503e4394fdecb3b54bfdac1d7662c0"},
{file = "coverage-7.9.2-cp312-cp312-win_arm64.whl", hash = "sha256:4e2c058aef613e79df00e86b6d42a641c877211384ce5bd07585ed7ba71ab31b"},
{file = "coverage-7.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:985abe7f242e0d7bba228ab01070fde1d6c8fa12f142e43debe9ed1dde686038"},
{file = "coverage-7.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82c3939264a76d44fde7f213924021ed31f55ef28111a19649fec90c0f109e6d"},
{file = "coverage-7.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae5d563e970dbe04382f736ec214ef48103d1b875967c89d83c6e3f21706d5b3"},
{file = "coverage-7.9.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdd612e59baed2a93c8843c9a7cb902260f181370f1d772f4842987535071d14"},
{file = "coverage-7.9.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:256ea87cb2a1ed992bcdfc349d8042dcea1b80436f4ddf6e246d6bee4b5d73b6"},
{file = "coverage-7.9.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f44ae036b63c8ea432f610534a2668b0c3aee810e7037ab9d8ff6883de480f5b"},
{file = "coverage-7.9.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82d76ad87c932935417a19b10cfe7abb15fd3f923cfe47dbdaa74ef4e503752d"},
{file = "coverage-7.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:619317bb86de4193debc712b9e59d5cffd91dc1d178627ab2a77b9870deb2868"},
{file = "coverage-7.9.2-cp313-cp313-win32.whl", hash = "sha256:0a07757de9feb1dfafd16ab651e0f628fd7ce551604d1bf23e47e1ddca93f08a"},
{file = "coverage-7.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:115db3d1f4d3f35f5bb021e270edd85011934ff97c8797216b62f461dd69374b"},
{file = "coverage-7.9.2-cp313-cp313-win_arm64.whl", hash = "sha256:48f82f889c80af8b2a7bb6e158d95a3fbec6a3453a1004d04e4f3b5945a02694"},
{file = "coverage-7.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:55a28954545f9d2f96870b40f6c3386a59ba8ed50caf2d949676dac3ecab99f5"},
{file = "coverage-7.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cdef6504637731a63c133bb2e6f0f0214e2748495ec15fe42d1e219d1b133f0b"},
{file = "coverage-7.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcd5ebe66c7a97273d5d2ddd4ad0ed2e706b39630ed4b53e713d360626c3dbb3"},
{file = "coverage-7.9.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9303aed20872d7a3c9cb39c5d2b9bdbe44e3a9a1aecb52920f7e7495410dfab8"},
{file = "coverage-7.9.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc18ea9e417a04d1920a9a76fe9ebd2f43ca505b81994598482f938d5c315f46"},
{file = "coverage-7.9.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6406cff19880aaaadc932152242523e892faff224da29e241ce2fca329866584"},
{file = "coverage-7.9.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d0d4f6ecdf37fcc19c88fec3e2277d5dee740fb51ffdd69b9579b8c31e4232e"},
{file = "coverage-7.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c33624f50cf8de418ab2b4d6ca9eda96dc45b2c4231336bac91454520e8d1fac"},
{file = "coverage-7.9.2-cp313-cp313t-win32.whl", hash = "sha256:1df6b76e737c6a92210eebcb2390af59a141f9e9430210595251fbaf02d46926"},
{file = "coverage-7.9.2-cp313-cp313t-win_amd64.whl", hash = "sha256:f5fd54310b92741ebe00d9c0d1d7b2b27463952c022da6d47c175d246a98d1bd"},
{file = "coverage-7.9.2-cp313-cp313t-win_arm64.whl", hash = "sha256:c48c2375287108c887ee87d13b4070a381c6537d30e8487b24ec721bf2a781cb"},
{file = "coverage-7.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ddc39510ac922a5c4c27849b739f875d3e1d9e590d1e7b64c98dadf037a16cce"},
{file = "coverage-7.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a535c0c7364acd55229749c2b3e5eebf141865de3a8f697076a3291985f02d30"},
{file = "coverage-7.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df0f9ef28e0f20c767ccdccfc5ae5f83a6f4a2fbdfbcbcc8487a8a78771168c8"},
{file = "coverage-7.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f3da12e0ccbcb348969221d29441ac714bbddc4d74e13923d3d5a7a0bebef7a"},
{file = "coverage-7.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a17eaf46f56ae0f870f14a3cbc2e4632fe3771eab7f687eda1ee59b73d09fe4"},
{file = "coverage-7.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:669135a9d25df55d1ed56a11bf555f37c922cf08d80799d4f65d77d7d6123fcf"},
{file = "coverage-7.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9d3a700304d01a627df9db4322dc082a0ce1e8fc74ac238e2af39ced4c083193"},
{file = "coverage-7.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:71ae8b53855644a0b1579d4041304ddc9995c7b21c8a1f16753c4d8903b4dfed"},
{file = "coverage-7.9.2-cp39-cp39-win32.whl", hash = "sha256:dd7a57b33b5cf27acb491e890720af45db05589a80c1ffc798462a765be6d4d7"},
{file = "coverage-7.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f65bb452e579d5540c8b37ec105dd54d8b9307b07bcaa186818c104ffda22441"},
{file = "coverage-7.9.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:8a1166db2fb62473285bcb092f586e081e92656c7dfa8e9f62b4d39d7e6b5050"},
{file = "coverage-7.9.2-py3-none-any.whl", hash = "sha256:e425cd5b00f6fc0ed7cdbd766c70be8baab4b7839e4d4fe5fac48581dd968ea4"},
{file = "coverage-7.9.2.tar.gz", hash = "sha256:997024fa51e3290264ffd7492ec97d0690293ccd2b45a6cd7d82d945a4a80c8b"},
]
[package.extras]
@ -684,24 +684,25 @@ cli = ["requests"]
[[package]]
name = "fastapi"
version = "0.115.14"
version = "0.116.1"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "fastapi-0.115.14-py3-none-any.whl", hash = "sha256:6c0c8bf9420bd58f565e585036d971872472b4f7d3f6c73b698e10cffdefb3ca"},
{file = "fastapi-0.115.14.tar.gz", hash = "sha256:b1de15cdc1c499a4da47914db35d0e4ef8f1ce62b624e94e0e5824421df99739"},
{file = "fastapi-0.116.1-py3-none-any.whl", hash = "sha256:c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565"},
{file = "fastapi-0.116.1.tar.gz", hash = "sha256:ed52cbf946abfd70c5a0dccb24673f0670deeb517a88b3544d03c2a6bf283143"},
]
[package.dependencies]
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
starlette = ">=0.40.0,<0.47.0"
starlette = ">=0.40.0,<0.48.0"
typing-extensions = ">=4.8.0"
[package.extras]
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
standard-no-fastapi-cloud-cli = ["email-validator (>=2.0.0)", "fastapi-cli[standard-no-fastapi-cloud-cli] (>=0.0.8)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
[[package]]
name = "filelock"
@ -1627,44 +1628,44 @@ files = [
[[package]]
name = "mypy"
version = "1.16.1"
version = "1.17.0"
description = "Optional static typing for Python"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a"},
{file = "mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72"},
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea"},
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574"},
{file = "mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d"},
{file = "mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6"},
{file = "mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc"},
{file = "mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782"},
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507"},
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca"},
{file = "mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4"},
{file = "mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6"},
{file = "mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d"},
{file = "mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9"},
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79"},
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15"},
{file = "mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd"},
{file = "mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b"},
{file = "mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438"},
{file = "mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536"},
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f"},
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359"},
{file = "mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be"},
{file = "mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee"},
{file = "mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069"},
{file = "mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da"},
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c"},
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383"},
{file = "mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40"},
{file = "mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b"},
{file = "mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37"},
{file = "mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab"},
{file = "mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6"},
{file = "mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d"},
{file = "mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b"},
{file = "mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a"},
{file = "mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f"},
{file = "mypy-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937"},
{file = "mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be"},
{file = "mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61"},
{file = "mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f"},
{file = "mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d"},
{file = "mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3"},
{file = "mypy-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70"},
{file = "mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb"},
{file = "mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d"},
{file = "mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8"},
{file = "mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e"},
{file = "mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8"},
{file = "mypy-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d"},
{file = "mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06"},
{file = "mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a"},
{file = "mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889"},
{file = "mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba"},
{file = "mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658"},
{file = "mypy-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c"},
{file = "mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab"},
{file = "mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad"},
{file = "mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c"},
{file = "mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8"},
{file = "mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97"},
{file = "mypy-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4"},
{file = "mypy-1.17.0-py3-none-any.whl", hash = "sha256:15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496"},
{file = "mypy-1.17.0.tar.gz", hash = "sha256:e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03"},
]
[package.dependencies]
@ -1816,14 +1817,14 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
[[package]]
name = "openai"
version = "1.95.1"
version = "1.97.0"
description = "The official Python library for the openai API"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "openai-1.95.1-py3-none-any.whl", hash = "sha256:8bbdfeceef231b1ddfabbc232b179d79f8b849aab5a7da131178f8d10e0f162f"},
{file = "openai-1.95.1.tar.gz", hash = "sha256:f089b605282e2a2b6776090b4b46563ac1da77f56402a222597d591e2dcc1086"},
{file = "openai-1.97.0-py3-none-any.whl", hash = "sha256:a1c24d96f4609f3f7f51c9e1c2606d97cc6e334833438659cfd687e9c972c610"},
{file = "openai-1.97.0.tar.gz", hash = "sha256:0be349569ccaa4fb54f97bb808423fd29ccaeb1246ee1be762e0c81a47bae0aa"},
]
[package.dependencies]
@ -1844,84 +1845,84 @@ voice-helpers = ["numpy (>=2.0.2)", "sounddevice (>=0.5.1)"]
[[package]]
name = "orjson"
version = "3.10.18"
version = "3.11.0"
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "orjson-3.10.18-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a45e5d68066b408e4bc383b6e4ef05e717c65219a9e1390abc6155a520cac402"},
{file = "orjson-3.10.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be3b9b143e8b9db05368b13b04c84d37544ec85bb97237b3a923f076265ec89c"},
{file = "orjson-3.10.18-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b0aa09745e2c9b3bf779b096fa71d1cc2d801a604ef6dd79c8b1bfef52b2f92"},
{file = "orjson-3.10.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53a245c104d2792e65c8d225158f2b8262749ffe64bc7755b00024757d957a13"},
{file = "orjson-3.10.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9495ab2611b7f8a0a8a505bcb0f0cbdb5469caafe17b0e404c3c746f9900469"},
{file = "orjson-3.10.18-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73be1cbcebadeabdbc468f82b087df435843c809cd079a565fb16f0f3b23238f"},
{file = "orjson-3.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8936ee2679e38903df158037a2f1c108129dee218975122e37847fb1d4ac68"},
{file = "orjson-3.10.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7115fcbc8525c74e4c2b608129bef740198e9a120ae46184dac7683191042056"},
{file = "orjson-3.10.18-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:771474ad34c66bc4d1c01f645f150048030694ea5b2709b87d3bda273ffe505d"},
{file = "orjson-3.10.18-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7c14047dbbea52886dd87169f21939af5d55143dad22d10db6a7514f058156a8"},
{file = "orjson-3.10.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641481b73baec8db14fdf58f8967e52dc8bda1f2aba3aa5f5c1b07ed6df50b7f"},
{file = "orjson-3.10.18-cp310-cp310-win32.whl", hash = "sha256:607eb3ae0909d47280c1fc657c4284c34b785bae371d007595633f4b1a2bbe06"},
{file = "orjson-3.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:8770432524ce0eca50b7efc2a9a5f486ee0113a5fbb4231526d414e6254eba92"},
{file = "orjson-3.10.18-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e0a183ac3b8e40471e8d843105da6fbe7c070faab023be3b08188ee3f85719b8"},
{file = "orjson-3.10.18-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5ef7c164d9174362f85238d0cd4afdeeb89d9e523e4651add6a5d458d6f7d42d"},
{file = "orjson-3.10.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd14c5d99cdc7bf93f22b12ec3b294931518aa019e2a147e8aa2f31fd3240f7"},
{file = "orjson-3.10.18-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b672502323b6cd133c4af6b79e3bea36bad2d16bca6c1f645903fce83909a7a"},
{file = "orjson-3.10.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51f8c63be6e070ec894c629186b1c0fe798662b8687f3d9fdfa5e401c6bd7679"},
{file = "orjson-3.10.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9478ade5313d724e0495d167083c6f3be0dd2f1c9c8a38db9a9e912cdaf947"},
{file = "orjson-3.10.18-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187aefa562300a9d382b4b4eb9694806e5848b0cedf52037bb5c228c61bb66d4"},
{file = "orjson-3.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da552683bc9da222379c7a01779bddd0ad39dd699dd6300abaf43eadee38334"},
{file = "orjson-3.10.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e450885f7b47a0231979d9c49b567ed1c4e9f69240804621be87c40bc9d3cf17"},
{file = "orjson-3.10.18-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5e3c9cc2ba324187cd06287ca24f65528f16dfc80add48dc99fa6c836bb3137e"},
{file = "orjson-3.10.18-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:50ce016233ac4bfd843ac5471e232b865271d7d9d44cf9d33773bcd883ce442b"},
{file = "orjson-3.10.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b3ceff74a8f7ffde0b2785ca749fc4e80e4315c0fd887561144059fb1c138aa7"},
{file = "orjson-3.10.18-cp311-cp311-win32.whl", hash = "sha256:fdba703c722bd868c04702cac4cb8c6b8ff137af2623bc0ddb3b3e6a2c8996c1"},
{file = "orjson-3.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:c28082933c71ff4bc6ccc82a454a2bffcef6e1d7379756ca567c772e4fb3278a"},
{file = "orjson-3.10.18-cp311-cp311-win_arm64.whl", hash = "sha256:a6c7c391beaedd3fa63206e5c2b7b554196f14debf1ec9deb54b5d279b1b46f5"},
{file = "orjson-3.10.18-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:50c15557afb7f6d63bc6d6348e0337a880a04eaa9cd7c9d569bcb4e760a24753"},
{file = "orjson-3.10.18-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:356b076f1662c9813d5fa56db7d63ccceef4c271b1fb3dd522aca291375fcf17"},
{file = "orjson-3.10.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:559eb40a70a7494cd5beab2d73657262a74a2c59aff2068fdba8f0424ec5b39d"},
{file = "orjson-3.10.18-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f3c29eb9a81e2fbc6fd7ddcfba3e101ba92eaff455b8d602bf7511088bbc0eae"},
{file = "orjson-3.10.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6612787e5b0756a171c7d81ba245ef63a3533a637c335aa7fcb8e665f4a0966f"},
{file = "orjson-3.10.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ac6bd7be0dcab5b702c9d43d25e70eb456dfd2e119d512447468f6405b4a69c"},
{file = "orjson-3.10.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f72f100cee8dde70100406d5c1abba515a7df926d4ed81e20a9730c062fe9ad"},
{file = "orjson-3.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca85398d6d093dd41dc0983cbf54ab8e6afd1c547b6b8a311643917fbf4e0c"},
{file = "orjson-3.10.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22748de2a07fcc8781a70edb887abf801bb6142e6236123ff93d12d92db3d406"},
{file = "orjson-3.10.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3a83c9954a4107b9acd10291b7f12a6b29e35e8d43a414799906ea10e75438e6"},
{file = "orjson-3.10.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:303565c67a6c7b1f194c94632a4a39918e067bd6176a48bec697393865ce4f06"},
{file = "orjson-3.10.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:86314fdb5053a2f5a5d881f03fca0219bfdf832912aa88d18676a5175c6916b5"},
{file = "orjson-3.10.18-cp312-cp312-win32.whl", hash = "sha256:187ec33bbec58c76dbd4066340067d9ece6e10067bb0cc074a21ae3300caa84e"},
{file = "orjson-3.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:f9f94cf6d3f9cd720d641f8399e390e7411487e493962213390d1ae45c7814fc"},
{file = "orjson-3.10.18-cp312-cp312-win_arm64.whl", hash = "sha256:3d600be83fe4514944500fa8c2a0a77099025ec6482e8087d7659e891f23058a"},
{file = "orjson-3.10.18-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:69c34b9441b863175cc6a01f2935de994025e773f814412030f269da4f7be147"},
{file = "orjson-3.10.18-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:1ebeda919725f9dbdb269f59bc94f861afbe2a27dce5608cdba2d92772364d1c"},
{file = "orjson-3.10.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5adf5f4eed520a4959d29ea80192fa626ab9a20b2ea13f8f6dc58644f6927103"},
{file = "orjson-3.10.18-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7592bb48a214e18cd670974f289520f12b7aed1fa0b2e2616b8ed9e069e08595"},
{file = "orjson-3.10.18-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f872bef9f042734110642b7a11937440797ace8c87527de25e0c53558b579ccc"},
{file = "orjson-3.10.18-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0315317601149c244cb3ecef246ef5861a64824ccbcb8018d32c66a60a84ffbc"},
{file = "orjson-3.10.18-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0da26957e77e9e55a6c2ce2e7182a36a6f6b180ab7189315cb0995ec362e049"},
{file = "orjson-3.10.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb70d489bc79b7519e5803e2cc4c72343c9dc1154258adf2f8925d0b60da7c58"},
{file = "orjson-3.10.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9e86a6af31b92299b00736c89caf63816f70a4001e750bda179e15564d7a034"},
{file = "orjson-3.10.18-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c382a5c0b5931a5fc5405053d36c1ce3fd561694738626c77ae0b1dfc0242ca1"},
{file = "orjson-3.10.18-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8e4b2ae732431127171b875cb2668f883e1234711d3c147ffd69fe5be51a8012"},
{file = "orjson-3.10.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d808e34ddb24fc29a4d4041dcfafbae13e129c93509b847b14432717d94b44f"},
{file = "orjson-3.10.18-cp313-cp313-win32.whl", hash = "sha256:ad8eacbb5d904d5591f27dee4031e2c1db43d559edb8f91778efd642d70e6bea"},
{file = "orjson-3.10.18-cp313-cp313-win_amd64.whl", hash = "sha256:aed411bcb68bf62e85588f2a7e03a6082cc42e5a2796e06e72a962d7c6310b52"},
{file = "orjson-3.10.18-cp313-cp313-win_arm64.whl", hash = "sha256:f54c1385a0e6aba2f15a40d703b858bedad36ded0491e55d35d905b2c34a4cc3"},
{file = "orjson-3.10.18-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95fae14225edfd699454e84f61c3dd938df6629a00c6ce15e704f57b58433bb"},
{file = "orjson-3.10.18-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5232d85f177f98e0cefabb48b5e7f60cff6f3f0365f9c60631fecd73849b2a82"},
{file = "orjson-3.10.18-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2783e121cafedf0d85c148c248a20470018b4ffd34494a68e125e7d5857655d1"},
{file = "orjson-3.10.18-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e54ee3722caf3db09c91f442441e78f916046aa58d16b93af8a91500b7bbf273"},
{file = "orjson-3.10.18-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2daf7e5379b61380808c24f6fc182b7719301739e4271c3ec88f2984a2d61f89"},
{file = "orjson-3.10.18-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f39b371af3add20b25338f4b29a8d6e79a8c7ed0e9dd49e008228a065d07781"},
{file = "orjson-3.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b819ed34c01d88c6bec290e6842966f8e9ff84b7694632e88341363440d4cc0"},
{file = "orjson-3.10.18-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2f6c57debaef0b1aa13092822cbd3698a1fb0209a9ea013a969f4efa36bdea57"},
{file = "orjson-3.10.18-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:755b6d61ffdb1ffa1e768330190132e21343757c9aa2308c67257cc81a1a6f5a"},
{file = "orjson-3.10.18-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ce8d0a875a85b4c8579eab5ac535fb4b2a50937267482be402627ca7e7570ee3"},
{file = "orjson-3.10.18-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57b5d0673cbd26781bebc2bf86f99dd19bd5a9cb55f71cc4f66419f6b50f3d77"},
{file = "orjson-3.10.18-cp39-cp39-win32.whl", hash = "sha256:951775d8b49d1d16ca8818b1f20c4965cae9157e7b562a2ae34d3967b8f21c8e"},
{file = "orjson-3.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:fdd9d68f83f0bc4406610b1ac68bdcded8c5ee58605cc69e643a06f4d075f429"},
{file = "orjson-3.10.18.tar.gz", hash = "sha256:e8da3947d92123eda795b68228cafe2724815621fe35e8e320a9e9593a4bcd53"},
{file = "orjson-3.11.0-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b8913baba9751f7400f8fa4ec18a8b618ff01177490842e39e47b66c1b04bc79"},
{file = "orjson-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d4d86910554de5c9c87bc560b3bdd315cc3988adbdc2acf5dda3797079407ed"},
{file = "orjson-3.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84ae3d329360cf18fb61b67c505c00dedb61b0ee23abfd50f377a58e7d7bed06"},
{file = "orjson-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47a54e660414baacd71ebf41a69bb17ea25abb3c5b69ce9e13e43be7ac20e342"},
{file = "orjson-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2560b740604751854be146169c1de7e7ee1e6120b00c1788ec3f3a012c6a243f"},
{file = "orjson-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7f9cd995da9e46fbac0a371f0ff6e89a21d8ecb7a8a113c0acb147b0a32f73"},
{file = "orjson-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cf728cb3a013bdf9f4132575404bf885aa773d8bb4205656575e1890fc91990"},
{file = "orjson-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c27de273320294121200440cd5002b6aeb922d3cb9dab3357087c69f04ca6934"},
{file = "orjson-3.11.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4430ec6ff1a1f4595dd7e0fad991bdb2fed65401ed294984c490ffa025926325"},
{file = "orjson-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:325be41a8d7c227d460a9795a181511ba0e731cf3fee088c63eb47e706ea7559"},
{file = "orjson-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9760217b84d1aee393b4436fbe9c639e963ec7bc0f2c074581ce5fb3777e466"},
{file = "orjson-3.11.0-cp310-cp310-win32.whl", hash = "sha256:fe36e5012f886ff91c68b87a499c227fa220e9668cea96335219874c8be5fab5"},
{file = "orjson-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:ebeecd5d5511b3ca9dc4e7db0ab95266afd41baf424cc2fad8c2d3a3cdae650a"},
{file = "orjson-3.11.0-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1785df7ada75c18411ff7e20ac822af904a40161ea9dfe8c55b3f6b66939add6"},
{file = "orjson-3.11.0-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:a57899bebbcea146616a2426d20b51b3562b4bc9f8039a3bd14fae361c23053d"},
{file = "orjson-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fbc2fc825aff1456dd358c11a0ad7912a4cb4537d3db92e5334af7463a967"},
{file = "orjson-3.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4305a638f4cf9bed3746ca3b7c242f14e05177d5baec2527026e0f9ee6c24fb7"},
{file = "orjson-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1235fe7bbc37164f69302199d46f29cfb874018738714dccc5a5a44042c79c77"},
{file = "orjson-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a640e3954e7b4fcb160097551e54cafbde9966be3991932155b71071077881aa"},
{file = "orjson-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d750b97d22d5566955e50b02c622f3a1d32744d7a578c878b29a873190ccb7a"},
{file = "orjson-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfcfe498484161e011f8190a400591c52b026de96b3b3cbd3f21e8999b9dc0e"},
{file = "orjson-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:feaed3ed43a1d2df75c039798eb5ec92c350c7d86be53369bafc4f3700ce7df2"},
{file = "orjson-3.11.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa1120607ec8fc98acf8c54aac6fb0b7b003ba883401fa2d261833111e2fa071"},
{file = "orjson-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c4b48d9775b0cf1f0aca734f4c6b272cbfacfac38e6a455e6520662f9434afb7"},
{file = "orjson-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f018ed1986d79434ac712ff19f951cd00b4dfcb767444410fbb834ebec160abf"},
{file = "orjson-3.11.0-cp311-cp311-win32.whl", hash = "sha256:08e191f8a55ac2c00be48e98a5d10dca004cbe8abe73392c55951bfda60fc123"},
{file = "orjson-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:b5a4214ea59c8a3b56f8d484b28114af74e9fba0956f9be5c3ce388ae143bf1f"},
{file = "orjson-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:57e8e7198a679ab21241ab3f355a7990c7447559e35940595e628c107ef23736"},
{file = "orjson-3.11.0-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b4089f940c638bb1947d54e46c1cd58f4259072fcc97bc833ea9c78903150ac9"},
{file = "orjson-3.11.0-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:8335a0ba1c26359fb5c82d643b4c1abbee2bc62875e0f2b5bde6c8e9e25eb68c"},
{file = "orjson-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63c1c9772dafc811d16d6a7efa3369a739da15d1720d6e58ebe7562f54d6f4a2"},
{file = "orjson-3.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9457ccbd8b241fb4ba516417a4c5b95ba0059df4ac801309bcb4ec3870f45ad9"},
{file = "orjson-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0846e13abe79daece94a00b92574f294acad1d362be766c04245b9b4dd0e47e1"},
{file = "orjson-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5587c85ae02f608a3f377b6af9eb04829606f518257cbffa8f5081c1aacf2e2f"},
{file = "orjson-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7a1964a71c1567b4570c932a0084ac24ad52c8cf6253d1881400936565ed438"},
{file = "orjson-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5a8243e73690cc6e9151c9e1dd046a8f21778d775f7d478fa1eb4daa4897c61"},
{file = "orjson-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51646f6d995df37b6e1b628f092f41c0feccf1d47e3452c6e95e2474b547d842"},
{file = "orjson-3.11.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:2fb8ca8f0b4e31b8aaec674c7540649b64ef02809410506a44dc68d31bd5647b"},
{file = "orjson-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:64a6a3e94a44856c3f6557e6aa56a6686544fed9816ae0afa8df9077f5759791"},
{file = "orjson-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d69f95d484938d8fab5963e09131bcf9fbbb81fa4ec132e316eb2fb9adb8ce78"},
{file = "orjson-3.11.0-cp312-cp312-win32.whl", hash = "sha256:8514f9f9c667ce7d7ef709ab1a73e7fcab78c297270e90b1963df7126d2b0e23"},
{file = "orjson-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:41b38a894520b8cb5344a35ffafdf6ae8042f56d16771b2c5eb107798cee85ee"},
{file = "orjson-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:5579acd235dd134467340b2f8a670c1c36023b5a69c6a3174c4792af7502bd92"},
{file = "orjson-3.11.0-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a8ba9698655e16746fdf5266939427da0f9553305152aeb1a1cc14974a19cfb"},
{file = "orjson-3.11.0-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:67133847f9a35a5ef5acfa3325d4a2f7fe05c11f1505c4117bb086fc06f2a58f"},
{file = "orjson-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f797d57814975b78f5f5423acb003db6f9be5186b72d48bd97a1000e89d331d"},
{file = "orjson-3.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:28acd19822987c5163b9e03a6e60853a52acfee384af2b394d11cb413b889246"},
{file = "orjson-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8d38d9e1e2cf9729658e35956cf01e13e89148beb4cb9e794c9c10c5cb252f8"},
{file = "orjson-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05f094edd2b782650b0761fd78858d9254de1c1286f5af43145b3d08cdacfd51"},
{file = "orjson-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d09176a4a9e04a5394a4a0edd758f645d53d903b306d02f2691b97d5c736a9e"},
{file = "orjson-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a585042104e90a61eda2564d11317b6a304eb4e71cd33e839f5af6be56c34d3"},
{file = "orjson-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d2218629dbfdeeb5c9e0573d59f809d42f9d49ae6464d2f479e667aee14c3ef4"},
{file = "orjson-3.11.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:613e54a2b10b51b656305c11235a9c4a5c5491ef5c283f86483d4e9e123ed5e4"},
{file = "orjson-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9dac7fbf3b8b05965986c5cfae051eb9a30fced7f15f1d13a5adc608436eb486"},
{file = "orjson-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b64b254414e2be55ac5257124b5602c5f0b4d06b80bd27d1165efe8f36e836"},
{file = "orjson-3.11.0-cp313-cp313-win32.whl", hash = "sha256:359cbe11bc940c64cb3848cf22000d2aef36aff7bfd09ca2c0b9cb309c387132"},
{file = "orjson-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:0759b36428067dc777b202dd286fbdd33d7f261c6455c4238ea4e8474358b1e6"},
{file = "orjson-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:51cdca2f36e923126d0734efaf72ddbb5d6da01dbd20eab898bdc50de80d7b5a"},
{file = "orjson-3.11.0-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d79c180cfb3ae68f13245d0ff551dca03d96258aa560830bf8a223bd68d8272c"},
{file = "orjson-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:105bca887532dc71ce4b05a5de95dea447a310409d7a8cf0cb1c4a120469e9ad"},
{file = "orjson-3.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acf5a63ae9cdb88274126af85913ceae554d8fd71122effa24a53227abbeee16"},
{file = "orjson-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:894635df36c0be32f1c8c8607e853b8865edb58e7618e57892e85d06418723eb"},
{file = "orjson-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02dd4f0a1a2be943a104ce5f3ec092631ee3e9f0b4bb9eeee3400430bd94ddef"},
{file = "orjson-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:720b4bb5e1b971960a62c2fa254c2d2a14e7eb791e350d05df8583025aa59d15"},
{file = "orjson-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bf058105a8aed144e0d1cfe7ac4174748c3fc7203f225abaeac7f4121abccb0"},
{file = "orjson-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a2788f741e5a0e885e5eaf1d91d0c9106e03cb9575b0c55ba36fd3d48b0b1e9b"},
{file = "orjson-3.11.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:c60c99fe1e15894367b0340b2ff16c7c69f9c3f3a54aa3961a58c102b292ad94"},
{file = "orjson-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:99d17aab984f4d029b8f3c307e6be3c63d9ee5ef55e30d761caf05e883009949"},
{file = "orjson-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e98f02e23611763c9e5dfcb83bd33219231091589f0d1691e721aea9c52bf329"},
{file = "orjson-3.11.0-cp39-cp39-win32.whl", hash = "sha256:923301f33ea866b18f8836cf41d9c6d33e3b5cab8577d20fed34ec29f0e13a0d"},
{file = "orjson-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:475491bb78af2a0170f49e90013f1a0f1286527f3617491f8940d7e5da862da7"},
{file = "orjson-3.11.0.tar.gz", hash = "sha256:2e4c129da624f291bcc607016a99e7f04a353f6874f3bd8d9b47b88597d5f700"},
]
[[package]]
@ -2684,14 +2685,14 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests
[[package]]
name = "pytest-asyncio"
version = "1.0.0"
version = "1.1.0"
description = "Pytest support for asyncio"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3"},
{file = "pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f"},
{file = "pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf"},
{file = "pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea"},
]
[package.dependencies]
@ -3871,4 +3872,4 @@ pgsql = ["psycopg2-binary"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.12,<3.13"
content-hash = "df16815f799254568f5e7083c49bb302e77003bcafbd34dfa92ad65d0335efb3"
content-hash = "8c337ab9231ded0f66d8e8d14a6d465bb8009f0f9377e5c480ed5baa4b928ed1"

View file

@ -3,7 +3,7 @@ authors = ["Hayden <hay-kot@pm.me>"]
description = "A Recipe Manager"
license = "AGPL"
name = "mealie"
version = "3.0.1"
version = "3.0.2"
include = [
# Explicit include to override .gitignore when packaging the frontend
{ path = "mealie/frontend/**/*", format = ["sdist", "wheel"] }
@ -24,7 +24,7 @@ appdirs = "1.4.4"
apprise = "^1.4.5"
bcrypt = "^4.0.1"
extruct = "^0.18.0"
fastapi = "^0.115.0"
fastapi = "^0.116.0"
httpx = "^0.28.0"
lxml = "^6.0.0"
orjson = "^3.8.0"

View file

@ -2,7 +2,8 @@ import pytest
from bs4 import BeautifulSoup
from mealie.routes import spa
from mealie.schema.recipe.recipe import Recipe
from mealie.schema.recipe.recipe import Recipe, RecipeSettings
from mealie.schema.recipe.recipe_notes import RecipeNote
from mealie.schema.recipe.recipe_share_token import RecipeShareTokenSave
from tests import data as test_data
from tests.utils.factories import random_string
@ -189,3 +190,28 @@ async def test_spa_service_shared_recipe_with_meta_invalid_data(unique_user: Tes
response = await spa.serve_shared_recipe_with_meta(group.slug, random_string(), session=unique_user.repos.session)
assert response.status_code == 404
@pytest.mark.parametrize(
"malicious_content, malicious_strings",
[
("<script>alert('XSS');</script>", ["<script>", "alert('XSS')"]),
("<img src=x onerror=alert('XSS')>", ["<img", "onerror=alert('XSS')"]),
("<div onmouseover=alert('XSS')>Hover me</div>", ["<div", "onmouseover=alert('XSS')"]),
("<a href='javascript:alert(\"XSS\")'>Click me</a>", ["<a", 'javascript:alert("XSS")']),
],
)
def test_spa_escapes_malicious_recipe_data(unique_user: TestUser, malicious_content: str, malicious_strings: list[str]):
recipe = Recipe(
user_id=unique_user.user_id,
group_id=unique_user.group_id,
name=malicious_content,
description=malicious_content,
image=malicious_content,
notes=[RecipeNote(title=malicious_content, text=malicious_content)],
settings=RecipeSettings(),
)
response = spa.content_with_meta(unique_user.group_id, recipe)
for string in malicious_strings:
assert string not in response