{"pageProps":{"locale":{"code":"fr","domain":"frenchstack.fr","lang":"fr-FR","json":{"TRANSLATE":"Traduire en","EN":"Anglais","FR":"Français","NO_TRANSLATION_AVAILABLE":"Aucune traduction disponible","PROFILE_OF":"Profil de","FILTER_BY_TAG":"Filtrer par tag","REMOVE_FILTER":"Supprimer le filtre","RESULT":"Résulat","RESULTS":"Résulats","FORM_CONTACT_SUPPORT":"Support","FORM_CONTACT_SALES":"Devis","FORM_CONTACT_BUGS":"Rapport de bug","FORM_LOADING":"Chargement","FORM_SEND":"Envoyer","FORM_VERIFY":"Vérifier","FORM_NAME":"Nom","FORM_TOPIC":"Sujet","FORM_PHONE":"Téléphone","FORM_EMAIL":"Email","FORM_MESSAGE":"Message","FORM_DOMAIN_PLACEHOLDER":"exemple.fr","FORM_DOMAIN_AVAILABLE":"Félicitations, le domaine <span data-selector='domain'></span> est disponible !","FORM_DOMAIN_TAKEN":"Désolé, le domaine <span data-selector='domain'></span> est pris.","SUBSCRIBE":"S'abonner","SUCCESS_CONTACT":"Votre message a bien été envoyé ! Nous vous répondrons dans les plus brefs délais.","SOMETING_WENT_WRONG":"Oops, une erreur s'est produite. Veuillez réessayer ultérieurement.","PERFORMANCE":"Performance","ACCESSIBILITY":"Accessibilité","BEST_PRACTICES":"Bonnes pratiques","SEO":"Référencement","MOBILE":"Mobile","TABLET":"Tablette","DESKTOP":"Ordinateur","VISITORS":"Visiteurs","ENGAGEMENT":"Engagement","CONVERSIONS":"Conversions","JAN":"Janv","FEB":"Févr","MAR":"Mars","APR":"Avr","MAY":"Mai","JUN":"Juin","JUL":"Juil","AUG":"Août","SEP":"Sept","OCT":"Oct","NOV":"Nov","DEC":"Déc","METHOD_PHONE":"Téléphone","METHOD_EMAIL":"Email","FOOTER_TAGLINE":"Nous créons des expériences numériques uniques pour les marques et les entreprises."},"subdomains":{"blog":"blog","clients":"references","videos":"videos","services":"services"},"ogSection":"Technologie"},"slugs":["fr","blog","fallow-codebase-intelligence-typescript"],"component":"article","article":{"id":"content/articles/fr/fallow-codebase-intelligence-typescript.mdx","heroSection":{"heroTitle":"Fallow : la qualité de code au rythme des agents IA","heroSubtitle":"Retour d'expérience sur un garde-fou déterministe","heroBadge":"","heroColoredWords":"1","heroBreakTitle":"","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Comment un analyseur statique en Rust guide nos agents IA pour transformer de longues fonctions en petites étapes claires, nommées et faciles à faire évoluer."}]}]},"heroSubtitleIsInline":false,"heroHasBackground":false,"heroImage":"/images/code-laptop.png","heroVideoBackground":"","heroStyle":{"heroBg":"","heroMaxWidth":"","heroMs":"","heroTitleMb":"","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"","navbarBorderColor":"","navbarLinkActive":"","navbarLinkHover":""},"imageAlt":"code laptop","imageWidth":5184,"imageHeight":3456},"seoSection":{"metaTitle":"Fallow et agents IA : retour d'expérience sur la qualité de code","metaDescription":"Retour d'expérience : Fallow, analyseur statique TypeScript en Rust, sert de garde-fou à nos agents IA et les guide pour découper les fonctions complexes en étapes claires et bien nommées.","metaTags":"Fallow, TypeScript, agent IA, qualité de code, complexité cognitive, refactoring, Claude Code, Codex, analyse statique","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2026-10-17T21:00:00.000Z","localeCode":"fr","slug":"fallow-codebase-intelligence-typescript","url":"/fr/blog/fallow-codebase-intelligence-typescript","ogId":"fallow-codebase-intelligence-typescript-blog-fr","ogImagePath":"/og/fallow-codebase-intelligence-typescript-blog-fr.png","type":"Article","title":"Fallow : la qualité de code au rythme des agents IA","subtitle":"Retour d'expérience sur un garde-fou déterministe pour TypeScript","browserUrl":"","textPreview":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Fallow mesure la complexité, le code mort et la duplication de nos projets TypeScript. Branché sur nos agents IA, il transforme chaque commit en occasion de découper une fonction trop longue en petites étapes bien nommées."}]}]},"subdomainKey":"blog","subdomain":"blog","draft":true,"logoAlt":"","logoWidth":0,"logoHeight":0,"icon":"code","body":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Les agents IA de développement écrivent désormais une large part du code de nos projets. Ils livrent vite et bien, mais ils ont une tendance naturelle : "},{"type":"text","text":"enrichir la fonction existante","bold":true},{"type":"text","text":" plutôt que de créer un nouveau concept. Au fil des demandes, une fonction de vingt lignes en compte cent, et son nom ne décrit plus qu'une partie de ce qu'elle fait."}]},{"type":"p","children":[{"type":"text","text":"Cet article présente la manière dont nous utilisons "},{"type":"text","text":"Fallow","bold":true},{"type":"text","text":" pour cadrer nos agents, et ce que cet outil a changé dans la forme même du code produit."}]},{"type":"hr","children":[{"type":"text","text":""}]},{"type":"h2","children":[{"type":"text","text":"1. Fallow en bref"}]},{"type":"p","children":[{"type":"a","url":"https://fallow.tools","title":"Fallow - Codebase intelligence","children":[{"type":"text","text":"Fallow"}]},{"type":"text","text":" est un analyseur statique pour "},{"type":"text","text":"TypeScript et JavaScript","bold":true},{"type":"text","text":", distribué sous la forme d'un binaire Rust unique. Il construit un graphe complet du dépôt (modules, exports, dépendances, fonctions) et en tire plusieurs analyses complémentaires :"}]},{"type":"ul","children":[{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Complexité","bold":true},{"type":"text","text":" : Mesure de la complexité cyclomatique et cognitive de chaque fonction, de sa taille et d'un score de santé global sur 100."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Code mort","bold":true},{"type":"text","text":" : Détection des fichiers, exports, types et dépendances que plus rien n'utilise."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Duplication","bold":true},{"type":"text","text":" : Repérage des blocs copiés entre fichiers, y compris dans le CSS et les composants Vue, Svelte ou Astro."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Architecture","bold":true},{"type":"text","text":" : Contrôle des frontières entre couches et des dépendances circulaires."}]}]}]},{"type":"mdxJsxFlowElement","name":"callout","children":[{"type":"text","text":""}],"props":{"title":"Un analyseur sans IA","variant":"info","content":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Fallow n'embarque "},{"type":"text","text":"aucun modèle de langage","bold":true},{"type":"text","text":" dans son analyseur : la même entrée produit toujours le même résultat. Il ne requiert ni compilateur TypeScript ni runtime Node.js, et analyse le monorepo de Next.js ("},{"type":"text","text":"20 558 fichiers","bold":true},{"type":"text","text":") en "},{"type":"text","text":"2,95 secondes","bold":true},{"type":"text","text":" selon les mesures publiées par le projet."}]},{"type":"p","children":[{"type":"text","text":"C'est précisément ce déterminisme qui en fait un bon partenaire pour un agent IA : l'agent propose, Fallow mesure."}]}]}}},{"type":"hr","children":[{"type":"text","text":""}]},{"type":"h2","children":[{"type":"text","text":"2. Un garde-fou dans la boucle de l'agent"}]},{"type":"p","children":[{"type":"text","text":"Au rythme des agents, chaque ligne n'est plus relue une à une, et demander « d'écrire du code simple » reste une intention : sans mesure, l'agent n'a aucun moyen de savoir s'il l'a atteinte."}]},{"type":"p","children":[{"type":"text","text":"Fallow devient le garde-fou de chaque commit."}]},{"type":"p","children":[{"type":"text","text":"La règle est inscrite dans le fichier "},{"type":"text","text":"AGENTS.md","code":true},{"type":"text","text":" lu par nos agents au début de chaque session. À la fin de chaque tâche, l'agent suit une boucle courte :"}]},{"type":"ol","children":[{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Développement","bold":true},{"type":"text","text":" : Implémentation de la fonctionnalité demandée, sans contrainte particulière."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Mesure","bold":true},{"type":"text","text":" : Lancement de Fallow, qui signale chaque fonction trop complexe, chaque export inutile et chaque bloc dupliqué."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Découpage","bold":true},{"type":"text","text":" : Traitement des signalements, en commençant par les fonctions critiques."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Validation","bold":true},{"type":"text","text":" : Nouvelle analyse jusqu'au vert, puis commit."}]}]}]},{"type":"p","children":[{"type":"text","text":"La mise en place tient en deux commandes :"}]},{"type":"code_block","lang":"bash","value":"# Configurer les agents du projet (skills, serveur MCP, garde-fou sur git commit)\nnpx fallow agent install\n\n# Ce que l'agent lance avant chaque commit\nnpx fallow health --format json --quiet","children":[{"type":"text","text":""}]},{"type":"p","children":[{"type":"text","text":"Les seuils sont ceux de Fallow par défaut : "},{"type":"text","text":"20","bold":true},{"type":"text","text":" de complexité cyclomatique, "},{"type":"text","text":"15","bold":true},{"type":"text","text":" de complexité cognitive et "},{"type":"text","text":"60 lignes","bold":true},{"type":"text","text":" par fonction. Fallow ne dit pas comment corriger : il signale ce qui est trop long, trop imbriqué ou répété, et laisse à l'agent le soin de "},{"type":"text","text":"découper","bold":true},{"type":"text","text":"."}]},{"type":"hr","children":[{"type":"text","text":""}]},{"type":"h2","children":[{"type":"text","text":"3. Retour d'expérience : un bot de réservation"}]},{"type":"p","children":[{"type":"text","text":"Le cas le plus parlant est celui d'un petit bot interne en "},{"type":"text","text":"TypeScript","bold":true},{"type":"text","text":" qui réserve automatiquement des séances de sport, dont les places partent en quelques minutes. Écrit à la main, il a ensuite été confié à un agent IA pour l'intégrer à "},{"type":"text","text":"Home Assistant","bold":true},{"type":"text","text":" : tableau de bord, interrupteurs par jour et notifications sur le téléphone."}]},{"type":"p","children":[{"type":"text","text":"L'agent a livré vite et tout fonctionnait, mais chaque demande avait atterri dans la fonction existante. La réservation tenait en une seule fonction qui se connectait à l'API, lisait le planning, choisissait le créneau puis réservait."}]},{"type":"p","children":[{"type":"text","text":"Une fois Fallow branché, l'agent n'a pas coupé au hasard pour faire baisser un chiffre : il a isolé chaque "},{"type":"text","text":"étape métier","bold":true},{"type":"text","text":" dans une fonction dédiée et lui a donné un nom qui dit exactement ce qu'elle fait. Le schéma ci-dessous montre la fonction de réservation avant et après. Survolez une étape pour voir où elle se cachait dans la fonction d'origine :"}]},{"type":"mdxJsxFlowElement","name":"functionSplit","children":[{"type":"text","text":""}],"props":{"name":"tryReserve","caption":"88 lignes où la connexion, le planning, le choix du créneau et la réservation s'entremêlent.","label":"découpé par l'agent","parts":[{"name":"getAuthAndBooked","params":"config","comment":"se connecter et lister mes réservations","weight":5},{"name":"getSessions","params":"planning","comment":"ne garder que les séances","weight":3},{"name":"pickLatestPerWeek","params":"sessions","comment":"le dernier créneau du jour, semaine par semaine","weight":4},{"name":"tryBookSession","params":"session","comment":"vérifier les places, puis réserver","weight":7}],"result":"La fonction principale passe de 88 à 28 lignes et se lit désormais comme une recette."}},{"type":"p","children":[{"type":"text","text":"Le même mouvement s'est répété sur tout le projet : l'envoi des notifications, écrit trois fois, n'existe plus qu'à un seul endroit sous le nom "},{"type":"text","text":"notifyBookingSuccess","code":true},{"type":"text","text":", et l'interface est passée d'un fichier de "},{"type":"text","text":"501 lignes","bold":true},{"type":"text","text":" à "},{"type":"text","text":"sept composants","bold":true},{"type":"text","text":" réutilisables."}]},{"type":"mdxJsxFlowElement","name":"callout","children":[{"type":"text","text":""}],"props":{"title":"Pourquoi les noms s'améliorent","variant":"success","content":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Une fonction de cent lignes peut porter un nom vague, car personne ne lit son nom pour comprendre ce qu'elle fait. Une fonction de dix lignes doit être nommée avec précision, sans quoi le code qui l'appelle devient illisible. En imposant des fonctions courtes, Fallow oblige l'agent à "},{"type":"text","text":"nommer chaque responsabilité","bold":true},{"type":"text","text":"."}]}]}}},{"type":"hr","children":[{"type":"text","text":""}]},{"type":"h2","children":[{"type":"text","text":"4. Ce que cela change au quotidien"}]},{"type":"p","children":[{"type":"text","text":"Fallow est désormais actif sur l'ensemble de nos applications TypeScript. Ses effets se ressentent à chaque étape du travail :"}]},{"type":"ul","children":[{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Lecture","bold":true},{"type":"text","text":" : Une fonction se comprend en lisant les noms des fonctions qu'elle appelle, sans entrer dans leur détail."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Évolution","bold":true},{"type":"text","text":" : Un nouveau cas prend la forme d'une nouvelle fonction nommée, au lieu d'une branche de plus dans une fonction déjà chargée."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Contexte des agents","bold":true},{"type":"text","text":" : Un agent qui reprend le projet lit moins de code, les noms le guidant directement vers le bon fichier."}]}]}]},{"type":"mdxJsxFlowElement","name":"callout","children":[{"type":"text","text":""}],"props":{"title":"Points d'attention","variant":"warning","content":{"type":"root","children":[{"type":"ul","children":[{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Configurer les points d'entrée","bold":true},{"type":"text","text":" : Sans déclaration des fichiers d'entrée et des dépendances chargées dynamiquement, Fallow signale à tort du code utilisé comme mort."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Relire les noms","bold":true},{"type":"text","text":" : L'agent découpe bien, mais un nom reste un choix de conception ; un coup d'œil humain garde la cohérence du vocabulaire."}]}]},{"type":"li","children":[{"type":"lic","children":[{"type":"text","text":"Adopter progressivement","bold":true},{"type":"text","text":" : Sur un projet existant, "},{"type":"text","text":"fallow audit","code":true},{"type":"text","text":" ne bloque que les problèmes introduits par la modification en cours."}]}]}]}]}}},{"type":"hr","children":[{"type":"text","text":""}]},{"type":"h2","children":[{"type":"text","text":"5. Conclusion"}]},{"type":"p","children":[{"type":"text","text":"Fallow n'écrit pas le code à la place de l'agent : il lui fixe un cadre mesurable, et ce cadre suffit à faire émerger la structure qu'un architecte logiciel aurait proposée. Associé à nos agents IA, il nous permet de livrer vite tout en gardant un code que nous savons "},{"type":"text","text":"lire, maintenir et faire évoluer","bold":true},{"type":"text","text":"."}]},{"type":"mdxJsxFlowElement","name":"buttons","children":[{"type":"text","text":""}],"props":{"buttons":[{"icon":"gitHub","label":"Fallow sur GitHub","link":"https://github.com/fallow-rs/fallow","style":"primary"},{"icon":"codeFile","label":"Documentation","link":"https://fallow.tools/docs","style":"light"}]}}]},"dateCreate":"2026-08-26T09:00:00.000Z","dateUpdate":"2026-10-17T21:00:00.000Z","author":{"id":"content/authors/fr/nicolas-roehm-bettcher.mdx","heroSection":{"heroTitle":"Nicolas Roehm","heroSubtitle":"Ingénieur logiciel","heroBadge":"","heroColoredWords":"","heroBreakTitle":"","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Fondateur de French Stack, je conçois des solutions informatiques complètes."}]},{"type":"p","children":[{"type":"text","text":"Développeur full-stack, j'interviens principalement sur des projets frontend avec Angular, React ou Vue."}]},{"type":"p","children":[{"type":"text","text":"Passionné de design, voici quelques-unes de mes "},{"type":"a","url":"https://www.artstation.com/nicolas-roehm","title":"ArtStation - Nicolas Roehm","children":[{"type":"text","text":"conceptions graphiques"}]},{"type":"text","text":"."}]},{"type":"mdxJsxFlowElement","name":"socialLinks","children":[{"type":"text","text":""}],"props":{"links":[{"icon":"gitHub","link":"https://github.com/NicolasRoehm"},{"icon":"stackOverflow","link":"https://stackoverflow.com/users/7462178/nicolas-roehm?tab=profile"},{"icon":"linkedIn","link":"https://fr.linkedin.com/in/nicolas-roehm-bettcher"}]}}]},"heroSubtitleIsInline":true,"heroHasBackground":false,"heroImage":"/images/nicolas-roehm-bettcher.png","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(312deg, #0800ff 0%, #4300ff00 70%)","heroMaxWidth":"","heroMs":"25%","heroTitleMb":"0.5rem","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"#fff0","navbarBorderColor":"","navbarLinkActive":"#6785be","navbarLinkHover":"#6785be"},"imageAlt":"nicolas roehm bettcher","imageWidth":0,"imageHeight":0},"seoSection":{"metaTitle":"Nicolas Roehm, Ingénieur logiciel","metaDescription":"Passionné d'informatique, je conçois des sites web dans leur intégralité : design, developpement, référencement, e-reputation, e-mailling, hébergement","metaTags":"Nicolas Roehm, Ingénieur logiciel, web, mobile, site internet","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-09T00:38:50.025Z","localeCode":"fr","slug":"nicolas-roehm-bettcher","url":"/fr/nicolas-roehm-bettcher","ogId":"nicolas-roehm-bettcher-fr","ogImagePath":"/og/nicolas-roehm-bettcher-fr.png","type":"Author","title":"Nicolas Roehm-Bettcher","avatar":"/images/nicolas-roehm-avatar.png","lname":"Roehm","fname":"Nicolas","name":"Nicolas Roehm","translations":[{"localeCode":"en","title":"Nicolas Roehm-Bettcher","slug":"nicolas-roehm-bettcher","url":"/en/nicolas-roehm-bettcher"}]},"translations":[],"tags":[{"id":"content/tags/fr/typescript.mdx","localeCode":"fr","title":"TypeScript","slug":"typescript","url":"/fr/blog/typescript"}]},"page":{"id":"content/subdomains/fr/blog.mdx","heroSection":{"heroTitle":"Actualités digitales","heroSubtitle":"","heroBadge":"","heroColoredWords":"2","heroBreakTitle":"","heroShape":"shiny","heroGradient":"business-gradient","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Explorez les dernières avancées en "},{"type":"text","text":"design web","bold":true},{"type":"text","text":", "},{"type":"text","text":"SEO","bold":true},{"type":"text","text":", "},{"type":"text","text":"marketing digital","bold":true},{"type":"text","text":", "},{"type":"text","text":"développement web","bold":true},{"type":"text","text":" et bien plus."}]},{"type":"p","children":[{"type":"text","text":"Nos articles décryptent les "},{"type":"text","text":"technologies innovantes","bold":true},{"type":"text","text":" et les "},{"type":"text","text":"standards du web","bold":true},{"type":"text","text":" qui façonnent l'"},{"type":"text","text":"avenir du numérique","bold":true},{"type":"text","text":"."}]},{"type":"p","children":[{"type":"text","text":"Restez connecté, suivez-nous sur les "},{"type":"text","text":"réseaux sociaux","bold":true},{"type":"text","text":"."}]}]},"heroSubtitleIsInline":false,"heroHasBackground":false,"heroImage":"/images/blog-news-web.jpg","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(353deg, rgba(255,129,0,0.64) 0%, #0018ffe0 120%)","heroMaxWidth":"","heroMs":"","heroTitleMb":"","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"","navbarBorderColor":"","navbarLinkActive":"","navbarLinkHover":""},"imageAlt":"blog news web","imageWidth":0,"imageHeight":0},"seoSection":{"metaTitle":"Actualité numérique","metaDescription":"Magazine en ligne pour apprendre le Web, trouver des ressources, parcourir les tendances et déguster un café chaud","metaTags":"inspiration web, tutoriels développement web, tendances web","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-12T18:23:51.381Z","localeCode":"fr","slug":"blog","url":"/fr/blog","ogId":"blog-fr","ogImagePath":"/og/blog-fr.png","type":"Subdomain","title":"Blog","subdomainKey":"blog","subdomain":"blog","translations":[{"localeCode":"en","title":"Blog","slug":"blog","url":"/en/blog"}],"canShare":true,"canComment":true,"hasAuthor":true,"tagsInPanel":true,"cardContainer":"col-md-6","cardTemplate":"default"},"neighbors":[null,null],"global":{"id":"content/global/fr/settings.json","localeCode":"fr","header":{"nav":[{"href":"index","label":"Accueil"},{"href":"blog","label":"Blog"},{"href":"videos","label":"Vidéos"},{"href":"services","label":"Prestations"},{"href":"references","label":"Références"},{"href":"a-propos","label":"À propos"},{"href":"contact","label":"Contact"}]},"footer":{"social":[{"website":"x","account":"RoehmNicolas"},{"website":"instagram","account":"roehm.nicolas"},{"website":"facebook","account":"thefrenchstack"},{"website":"youtube","account":"@frenchstack"}],"hasSocial":true,"nav":[{"title":"L'agence","links":[{"href":"references","label":"Références"},{"href":"a-propos","label":"À propos"},{"href":"contact","label":"Contact"}]},{"title":"Prestations","links":[{"href":"services/creation-graphique","label":"Graphisme"},{"href":"services/developpement-web-mobile","label":"Développement"},{"href":"services/marketing-web","label":"Marketing"},{"href":"services/formation-informatique","label":"Formation"}]},{"title":"Blog","links":[{"href":"blog/angular","label":"Angular"},{"href":"blog/jquery","label":"jQuery"}]},{"title":"Vidéos","links":[{"href":"videos/marketing-audiovisuel","label":"Marketing audiovisuel"}]}]},"bottom":{"dateCreate":"2015-12-27T05:55:00.000Z","nav":[{"href":"mentions-legales","label":"Mentions légales"},{"href":"politique-de-confidentialite","label":"Politique de confidentialité"}],"hasLinks":true},"contactInfo":{"contactMethods":[{"id":"email","icon":"envelope","value":"frenchstack@gmail.com"},{"id":"phone","icon":"phone","value":"0651570751"}]}}},"__N_SSG":true}