From 50fdae2308261f66a5598b4c3ed43d04b6f588a5 Mon Sep 17 00:00:00 2001 From: Nico Date: Wed, 19 Apr 2023 18:24:40 +0200 Subject: [PATCH] added references page + references --- .astro-i18n/generated.d.ts | 8 +-- .astro/types.d.ts | 58 +++++++++++++++++++ astro.i18n.config.ts | 1 + src/components/CardEditorial.astro | 58 +++++++++++++------ src/components/Navigation.astro | 6 ++ src/content/config.ts | 19 ++++++ src/content/references/en/3w.md | 10 ++++ src/content/references/en/natureo.md | 10 ++++ .../references/en/parole-expression.md | 10 ++++ src/content/references/en/rose-primaire.md | 10 ++++ src/content/references/fr/3w.md | 10 ++++ src/content/references/fr/natureo.md | 10 ++++ .../references/fr/parole-expression.md | 10 ++++ src/content/references/fr/rose-primaire.md | 10 ++++ src/data/HP/en/01-offre.md | 2 + src/data/HP/fr/01-offre.md | 2 + src/i18n/en.json | 17 +++--- src/i18n/fr.json | 19 +++--- src/pages/en/work/[slug].astro | 9 +++ src/pages/en/work/index.astro | 7 +++ src/pages/references/i18n/en.json | 4 ++ src/pages/references/i18n/fr.json | 4 ++ src/pages/references/index.astro | 44 ++++++++++++++ 23 files changed, 297 insertions(+), 41 deletions(-) create mode 100644 src/content/references/en/3w.md create mode 100644 src/content/references/en/natureo.md create mode 100644 src/content/references/en/parole-expression.md create mode 100644 src/content/references/en/rose-primaire.md create mode 100644 src/content/references/fr/3w.md create mode 100644 src/content/references/fr/natureo.md create mode 100644 src/content/references/fr/parole-expression.md create mode 100644 src/content/references/fr/rose-primaire.md create mode 100644 src/pages/en/work/[slug].astro create mode 100644 src/pages/en/work/index.astro create mode 100644 src/pages/references/i18n/en.json create mode 100644 src/pages/references/i18n/fr.json create mode 100644 src/pages/references/index.astro diff --git a/.astro-i18n/generated.d.ts b/.astro-i18n/generated.d.ts index 0d8c3a4..213751d 100644 --- a/.astro-i18n/generated.d.ts +++ b/.astro-i18n/generated.d.ts @@ -1,10 +1,10 @@ type DefaultLangCode = "fr" type SupportedLangCode = "en" type LangCode = DefaultLangCode | SupportedLangCode -type RouteUri = | "/articles/[slug]" | "/articles" | "/agments/[slug]" | "/agments" | "/" | "/plan-du-site" -type RouteParams = {"/articles/[slug]": { "slug": string; }; "/articles": undefined; "/agments/[slug]": { "slug": string; }; "/agments": undefined; "/": undefined; "/plan-du-site": undefined; } -type TranslationPath = "accueil" | "tagline" | "copyright" | "contact.title" | "contact.email" | "contact.tel" | "contenuVide" | "header.skipLink" | "header.mainNav" | "header.homeLink" | "sitemap" | "prevNext.contenus" | "prevNext.precedent" | "prevNext.suivant" | "article.titre" | "article.tagline" | "article.published" | "meta.publication" | "meta.modification" | "meta.credit" | "fragments.titre" | "fragments.tagline" | "projet.titre" | "projet.tagline" | "projet.cta" | "projet.lienTitle" | "projet.fenetre" | "erreur.introuvable" | "erreur.autre" | "erreur.lienRetour" | "seo.article.title" | "seo.article.description" | "seo.projet.title" | "seo.projet.description" | "seo.code.title" | "seo.code.description" | "index.articles.pageName" | "index.articles.subtitle" | "index.fragments.pageName" | "index.fragments.subtitle" | "index.title" | "index.subtitle" | "index.quoi" | "index.comment" | "index.opensource" | "index.writing" | "index.latestProjects" | "index.latestArticles" | "index.allProjects" | "index.allArticles" | "index.latestSnippets" | "index.allSnippets" | "index.toc" | "contact.contenuVide" -type TranslationOptions = { "accueil": {} | undefined; "tagline": {} | undefined; "copyright": {} | undefined; "contact.title": {} | undefined; "contact.email": {} | undefined; "contact.tel": {} | undefined; "contenuVide": {} | undefined; "header.skipLink": {} | undefined; "header.mainNav": {} | undefined; "header.homeLink": {} | undefined; "sitemap": {} | undefined; "prevNext.contenus": {} | undefined; "prevNext.precedent": {} | undefined; "prevNext.suivant": {} | undefined; "article.titre": {} | undefined; "article.tagline": {} | undefined; "article.published": { datetime: unknown; options: unknown; }; "meta.publication": {} | undefined; "meta.modification": {} | undefined; "meta.credit": {} | undefined; "fragments.titre": {} | undefined; "fragments.tagline": {} | undefined; "projet.titre": {} | undefined; "projet.tagline": {} | undefined; "projet.cta": {} | undefined; "projet.lienTitle": {} | undefined; "projet.fenetre": {} | undefined; "erreur.introuvable": {} | undefined; "erreur.autre": {} | undefined; "erreur.lienRetour": {} | undefined; "seo.article.title": {} | undefined; "seo.article.description": {} | undefined; "seo.projet.title": {} | undefined; "seo.projet.description": {} | undefined; "seo.code.title": {} | undefined; "seo.code.description": {} | undefined; "index.articles.pageName": {} | undefined; "index.articles.subtitle": {} | undefined; "index.fragments.pageName": {} | undefined; "index.fragments.subtitle": {} | undefined; "index.title": {} | undefined; "index.subtitle": {} | undefined; "index.quoi": {} | undefined; "index.comment": {} | undefined; "index.opensource": {} | undefined; "index.writing": {} | undefined; "index.latestProjects": {} | undefined; "index.latestArticles": {} | undefined; "index.allProjects": {} | undefined; "index.allArticles": {} | undefined; "index.latestSnippets": {} | undefined; "index.allSnippets": {} | undefined; "index.toc": {} | undefined; "contact.contenuVide": {} | undefined; } +type RouteUri = | "/articles/[slug]" | "/articles" | "/agments/[slug]" | "/agments" | "/references" | "/" | "/plan-du-site" +type RouteParams = {"/articles/[slug]": { "slug": string; }; "/articles": undefined; "/agments/[slug]": { "slug": string; }; "/agments": undefined; "/references": undefined; "/": undefined; "/plan-du-site": undefined; } +type TranslationPath = "accueil" | "tagline" | "copyright" | "contact.title" | "contact.email" | "contact.tel" | "contenuVide" | "header.skipLink" | "header.mainNav" | "header.homeLink" | "sitemap" | "prevNext.contenus" | "prevNext.precedent" | "prevNext.suivant" | "article.titre" | "article.tagline" | "article.published" | "meta.publication" | "meta.modification" | "meta.credit" | "fragments.titre" | "fragments.tagline" | "references.titre" | "references.slug" | "references.cta" | "references.tagline" | "erreur.introuvable" | "erreur.autre" | "erreur.lienRetour" | "seo.article.title" | "seo.article.description" | "seo.code.title" | "seo.code.description" | "seo.references.title" | "seo.references.description" | "index.articles.pageName" | "index.articles.subtitle" | "index.fragments.pageName" | "index.fragments.subtitle" | "index.references.pageName" | "index.references.subtitle" | "index.title" | "index.subtitle" | "index.quoi" | "index.comment" | "index.opensource" | "index.writing" | "index.latestProjects" | "index.latestArticles" | "index.allProjects" | "index.allArticles" | "index.latestSnippets" | "index.allSnippets" | "index.toc" | "contact.contenuVide" +type TranslationOptions = { "accueil": {} | undefined; "tagline": {} | undefined; "copyright": {} | undefined; "contact.title": {} | undefined; "contact.email": {} | undefined; "contact.tel": {} | undefined; "contenuVide": {} | undefined; "header.skipLink": {} | undefined; "header.mainNav": {} | undefined; "header.homeLink": {} | undefined; "sitemap": {} | undefined; "prevNext.contenus": {} | undefined; "prevNext.precedent": {} | undefined; "prevNext.suivant": {} | undefined; "article.titre": {} | undefined; "article.tagline": {} | undefined; "article.published": { datetime: unknown; options: unknown; }; "meta.publication": {} | undefined; "meta.modification": {} | undefined; "meta.credit": {} | undefined; "fragments.titre": {} | undefined; "fragments.tagline": {} | undefined; "references.titre": {} | undefined; "references.slug": {} | undefined; "references.cta": {} | undefined; "references.tagline": {} | undefined; "erreur.introuvable": {} | undefined; "erreur.autre": {} | undefined; "erreur.lienRetour": {} | undefined; "seo.article.title": {} | undefined; "seo.article.description": {} | undefined; "seo.code.title": {} | undefined; "seo.code.description": {} | undefined; "seo.references.title": {} | undefined; "seo.references.description": {} | undefined; "index.articles.pageName": {} | undefined; "index.articles.subtitle": {} | undefined; "index.fragments.pageName": {} | undefined; "index.fragments.subtitle": {} | undefined; "index.references.pageName": {} | undefined; "index.references.subtitle": {} | undefined; "index.title": {} | undefined; "index.subtitle": {} | undefined; "index.quoi": {} | undefined; "index.comment": {} | undefined; "index.opensource": {} | undefined; "index.writing": {} | undefined; "index.latestProjects": {} | undefined; "index.latestArticles": {} | undefined; "index.allProjects": {} | undefined; "index.allArticles": {} | undefined; "index.latestSnippets": {} | undefined; "index.allSnippets": {} | undefined; "index.toc": {} | undefined; "contact.contenuVide": {} | undefined; } declare module "astro-i18n" { export * from "astro-i18n/" diff --git a/.astro/types.d.ts b/.astro/types.d.ts index 8076dc3..0fd16b7 100644 --- a/.astro/types.d.ts +++ b/.astro/types.d.ts @@ -324,6 +324,64 @@ declare module 'astro:content' { collection: "fragments", data: InferEntrySchema<"fragments"> } & { render(): Render[".md"] }, +}, +"references": { +"en/3w.md": { + id: "en/3w.md", + slug: "3w", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, +"en/natureo.md": { + id: "en/natureo.md", + slug: "natureo", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, +"en/parole-expression.md": { + id: "en/parole-expression.md", + slug: "parole-expression", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, +"en/rose-primaire.md": { + id: "en/rose-primaire.md", + slug: "rose-primaire", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, +"fr/3w.md": { + id: "fr/3w.md", + slug: "3w", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, +"fr/natureo.md": { + id: "fr/natureo.md", + slug: "natureo", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, +"fr/parole-expression.md": { + id: "fr/parole-expression.md", + slug: "parole-expression", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, +"fr/rose-primaire.md": { + id: "fr/rose-primaire.md", + slug: "rose-primaire", + body: string, + collection: "references", + data: InferEntrySchema<"references"> +} & { render(): Render[".md"] }, }, }; diff --git a/astro.i18n.config.ts b/astro.i18n.config.ts index ae8268f..54e3e28 100644 --- a/astro.i18n.config.ts +++ b/astro.i18n.config.ts @@ -13,6 +13,7 @@ export default defineAstroI18nConfig({ "sci-hub-blocage": "sci-hub-unblock", fragments: "snippets", "plan-du-site": "sitemap", + references: "work", }, }, }); diff --git a/src/components/CardEditorial.astro b/src/components/CardEditorial.astro index 67049b6..e8f4d9b 100644 --- a/src/components/CardEditorial.astro +++ b/src/components/CardEditorial.astro @@ -1,20 +1,39 @@ --- import ListTags from "./ListTags.astro"; -import { l, astroI18n } from "astro-i18n"; +import { l, t } from "astro-i18n"; const { item, routeName } = Astro.props; + +// no link on references cards +const isReference = routeName === t("references.slug"); --- -
+

- {item.data.title} + { + !isReference ? ( + + {item.data.title} + + ) : ( + {item.data.title} + ) + }

{item.data.subtitle}

+ { + isReference && ( + + {t("references.cta")} + {item.data.title} + + ) + }
@@ -25,17 +44,20 @@ const { item, routeName } = Astro.props; display: block; block-size: 100%; overflow: hidden; - cursor: pointer; box-shadow: var(--shadow-elevation-medium); background-color: white; } - .card:hover { + /* + * to be replaced with .card:has(a) + * when firefox supports it + */ + .card--link:hover { box-shadow: var(--shadow-elevation-high); } - .card:focus-within { + .card--link:focus-within { box-shadow: var(--shadow-elevation-high); } - .card::after { + .card--link::after { content: ""; position: absolute; inline-size: 30px; @@ -49,19 +71,19 @@ const { item, routeName } = Astro.props; background-size: contain; transform: translateX(1rem); } - .card:hover::after, - .card:focus-within::after { + .card--link:hover::after, + .card--link:focus-within::after { transform: translateX(0); opacity: 1; } - .card:hover h3 a { + .card--link:hover h3 a { text-decoration: underline; } - .card:hover h3 a, - .card:focus-within h3 a { + .card--link:hover h3 a, + .card--link:focus-within h3 a { color: var(--color-brique); } - .card::before { + .card--link::before { content: ""; position: absolute; top: 0; @@ -73,8 +95,8 @@ const { item, routeName } = Astro.props; transform-origin: bottom; background-color: var(--color-brique); } - .card:hover::before, - .card:focus-within::before { + .card--link:hover::before, + .card--link:focus-within::before { transform: scaleY(1); transform-origin: top; } diff --git a/src/components/Navigation.astro b/src/components/Navigation.astro index ed9a733..c89b5c9 100644 --- a/src/components/Navigation.astro +++ b/src/components/Navigation.astro @@ -17,6 +17,12 @@ import LanguageSwitcher from "./LangSwitcher.astro"; > +
  • + {t("references.titre")} + +
  • new Date(str)), + updatedAt: z + .string() + .transform((str) => new Date(str)) + .optional(), + code: z.boolean().optional() || false, + draft: z.boolean().optional() || false, + }), +}); + export const collections = { // Don't forget 'quotes' for collection names containing dashes articles, fragments, + references, }; diff --git a/src/content/references/en/3w.md b/src/content/references/en/3w.md new file mode 100644 index 0000000..a50424f --- /dev/null +++ b/src/content/references/en/3w.md @@ -0,0 +1,10 @@ +--- +title: 3w +subtitle: I wrote the doc! +url: https://3-w.fr +lang: en +slug: "3w" +excerpt: Développement web et compagnie. +tags: ["Front-end", "docs"] +createdAt: "2022-10-19T18:02:00.000Z" +--- diff --git a/src/content/references/en/natureo.md b/src/content/references/en/natureo.md new file mode 100644 index 0000000..967b399 --- /dev/null +++ b/src/content/references/en/natureo.md @@ -0,0 +1,10 @@ +--- +title: Nature en Occitanie +subtitle: Sobriety is only natural. +url: https://www.natureo.org/ +lang: en +slug: "natureo" +excerpt: Développement web et compagnie. +tags: ["Front-end", "accessibility", "sobriety", "CMS"] +createdAt: "2023-04-19T18:02:00.000Z" +--- diff --git a/src/content/references/en/parole-expression.md b/src/content/references/en/parole-expression.md new file mode 100644 index 0000000..53dfd38 --- /dev/null +++ b/src/content/references/en/parole-expression.md @@ -0,0 +1,10 @@ +--- +title: Parole Expression +subtitle: A new website for the association. +url: https://www.paroleexpression.fr/ +lang: en +slug: "parole-expression" +excerpt: Développement web et compagnie. +tags: ["Front-end", "sobriety", "CMS"] +createdAt: "2022-04-19T17:11:00.000Z" +--- diff --git a/src/content/references/en/rose-primaire.md b/src/content/references/en/rose-primaire.md new file mode 100644 index 0000000..1e9ed23 --- /dev/null +++ b/src/content/references/en/rose-primaire.md @@ -0,0 +1,10 @@ +--- +title: Rose Primaire +subtitle: An agency we love. +url: https://roseprimaire.com/ +lang: en +slug: "rose-primaire" +excerpt: Web dev and other things. +tags: ["Front-end", "accessibility", "sobriety", "CMS"] +createdAt: "2023-04-19T17:11:00.000Z" +--- diff --git a/src/content/references/fr/3w.md b/src/content/references/fr/3w.md new file mode 100644 index 0000000..8f0e984 --- /dev/null +++ b/src/content/references/fr/3w.md @@ -0,0 +1,10 @@ +--- +title: 3w +subtitle: J'ai fait de la doc! +url: https://3-w.fr +lang: fr +slug: "3w" +excerpt: Développement web et compagnie. +tags: ["Front-end", "documentation"] +createdAt: "2022-10-19T18:02:00.000Z" +--- diff --git a/src/content/references/fr/natureo.md b/src/content/references/fr/natureo.md new file mode 100644 index 0000000..4a42a10 --- /dev/null +++ b/src/content/references/fr/natureo.md @@ -0,0 +1,10 @@ +--- +title: Nature en Occitanie +subtitle: La sobriété au naturel. +url: https://www.natureo.org/ +lang: fr +slug: "natureo" +excerpt: Développement web et compagnie. +tags: ["Front-end", "accessibilité", "éco-conception", "CMS"] +createdAt: "2023-04-19T18:02:00.000Z" +--- diff --git a/src/content/references/fr/parole-expression.md b/src/content/references/fr/parole-expression.md new file mode 100644 index 0000000..29c3033 --- /dev/null +++ b/src/content/references/fr/parole-expression.md @@ -0,0 +1,10 @@ +--- +title: Parole Expression +subtitle: Un nouveau site pour l'association. +url: https://www.paroleexpression.fr/ +lang: fr +slug: "parole-expression" +excerpt: Développement web et compagnie. +tags: ["Front-end", "éco-conception", "CMS"] +createdAt: "2022-04-19T17:11:00.000Z" +--- diff --git a/src/content/references/fr/rose-primaire.md b/src/content/references/fr/rose-primaire.md new file mode 100644 index 0000000..328687c --- /dev/null +++ b/src/content/references/fr/rose-primaire.md @@ -0,0 +1,10 @@ +--- +title: Rose Primaire +subtitle: Une agence comme on l'aime. +url: https://roseprimaire.com/ +lang: fr +slug: "rose-primaire" +excerpt: Développement web et compagnie. +tags: ["Front-end", "accessibilité", "éco-conception", "CMS"] +createdAt: "2023-04-19T17:11:00.000Z" +--- diff --git a/src/data/HP/en/01-offre.md b/src/data/HP/en/01-offre.md index 2d5e0b6..45111cb 100644 --- a/src/data/HP/en/01-offre.md +++ b/src/data/HP/en/01-offre.md @@ -27,3 +27,5 @@ When the project is larger, I call on talented partners who share the same value - [Rose Primaire](https://roseprimaire.com/) for the monitoring and management of the project; - [Sylvain Plantier](https://jedessinebien.com/) and/or [Benoît Etchevery](http://ben-etche.com/) for illustration and art direction. + +[See some work here!](/en/work/) diff --git a/src/data/HP/fr/01-offre.md b/src/data/HP/fr/01-offre.md index 94b62d7..609ed82 100644 --- a/src/data/HP/fr/01-offre.md +++ b/src/data/HP/fr/01-offre.md @@ -27,3 +27,5 @@ Lorsque le projet est plus volumineux, je fais appel à des partenaires talentue - [Rose Primaire](https://roseprimaire.com/) pour le conseil et l'accompagnement du projet ; - [Sylvain Plantier](https://jedessinebien.com/) et/ou [Benoît Etchevery](http://ben-etche.com/) pour l'illustration et la direction artistique. + +[Consultez quelques références ici !](/references/) diff --git a/src/i18n/en.json b/src/i18n/en.json index e375dea..2cc44af 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -33,12 +33,11 @@ "titre": "snippets", "tagline": "School with Nicool." }, - "projet": { - "titre": "projects", - "tagline": "Freelance work", + "references": { + "titre": "work", + "slug": "work", "cta": "Visit website", - "lienTitle": "Website of", - "fenetre": "(new window)" + "tagline": "Some work." }, "erreur": { "introuvable": "Sorry, page not found.", @@ -50,13 +49,13 @@ "title": "Articles", "description": "A few articles about graphic design and front-end development." }, - "projet": { - "title": "Projects", - "description": "Some of my work as a freelance web designer and developer." - }, "code": { "title": "Snippets", "description": "Snippets of fresh, easy and accessible code." + }, + "references": { + "title": "Work", + "description": "A few case studies I worked on as a front-end developer." } } } diff --git a/src/i18n/fr.json b/src/i18n/fr.json index 665520f..a94e8a4 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -33,12 +33,11 @@ "titre": "fragments", "tagline": "Les tutos de Nico mdr." }, - "projet": { - "titre": "projets", - "tagline": "Mon travail en freelance", + "references": { + "titre": "références", + "slug": "references", "cta": "Consulter le site", - "lienTitle": "Site web de", - "fenetre": "(nouvelle fenêtre)" + "tagline": "Quelques références." }, "erreur": { "introuvable": "Page introuvable", @@ -48,15 +47,15 @@ "seo": { "article": { "title": "Articles", - "description": "Quelques articles en tant que graphiste et développeur front-end à Toulouse." - }, - "projet": { - "title": "Projets", - "description": "Mon travail en tant que graphiste et développeur front-end à Toulouse." + "description": "Quelques articles sur le développement web front-end et l'informatique à Toulouse." }, "code": { "title": "Fragments", "description": "Fragments de codes stylés, faciles et accessibles." + }, + "references": { + "title": "Références", + "description": "Quelques travaux réalisés en tant que et développeur web front-end à Toulouse." } } } diff --git a/src/pages/en/work/[slug].astro b/src/pages/en/work/[slug].astro new file mode 100644 index 0000000..8b5eda2 --- /dev/null +++ b/src/pages/en/work/[slug].astro @@ -0,0 +1,9 @@ +--- +import Page from "../../travaux/[slug].astro" + +export { getStaticPaths } from "../../travaux/[slug].astro" + +const { props } = Astro +--- + + \ No newline at end of file diff --git a/src/pages/en/work/index.astro b/src/pages/en/work/index.astro new file mode 100644 index 0000000..fe66bee --- /dev/null +++ b/src/pages/en/work/index.astro @@ -0,0 +1,7 @@ +--- +import Page from "../../references/index.astro" + +const { props } = Astro +--- + + \ No newline at end of file diff --git a/src/pages/references/i18n/en.json b/src/pages/references/i18n/en.json new file mode 100644 index 0000000..5105d00 --- /dev/null +++ b/src/pages/references/i18n/en.json @@ -0,0 +1,4 @@ +{ + "pageName": "Work", + "subtitle": "Some fine websites right here." +} diff --git a/src/pages/references/i18n/fr.json b/src/pages/references/i18n/fr.json new file mode 100644 index 0000000..e04ca6b --- /dev/null +++ b/src/pages/references/i18n/fr.json @@ -0,0 +1,4 @@ +{ + "pageName": "Références", + "subtitle": "Des sites web de qualité." +} diff --git a/src/pages/references/index.astro b/src/pages/references/index.astro new file mode 100644 index 0000000..c976dae --- /dev/null +++ b/src/pages/references/index.astro @@ -0,0 +1,44 @@ +--- +import { l, t, astroI18n } from "astro-i18n"; +astroI18n.init(Astro); + +// New astro content collections +import { getCollection } from "astro:content"; + +import BaseLayout from "../../layouts/BaseLayout.astro"; +import ListCards from "../../components/ListCards.astro"; + +const localizedPost = await getCollection("references", ({ data }) => { + return data.lang === astroI18n.langCode && !data.draft; +}); +// sort references by descending publication date +const sortedReferences = localizedPost.sort( + (a, b) => b.data.createdAt - a.data.createdAt +); + +const pageTitle = t("index.references.pageName"); +--- + + +
    +

    {t("index.references.pageName")}

    +

    {t("index.references.subtitle")}

    + +
    +
    + +