% Author     : C. Pierquet
% licence    : Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txtf
%            : Luatruthtable from Chetan Shirore and Dr. Ajit Kumar https://ctan.org/pkg/luatruthtable

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ProfSio}[2023/08/23 0.1.4 Pour les enseignants en BTS SIO]
%0.1.4	Possibilité de remplir une table de Karnaugh sans virgule
%0.1.3	Style alternatif et Clé [PoliceTT] pour les tables de Karnaugh
%0.1.2	Ajout d'une option [Offset] pour les diagrammes sagittaux + Diagrammes sagittaux de composée + Tables de vérité
%0.1.1	Correction de la documentation + Ajout des diagrammes sagittaux
%0.1.0	Version initiale

%------Packages utiles
\RequirePackage{iftex}
\RequirePackage{tikz,pgffor}
\RequirePackage{tabularray}
\RequirePackage{simplekv}
\RequirePackage{xstring}
\RequirePackage{listofitems}
\RequirePackage{xintexpr}
%------Librairies
\usetikzlibrary{positioning,decorations.pathreplacing,decorations.markings,arrows,arrows.meta,calc,babel,shapes,shapes.geometric}

%------Graphe MPM
\defKV[MPM]{%
	CouleurDurees=\def\MPMCoulDuree{#1},%
	CouleurFleches=\def\MPMCoulFleche{#1},%
	LargeurCases=\def\MPMLargBoite{#1},%
	Epaisseur=\def\MPMThick{#1},%
	Police=\def\MPMFont{#1},%
	CouleurDates=\def\MPMCoulDates{#1},%
	CouleurBords=\def\MPMCoulTraits{#1},%
	Grille=\def\MPMGrille{#1}
}

\setKVdefault[MPM]{%
	CouleurDurees=purple,
	CouleurFleches=blue,%
	LargeurCases=0.75cm,%
	Epaisseur=0.75pt,%
	Police=\footnotesize\sffamily,%
	CouleurDates=teal/red,%
	CouleurBords=black,%
	NoirBlanc=false,%
	Grille={}
}

\NewTblrEnviron{MPMtache}
\SetTblrInner[MPMtache]{rowsep=1pt,colsep=1pt,colspec={Q[\MPMLargBoite,m,c]Q[\MPMLargBoite,m,c]},cells={font=\MPMFont},row{1}={font=\bfseries\MPMFont}}

\tikzset{
	pics/MPM/.style args={nom=#1,t=#2,T=#3}{%1=nom noeud,2=t,3=T
		code = {
			\node[inner sep=0pt,outer sep=0pt] (#1) at (0,0) {
				\begin{MPMtache}{hlines={wd=\MPMThick,fg=\MPMCoulTraits},vlines={wd=\MPMThick,fg=\MPMCoulTraits}}
					\SetCell[c=2]{c} {#1} & \\
					\textcolor{\MPMCoulDatet}{#2} & \textcolor{\MPMCoulDateT}{#3} \\
				\end{MPMtache}};
		}
	},
	pics/MPMcomplet/.style args={nom=#1,t=#2,T=#3,MT=#4,ML=#5}{%1=nom noeud/2=t/3=T/4=MT/5=ML
		code = {
			\node[inner sep=0pt,outer sep=0pt] (#1) at (0,0) {
				\begin{MPMtache}{hlines={wd=\MPMThick,fg=\MPMCoulTraits},vlines={wd=\MPMThick,fg=\MPMCoulTraits}}
					\SetCell[c=2]{c} {#1} & \\
					\textcolor{\MPMCoulDatet}{#2} & \textcolor{\MPMCoulDateT}{#3} \\
					#4 & #5 \\
			\end{MPMtache}};
		}
	},%
	pics/MPMnotice/.style={%
		code = {
			\node[inner sep=0pt,outer sep=0pt] (Notice) at (0,0) {
				\begin{MPMtache}{hline{2-Z}={wd=\MPMThick,fg=\MPMCoulTraits},vlines={2-Z}{wd=\MPMThick,fg=\MPMCoulTraits}}
					\SetCell[c=2]{c} \textcolor{violet}{Aide} & \\
					\SetCell[c=2]{c} \textbf{Som.} & \\
					\textcolor{\MPMCoulDatet}{t} & \textcolor{\MPMCoulDateT}{T} \\
			\end{MPMtache}};
		}
	},%
	pics/MPMnoticecomplet/.style={%
		code = {
			\node[inner sep=0pt,outer sep=0pt] (Notice) at (0,0) {
				\begin{MPMtache}{hline{2-Z}={wd=\MPMThick,fg=\MPMCoulTraits},vlines={2-Z}{wd=\MPMThick,fg=\MPMCoulTraits}}
					\SetCell[c=2]{c} \textcolor{violet}{Aide} & \\
					\SetCell[c=2]{c} {Som.} & \\
					\textcolor{\MPMCoulDatet}{t} & \textcolor{\MPMCoulDateT}{T} \\
					MT & ML \\
			\end{MPMtache}};
		}
	},%
	dureeMPM/.style={circle,draw=none,fill=white,inner sep=1pt,font=\MPMFont,text=\MPMCoulDuree},
	arcMPM/.style={\MPMCoulFleche,->,>=latex,line width=\MPMThick,line cap=round}
}


\NewDocumentCommand\MPMPlaceTache{ r() r() r() }{%
	\StrCount{#3}{,}[\MPMtmpType]
	\xintifboolexpr{\MPMtmpType == 1 }%si il n'y a que 2 dates...
		{%
			\StrCut{#3}{,}{\MPMtmpt}{\MPMtmpT}%
			\pic at (#1) {MPM={nom=#2,t=\MPMtmpt,T=\MPMtmpT}} ;
		}%
		{%
			\StrBefore[1]{#3}{,}[\MPMtmpt]%
			\StrBetween[1,2]{#3}{,}{,}[\MPMtmpT]%
			\StrBetween[2,3]{#3}{,}{,}[\MPMtmpMT]%
			\StrBehind[3]{#3}{,}[\MPMtmpML]%
			\pic at (#1) {MPMcomplet={nom=#2,t=\MPMtmpt,T=\MPMtmpT,MT=\MPMtmpMT,ML=\MPMtmpML}} ;
		}%
}

\NewDocumentCommand\MPMPlaceTaches{ m }{%
	\setsepchar[.]{/}%
	\readlist*\MPMListeTaches{#1}%
	\foreach \i in {1,2,...,\MPMListeTacheslen}%
		{%
			\itemtomacro\MPMListeTaches[\i]{\MPMtmpData}%
			\StrBetween[1,1]{\MPMtmpData}{(}{)}[\MPMtmpCoord]%
			\StrBetween[2,2]{\MPMtmpData}{(}{)}[\MPMtmpTache]%
			\StrBetween[3,3]{\MPMtmpData}{(}{)}[\MPMtmpDates]%
			\MPMPlaceTache(\MPMtmpCoord)(\MPMtmpTache)(\MPMtmpDates)
		}%
}

\NewDocumentCommand\MPMPlaceNotice{ s r() }{%
	\IfBooleanTF{#1}%
		{%
			\pic at (#2) {MPMnoticecomplet} ;
		}%
		{%
			\pic at (#2) {MPMnotice} ;
		}%
}

\defKV[MPMarc]{%
	DecalHorizDeb=\def\MPMOffsetHInit{#1},%
	DecalVertDeb=\def\MPMOffsetVInit{#1},%
	DecalHorizFin=\def\MPMOffsetHFin{#1},%
	DecalVertFin=\def\MPMOffsetVFin{#1},%
	SensCoude=\def\MPMOrientation{#1},%
	HauteurCoude=\def\MPMHautCoude{#1}
}

\setKVdefault[MPMarc]{%
	DecalHorizDeb=0pt,%
	DecalVertDeb=0pt,%
	DecalHorizFin=0pt,%
	DecalVertFin=0pt,%
	Coude=false,%
	SensCoude=HV,%
	HauteurCoude=10pt
}

\NewDocumentCommand\MPMPlaceDuree{ O{} m D<>{midway}}{%
	\useKVdefault[MPMarc]%
	\setKV[MPMarc]{#1}%
	\StrBefore{#2}{>}[\MPMSommetDep]%
	\StrBetween{#2}{>}{,}[\MPMSommetFin]%
	\StrBehind{#2}{,}[\MPMduree]%
	\ifboolKV[MPMarc]{Coude}%
		{%
			\IfStrEq{\MPMOrientation}{HV}%
				{%
					\draw[arcMPM] ([xshift=\MPMOffsetHInit,yshift=\MPMOffsetVInit]\MPMSommetDep) -| ([xshift=\MPMOffsetHFin,yshift=\MPMOffsetVFin]\MPMSommetFin) node[dureeMPM,#3] {\MPMduree} ;
				}{}%
			\IfStrEq{\MPMOrientation}{VH}%
				{%
					\draw[arcMPM] ([xshift=\MPMOffsetHInit,yshift=\MPMOffsetVInit]\MPMSommetDep) |- ([xshift=\MPMOffsetHFin,yshift=\MPMOffsetVFin]\MPMSommetFin) node[dureeMPM,#3] {\MPMduree} ;
				}{}%
			\IfStrEq{\MPMOrientation}{VHV}%
				{%
					\draw[arcMPM] ([xshift=\MPMOffsetHInit,yshift=\MPMOffsetVInit]\MPMSommetDep)--++(0,{-\MPMHautCoude}) -| ([xshift=\MPMOffsetHFin,yshift=\MPMOffsetVFin]\MPMSommetFin) node[dureeMPM,#3] {\MPMduree} ;
				}{}%
		}%
		{%
			\draw[arcMPM] ([xshift=\MPMOffsetHInit,yshift=\MPMOffsetVInit]\MPMSommetDep) -- ([xshift=\MPMOffsetHFin,yshift=\MPMOffsetVFin]\MPMSommetFin) node[dureeMPM,#3] {\MPMduree} ;
		}%
}

\NewDocumentCommand\MPMPlaceDurees{ O{} m D<>{midway} }{%
	\setsepchar[.]{/}*
	\readlist*\KGHListeDurees{#2}%
	\foreachitem\dureetache\in\KGHListeDurees{%
		\MPMPlaceDuree[#1]{\dureetache}<#3>%
	}
}

\NewDocumentEnvironment{GrapheMPM}{ O{} D<>{} }%
{%
	\useKVdefault[MPM]%
	\setKV[MPM]{#1}%
	\ifboolKV[MPM]{NoirBlanc}%
		{%
			\def\MPMCoulDuree{black}%
			\def\MPMCoulFleche{black}%
			\def\MPMCoulDates{black}%
			\def\MPMCoulTraits{black}
		}{}%
	\IfSubStr{\MPMCoulDates}{/}%
		{%
			\StrCut{\MPMCoulDates}{/}{\MPMCoulDatet}{\MPMCoulDateT}%
		}%
		{%
			\xdef\MPMCoulDatet{\MPMCoulDates}\xdef\MPMCoulDateT{\MPMCoulDates}
		}%
	\begin{tikzpicture}[#2]
		\IfStrEq{\MPMGrille}{}%
			{}%
			{%
				\StrCut{\MPMGrille}{,}{\MPMGrilleX}{\MPMGrilleY}%
				\draw[thin,dotted,lightgray,xstep=0.5,ystep=0.5] (0,0) grid (\MPMGrille) ;
				\draw[thin,lightgray,xstep=1,ystep=1] (0,0) grid (\MPMGrille) ;
				\foreach \x in {0,0.5,...,\MPMGrilleX} {\draw[thin,lightgray] (\x,0)--++(0,-2pt) node[below,inner sep=1pt,font=\sffamily\tiny] {\x} ;}
				\foreach \y in {0,0.5,...,\MPMGrilleY} {\draw[thin,lightgray] (0,\y)--++(-2pt,0) node[left,inner sep=1pt,font=\sffamily\tiny] {\y} ;}
				\filldraw[lightgray] (0,0) circle[radius=1.5pt] ;
			}%
}%
{%
	\end{tikzpicture}
}

%------Karnaugh (3 variables)
\defKV[tblkgh]{%
	Unite=\def\KGHTechelle{#1},%
	Variables=\def\KGHTvariables{#1},%
	Epaisseur=\def\KGHThick{#1},%
	CouleurCases=\def\KGHTCoulCases{#1},%
	Couleur=\def\KGHTCoul{#1},%
	PosVarLaterale=\def\KGHTPosVarA{#1},%
	CouleurLegende=\def\KGHTCoulLegende{#1}
}

\setKVdefault[tblkgh]{%
	Unite=1cm,%
	Variables=a/b/c,%
	Swap=false,%
	Aide=false,%
	Epaisseur=0.75pt,%
	CouleurCases=lightgray,%
	Legende=true,%
	Couleur=black,%
	PosVarLaterale=Gauche,%
	CouleurLegende=black,
	StyleAlternatif=false,%
	AideAlt=true,%
	PoliceTT=false
}

\NewDocumentEnvironment{TableKarnaugh}{ O{} D<>{} }%
{%
	\useKVdefault[tblkgh]%
	\setKV[tblkgh]{#1}%
	\setsepchar[.]{/}%
	\readlist*\ListeVariablesKGH\KGHTvariables%
	\IfSubStr{\KGHTCoulLegende}{/}%
		{%
			\StrBefore[1]{\KGHTCoulLegende}{/}[\KGHTCoulLegendeA]%
			\StrBetween[1,2]{\KGHTCoulLegende}{/}{/}[\KGHTCoulLegendeB]%
			\StrBehind[2]{\KGHTCoulLegende}{/}[\KGHTCoulLegendeC]%
		}%
		{%
			\def\KGHTCoulLegendeA{\KGHTCoulLegende}%
			\def\KGHTCoulLegendeB{\KGHTCoulLegende}%
			\def\KGHTCoulLegendeC{\KGHTCoulLegende}%
		}%
	\begin{tikzpicture}[x=\KGHTechelle,y=\KGHTechelle,line join=miter,#2]
		\coordinate (A00) at (0,0) ; \coordinate (A10) at (1,0) ;
		\coordinate (A20) at (2,0) ; \coordinate (A30) at (3,0) ;
		\coordinate (A40) at (4,0) ; \coordinate (A01) at (0,1) ;
		\coordinate (A11) at (1,1) ; \coordinate (A21) at (2,1) ;
		\coordinate (A31) at (3,1) ; \coordinate (A41) at (4,1) ;
		\coordinate (A02) at (0,2) ; \coordinate (A12) at (1,2) ;
		\coordinate (A22) at (2,2) ; \coordinate (A32) at (3,2) ;
		\coordinate (A42) at (4,2) ;
		\ifboolKV[tblkgh]{StyleAlternatif}%
			{
				\draw[line width=\KGHThick,\KGHTCoul] (A02)--++({-0.5*sqrt(2)},{0.5*sqrt(2)}) ;
				\ifboolKV[tblkgh]{Legende}
					{% 
						\draw[\KGHTCoulLegendeC,line width=\KGHThick] (-7pt,0)--++(0,1) node[midway,left=3pt,inner sep=1pt,text=\KGHTCoulLegendeC,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[3]}$}{$\strut{\ListeVariablesKGH[3]}$} } ;
						\draw[\KGHTCoulLegendeA,line width=\KGHThick] ($(A22)+(0,7pt)$)--++(2,0) node[midway,above,inner sep=1pt,text=\KGHTCoulLegendeA,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[1]}$}{$\strut{\ListeVariablesKGH[1]}$} } ;
						\draw[\KGHTCoulLegendeB,line width=\KGHThick] ($(A10)+(0,-7pt)$)--++(2,0) node[midway,below,inner sep=1pt,text=\KGHTCoulLegendeB,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[2]}$}{$\strut{\ListeVariablesKGH[2]}$} } ;
						\draw ($({-0.25*sqrt(2)},{2+0.25*sqrt(2)})+(-135:10pt)$) node[inner sep=1pt,text=\KGHTCoulLegendeC,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[3]}$}{$\strut{\ListeVariablesKGH[3]}$} } ;
						\draw ($({-0.25*sqrt(2)},{2+0.25*sqrt(2)})+(45:10pt)$) node[inner sep=1pt,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\mathcolor{\KGHTCoulLegendeA}{\ListeVariablesKGH[1]}\mathcolor{\KGHTCoulLegendeB}{\ListeVariablesKGH[2]}}$}{$\strut{\mathcolor{\KGHTCoulLegendeA}{\ListeVariablesKGH[1]}\mathcolor{\KGHTCoulLegendeB}{\ListeVariablesKGH[2]}}$} } ;
					}%
					{}%
			}%
			{%
				\ifboolKV[tblkgh]{Legende}
					{%
						\draw[\KGHTCoulLegendeB,line width=\KGHThick,decorate,decoration={brace,amplitude=7pt}](0,2.1)--(2,2.1) node[midway,above=7pt,inner sep=1pt,text=\KGHTCoulLegendeB,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[2]}$}{$\strut{\ListeVariablesKGH[2]}$} };
						\draw[\KGHTCoulLegendeB,line width=\KGHThick,decorate,decoration={brace,amplitude=7pt}](2,2.1)--(4,2.1) node[midway,above=7pt,inner sep=1pt,text=\KGHTCoulLegendeB,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\overline{\ListeVariablesKGH[2]}}$}{$\strut{\overline{\ListeVariablesKGH[2]}}$} };
						\ifboolKV[tblkgh]{Swap}%
							{%
								\draw[\KGHTCoulLegendeC,line width=\KGHThick,decorate,decoration={brace,amplitude=7pt,mirror}](1,-0.1)--(3,-0.1) node[midway,below=7pt,inner sep=1pt,text=\KGHTCoulLegendeC,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[3]}$}{$\strut{\ListeVariablesKGH[3]}$} };
								\node[\KGHTCoulLegendeC,inner sep=1pt,below=7pt,outer sep=0pt] at (0.5,-0.1) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\overline{\ListeVariablesKGH[3]}}$}{$\strut{\overline{\ListeVariablesKGH[3]}}$} };
								\node[\KGHTCoulLegendeC,inner sep=1pt,below=7pt,outer sep=0pt] at (3.5,-0.1) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\overline{\ListeVariablesKGH[3]}}$}{$\strut{\overline{\ListeVariablesKGH[3]}}$} };
							}%
							{%
								\draw[\KGHTCoulLegendeC,line width=\KGHThick,decorate,decoration={brace,amplitude=7pt,mirror}](1,-0.1)--(3,-0.1) node[midway,below=7pt,inner sep=1pt,text=\KGHTCoulLegendeC,outer sep=0pt] { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\overline{\ListeVariablesKGH[3]}}$}{$\strut{\overline{\ListeVariablesKGH[3]}}$} };
								\node[\KGHTCoulLegendeC,inner sep=1pt,below=7pt,outer sep=0pt] at (0.5,-0.1) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[3]}$}{$\strut{\ListeVariablesKGH[3]}$} };
								\node[\KGHTCoulLegendeC,inner sep=1pt,below=7pt,outer sep=0pt] at (3.5,-0.1) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[3]}$}{$\strut{\ListeVariablesKGH[3]}$} };
							}%
						\IfStrEq{\KGHTPosVarA}{Gauche}
							{%
								\node[\KGHTCoulLegendeA,inner sep=1pt,outer sep=0pt,left=8pt] at (0,0.5) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\overline{\ListeVariablesKGH[1]}}$}{$\strut{\overline{\ListeVariablesKGH[1]}}$} };
								\node[\KGHTCoulLegendeA,inner sep=1pt,outer sep=0pt,left=8pt] at (0,1.5) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[1]}$}{$\strut{\ListeVariablesKGH[1]}$} };
							}{}%
						\IfStrEq{\KGHTPosVarA}{Droite}
							{%
								\node[\KGHTCoulLegendeA,inner sep=1pt,outer sep=0pt,right=8pt] at (4,0.5) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\overline{\ListeVariablesKGH[1]}}$}{$\strut{\overline{\ListeVariablesKGH[1]}}$} };
								\node[\KGHTCoulLegendeA,inner sep=1pt,outer sep=0pt,right=8pt] at (4,1.5) { \ifboolKV[tblkgh]{PoliceTT}{$\strut\mathtt{\ListeVariablesKGH[1]}$}{$\strut{\ListeVariablesKGH[1]}$} };
							}{}%
					}%
					{}%
			}%
		\draw[line width=\KGHThick,step=1,ystep=1,\KGHTCoul] (0,0) grid (4,2) ; \draw[line width=\KGHThick,\KGHTCoul] (0,0) rectangle (4,2) ;
	}%
	{%
		\ifboolKV[tblkgh]{StyleAlternatif}%
			{%
				\ifboolKV[tblkgh]{AideAlt}%
					{%
						\draw (A02) node[below right=2pt,inner sep=1pt,font=\scriptsize] {000} ;
						\draw (A12) node[below right=2pt,inner sep=1pt,font=\scriptsize] {010} ;
						\draw (A22) node[below right=2pt,inner sep=1pt,font=\scriptsize] {110} ;
						\draw (A32) node[below right=2pt,inner sep=1pt,font=\scriptsize] {100} ;
						\draw (A01) node[below right=2pt,inner sep=1pt,font=\scriptsize] {001} ;
						\draw (A11) node[below right=2pt,inner sep=1pt,font=\scriptsize] {011} ;
						\draw (A21) node[below right=2pt,inner sep=1pt,font=\scriptsize] {111} ;
						\draw (A31) node[below right=2pt,inner sep=1pt,font=\scriptsize] {101} ;
					}{}%
			}{}%
		\ifboolKV[tblkgh]{Aide}%
			{%
				\foreach \noeud in {00,10,20,30,40,01,11,21,31,41,02,12,22,32,42}
					{%
						\draw (A\noeud) node[gray,inner sep=1pt,fill=yellow,text=red,outer sep=0pt,font=\tiny\sffamily,scale=0.75] {A\noeud} ;
					}%
			}{}%
	\end{tikzpicture}
}%

\defKV[blockarnaugh]{%
	Decalage=\def\KGHdecalage{#1},%
	Couleur=\def\KGHcouleur{#1},%
	Type=\def\KGHtype{#1}
}

\setKVdefault[blockarnaugh]{%
	Decalage=2pt,%
	Couleur=red,%
	Type=Centre
}

\newcommand\KarnaughBlocCoul[2][lightgray]{%
	\setsepchar[.]{,./}%
	\readlist*\KGHListeRect{#2}%
	\xintFor* ##1 in {\xintSeq{1}{\KGHListeRectlen}}\do{%
		\draw[line width=\KGHThick,fill=#1] (A\KGHListeRect[##1,1]) rectangle (A\KGHListeRect[##1,2]) ;
		\draw[line width=\KGHThick] (A\KGHListeRect[##1,1]) grid (A\KGHListeRect[##1,2]) ;
	}%
}

\NewDocumentCommand\KarnaughCasesResult{ s m }{%
	\IfBooleanTF{#1}%
		{%
			\IfSubStr{#2}{,}%
				{%
					\setsepchar{,}%
					\readlist*\KGHListeResult{#2}%
					\xintifboolexpr{\KGHListeResult[1] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A01) rectangle (A12) ;}{}%
					\xintifboolexpr{\KGHListeResult[2] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A11) rectangle (A22) ;}{}%
					\xintifboolexpr{\KGHListeResult[3] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A21) rectangle (A32) ;}{}%
					\xintifboolexpr{\KGHListeResult[4] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A31) rectangle (A42) ;}{}%
					\xintifboolexpr{\KGHListeResult[5] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A00) rectangle (A11) ;}{}%
					\xintifboolexpr{\KGHListeResult[6] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A10) rectangle (A21) ;}{}%
					\xintifboolexpr{\KGHListeResult[7] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A20) rectangle (A31) ;}{}%
					\xintifboolexpr{\KGHListeResult[8] == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A30) rectangle (A41) ;}{}%
				}%
				{%
					\StrChar{#2}{1}[\TmpCharA]\xintifboolexpr{\TmpCharA == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A01) rectangle (A12) ;}{}%
					\StrChar{#2}{2}[\TmpCharB]\xintifboolexpr{\TmpCharB == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A11) rectangle (A22) ;}{}%
					\StrChar{#2}{3}[\TmpCharC]\xintifboolexpr{\TmpCharC == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A21) rectangle (A32) ;}{}%
					\StrChar{#2}{4}[\TmpCharD]\xintifboolexpr{\TmpCharD == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A31) rectangle (A42) ;}{}%
					\StrChar{#2}{5}[\TmpCharE]\xintifboolexpr{\TmpCharE == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A00) rectangle (A11) ;}{}%
					\StrChar{#2}{6}[\TmpCharF]\xintifboolexpr{\TmpCharF == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A10) rectangle (A21) ;}{}%
					\StrChar{#2}{7}[\TmpCharG]\xintifboolexpr{\TmpCharG == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A20) rectangle (A31) ;}{}%
					\StrChar{#2}{8}[\TmpCharH]\xintifboolexpr{\TmpCharH == 1}{\draw[line width=\KGHThick,fill=\KGHTCoulCases,draw=\KGHTCoul] (A30) rectangle (A41) ;}{}%
				}%
		}%
		{%
			\IfSubStr{#2}{,}%
				{%
					\setsepchar{,}%
					\readlist*\KGHListeResult{#2}%
					\draw (0.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[1]} ;
					\draw (1.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[2]} ;
					\draw (2.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[3]} ;
					\draw (3.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[4]} ;
					\draw (0.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[5]} ;
					\draw (1.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[6]} ;
					\draw (2.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[7]} ;
					\draw (3.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\KGHListeResult[8]} ;
				}%
				{%
					\draw (0.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{1}} ;
					\draw (1.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{2}} ;
					\draw (2.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{3}} ;
					\draw (3.5,1.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{4}} ;
					\draw (0.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{5}} ;
					\draw (1.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{6}} ;
					\draw (2.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{7}} ;
					\draw (3.5,0.5) node[text=\KGHTCoulCases!50!black,font=\large\ttfamily] {\StrChar{#2}{8}} ;
				}%
		}%
}

\newcommand\KarnaughBlocRegroup[3][]{%
	\useKVdefault[blockarnaugh]%
	\setKV[blockarnaugh]{#1}%
	\IfStrEq{\KGHtype}{Centre}%
		{\draw[rounded corners,line width=1.25pt,color=\KGHcouleur] ($(A#2)+(-\KGHdecalage,-\KGHdecalage)$) rectangle ($(A#3)+(\KGHdecalage,\KGHdecalage)$);}%
		{}%
	\IfStrEq{\KGHtype}{Gauche}%#2=BG #3=HD
		{%
			\StrChar{#2}{1}[\KGHia]%
			\StrChar{#2}{2}[\KGHja]%
			\StrChar{#3}{1}[\KGHib]%
			\StrChar{#3}{2}[\KGHjb]%
			\draw[rounded corners,line width=1.25pt,color=\KGHcouleur]%
			($(A#2)+(-\KGHdecalage,-\KGHdecalage)$) -- ($(A\KGHib\KGHja)+(\KGHdecalage,-\KGHdecalage)$)%
			-- ($(A#3)+(\KGHdecalage,\KGHdecalage)$) -- ($(A\KGHia\KGHjb)+(-\KGHdecalage,\KGHdecalage)$);%
		}%
		{}%
	\IfStrEq{\KGHtype}{Droite}%#2=BD #3=HG
		{%
			\StrChar{#2}{1}[\KGHia]%
			\StrChar{#2}{2}[\KGHja]%
			\StrChar{#3}{1}[\KGHib]%
			\StrChar{#3}{2}[\KGHjb]%
			\draw[rounded corners,line width=1.25pt,color=\KGHcouleur]%
			($(A#2)+(\KGHdecalage,-\KGHdecalage)$) -- ($(A\KGHib\KGHja)+(-\KGHdecalage,-\KGHdecalage)$)%
			-- ($(A#3)+(-\KGHdecalage,\KGHdecalage)$) -- ($(A\KGHia\KGHjb)+(\KGHdecalage,\KGHdecalage)$);%
		}%
		{}%
}

%------Graphes
\defKV[GraphSIO]{%
	Police=\def\GrphPoliceSommets{#1},%
	Poids=\def\GrphPolicePoids{#1},%
	CouleurSommets=\def\GrphCoulSommets{#1},%
	CouleurFleches=\def\GrphCoulFleches{#1},%
	Epaisseur=\def\GrphTchick{#1},%
	TypeSommets=\def\GrphTypeSomm{#1},%
	Unite=\def\GrphUnit{#1},%
	CouleurFT=\def\GrphCoulFT{#1},%
	Grille=\def\GrphGrille{#1},%
	DimensionSommets=\def\GrphDimSommet{#1},%
	PositionFleches=\def\GrphPosArrow{#1},%
	EchelleFleches=\def\GrphScaleArrow{#1},%
	TypeFleche=\def\GrphTypeArrow{#1}
}

\setKVdefault[GraphSIO]{%
	Police={\bfseries\Large\sffamily},%
	Poids={\sffamily},%
	CouleurSommets={black},%
	CouleurFleches={black},%
	TypeSommets=circle,%
	Epaisseur=thick,%
	Unite=1cm,%
	CouleurFT=red,%
	Grille={},%
	DimensionSommets=1cm,%
	PositionFleches={Fin},%
	EchelleFleches=1,%
	TypeFleche=Latex
}

\NewDocumentEnvironment{GrapheTikz}{ O{} D<>{} }%
{%
	\restoreKV[GraphSIO]% revenir au valeurs par défaut
	\setKV[GraphSIO]{#1}% lit les arguments optionnels
	\IfSubStr{\GrphDimSommet}{/}%
		{%
			\StrCut{\GrphDimSommet}{/}{\GrphDimSommetLarg}{\GrphDimSommetHaut}%
		}%
		{%
			\def\GrphDimSommetLarg{\GrphDimSommet}\def\GrphDimSommetHaut{\GrphDimSommet}%
		}%
	\IfSubStr{\GrphTchick}{/}%
		{%
			\StrCut{\GrphTchick}{/}{\GrphTchickA}{\GrphTchickB}%
		}%
		{%
			\def\GrphTchickA{\GrphTchick}\def\GrphTchickB{\GrphTchick}%
		}%
	\IfSubStr{\GrphCoulSommets}{/}%
		{%
			\StrCut{\GrphCoulSommets}{/}{\GrphCoulA}{\GrphCoulB}%
		}%
		{%
			\def\GrphCoulA{\GrphCoulSommets}\def\GrphCoulB{\GrphCoulSommets}%
		}%
	\begin{tikzpicture}[x=\GrphUnit,y=\GrphUnit,#2]
		\tikzset{GrphStyleSommet/.style = {\GrphTchickA,draw=\GrphCoulA,\GrphTypeSomm,minimum height=\GrphDimSommetHaut,minimum width=\GrphDimSommetLarg,text=\GrphCoulB}}%
		\tikzset{GrphStylepoids/.style = {inner sep=2pt,midway,draw=none,font=\GrphPolicePoids,text=\GrphCoulFleches,fill=white}}%
		\IfStrEq{\GrphPosArrow}{Fin}%
			{%
				\tikzset{GrphStyleArc/.style = {\GrphCoulFleches,\GrphTchickB,-{\GrphTypeArrow[scale=\GrphScaleArrow]}}}%
			}%
			{}%
		\IfStrEq{\GrphPosArrow}{Milieu}%
			{%
				\tikzset{GrphStyleArc/.style = {\GrphCoulFleches,\GrphTchickB,postaction={decorate},decoration={markings,mark=at position 0.55 with {\arrow[scale=\GrphScaleArrow,>=\GrphTypeArrow]{>}}}}}%
			}{}%
		\tikzset{FT/.style = {\GrphCoulFT}}%
		\IfStrEq{\GrphGrille}{}%
			{}%
			{%
				\StrCut{\GrphGrille}{,}{\GrphGrilleX}{\GrphGrilleY}%
				\draw[thin,dotted,lightgray,xstep=0.5,ystep=0.5] (0,0) grid (\GrphGrille) ;%
				\draw[thin,lightgray,xstep=1,ystep=1] (0,0) grid (\GrphGrille) ;%
				\foreach \x in {0,0.5,...,\GrphGrilleX} {\draw[thin,lightgray] (\x,0)--++(0,-2pt) node[below,inner sep=1pt,font=\sffamily\tiny] {\x} ;}%
				\foreach \y in {0,0.5,...,\GrphGrilleY} {\draw[thin,lightgray] (0,\y)--++(-2pt,0) node[left,inner sep=1pt,font=\sffamily\tiny] {\y} ;}%
				\filldraw[lightgray] (0,0) circle[radius=1.5pt] ;%
			}%
}%
{%
	\end{tikzpicture}
}

\NewDocumentCommand\GrphPlaceSommets{ m }{%
	\setsepchar[.]{ ./}%
	\readlist*\GrphtmpLS{#1}%
	\xintFor* ##1 in {\xintSeq{1}{\GrphtmpLSlen}}\do{%
		\node[GrphStyleSommet,font=\GrphPoliceSommets] (\GrphtmpLS[##1,2]) at \GrphtmpLS[##1,1] {\GrphtmpLS[##1,2]} ;
	}%
}

\NewDocumentCommand\GrphTraceAretes{ s O{Droit} D<>{} m }{%
	\setsepchar[.]{ ./}%
	\readlist*\GrphtmpLA{#4}%
	\xintFor* ##1 in {\xintSeq{1}{\GrphtmpLAlen}}\do{%
		\IfStrEq{#2}{Droit}%
			{%
				\IfBooleanTF{#1}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1])--(\GrphtmpLA[##1,2]) node[GrphStylepoids] {\GrphtmpLA[##1,3]} ;%
					}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1])--(\GrphtmpLA[##1,2]) ;
					}%
			}{}%
		\IfSubStr{#2}{AngleGauche}%
			{%
				\def\GrphAngle{10}%
				\IfSubStr{#2}{=}%
					{%
						\StrBehind{#2}{=}[\GrphAngle]%
					}{}%
				\IfBooleanTF{#1}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1]) to[bend left=\GrphAngle] node[GrphStylepoids] {\GrphtmpLA[##1,3]} (\GrphtmpLA[##1,2]) ;%
					}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1]) to[bend left=\GrphAngle] (\GrphtmpLA[##1,2]) ;
					}%
			}{}%
		\IfSubStr{#2}{AngleDroit}%
			{%
				\def\GrphAngle{10}%
				\IfSubStr{#2}{=}%
					{%
						\StrBehind{#2}{=}[\GrphAngle]%
					}{}%
				\IfBooleanTF{#1}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1]) to[bend right=\GrphAngle] node[GrphStylepoids] {\GrphtmpLA[##1,3]} (\GrphtmpLA[##1,2]) ;%
					}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1]) to[bend right=\GrphAngle] (\GrphtmpLA[##1,2]) ;
					}%
			}{}%
		\IfSubStr{#2}{Boucle}%
			{%
				\def\GrphBoucleCoeff{6}%
				\IfSubStr{#2}{=}%
					{%
						\StrBehind{#2}{=}[\GrphBoucleCoeff]%
					}{}%
				\def\GrphAngleOut{\GrphtmpLA[##1,2]}%
				\def\GrphAngleIn{\inteval{\GrphAngleOut+90}}%
				\IfBooleanTF{#1}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1]) to[loop,looseness=\GrphBoucleCoeff,out=\GrphAngleOut,in=\GrphAngleIn] node[GrphStylepoids] {\GrphtmpLA[##1,3]} (\GrphtmpLA[##1,1]) ;%
					}%
					{%
						\draw[GrphStyleArc,#3] (\GrphtmpLA[##1,1]) to[loop,looseness=\GrphBoucleCoeff,out=\GrphAngleOut,in=\GrphAngleIn] (\GrphtmpLA[##1,1]) ;
					}%
			}{}%
	}%
}

%------Diagramme Sagittal
\defKV[DiagSagitt]{%
	E=\def\DSListeEltE{#1},%
	F=\def\DSListeEltF{#1},%
	DistElem=\def\DSEcartIN{#1},%
	DistEns=\def\DSEcartIP{#1},%
	LargEns=\def\DSLargPatates{#1},%
	NomAppli=\def\DSNomFctPatates{#1},%
	CouleurE=\def\DSCouleurE{#1},%
	CouleurAppli=\def\DSCouleurFct{#1},%
	CouleurF=\def\DSCouleurF{#1},%
	CouleurFleches=\def\DSCouleurArc{#1},%
	TypeFleche=\def\DSTypeFleche{#1},%
	Epaisseur=\def\DSThick{#1},%
	Police=\def\DSPolicePatates{#1},%
	PoliceLabels=\def\DSPoliceLabels{#1},%
	Ensembles=\def\DSNomEns{#1},%
	PosLabels=\def\DSPosLabels{#1},%
	Offset=\def\DSOffset{#1}
}

\setKVdefault[DiagSagitt]{%
	DistElem=0.75,%
	DistEns=4,%
	LargEns=1.5,%
	NomAppli={$f$},%
	CouleurE={blue},%
	CouleurAppli={violet},%
	CouleurF={red},%
	CouleurFleches={teal},%
	TypeFleche=Latex,%
	Epaisseur=0.8pt,%
	Police={},%
	NoirBlanc=false,%
	Labels=true,%
	Ensembles={$\mathcal{E}$/$\mathcal{F}$},%{E/F},%
	PosLabels=bas,%
	PoliceLabels={},%
	Offset=2pt
}

\NewDocumentCommand\DiagrammeSagittal{s O{} D<>{} m }{%
	\restoreKV[DiagSagitt]%paramètres par défaut
	\setKV[DiagSagitt]{#2}%
	\readlist*\DSLstE{\DSListeEltE}%
	\readlist*\DSLstF{\DSListeEltF}%
	\def\DSHauteurPatateE{\fpeval{\DSEcartIN*(1+\DSLstElen)}}%
	\def\DSHauteurPatateF{\fpeval{\DSEcartIN*(1+\DSLstFlen)}}%
	\def\DSMaxHauteursPatates{\fpeval{max(\DSHauteurPatateE,\DSHauteurPatateF)}}%
	\def\DSOffsetPatates{\fpeval{0.5*\DSHauteurPatateF-0.5*\DSHauteurPatateE}}%
	\IfStrEq{\DSPosLabels}{bas}%
		{%
			\def\DSHautLegende{\fpeval{min(0,-\DSOffsetPatates)-0.5*\DSEcartIN}}%
		}{}%
	\IfStrEq{\DSPosLabels}{haut}%
		{%
			\def\DSHautLegende{\fpeval{max(\DSHauteurPatateE,\DSHauteurPatateF-\DSOffsetPatates)+0.5*\DSEcartIN}}%
		}{}
	\ifboolKV[DiagSagitt]{NoirBlanc}%
		{%
			\def\DSCouleurE{black}%
			\def\DSCouleurF{black}%
			\def\DSCouleurArc{black}%
			\def\DSCouleurFct{black}%
		}{}%
	\IfBooleanTF{#1}%
		{}%
		{\begin{tikzpicture}[#3]}%
		%LABELS
		%\draw[lightgray,thin,->] (-1,0)--++(6,0) ;
		\ifboolKV[DiagSagitt]{Labels}%
			{%
				\saveexpandmode\expandarg
				\StrCut{\DSNomEns}{/}{\DSNomE}{\DSNomF}
				\restoreexpandmode
				\draw (0,{\DSHautLegende}) node[\DSCouleurE,inner sep=1pt,font=\DSPoliceLabels] {\DSNomE} ;
				\draw ({\DSEcartIP},{\DSHautLegende}) node[\DSCouleurF,inner sep=1pt,font=\DSPoliceLabels] {\DSNomF} ;
				\draw[line width=\DSThick,->,>=\DSTypeFleche] ({0.45},{\DSHautLegende})--({\DSEcartIP-0.45},{\DSHautLegende}) node[midway,above=2pt,inner sep=1pt,text=\DSCouleurFct,font=\DSPoliceLabels] {\DSNomFctPatates} ;
			}{}%
		%PATATE_E (ok)
		\draw[line width=\DSThick] (0,{0.5*\DSHauteurPatateE}) ellipse ({0.5*\DSLargPatates} and {0.5*\DSHauteurPatateE} );
		\foreach \i in {1,...,\DSLstElen}{%
			\coordinate (E\DSLstE[\i]) at ({0.05*\DSLargPatates},{(\DSLstElen-\i+1)*\DSEcartIN}) ;%
			\filldraw[\DSCouleurE] (E\DSLstE[\i]) circle[radius=1.5pt] node[left,font=\DSPolicePatates] {\DSLstE[\i]} ;%
		}%
		%PATATE_F (ok)
		\draw[line width=\DSThick] ({\DSEcartIP},{0.5*\DSHauteurPatateF-\DSOffsetPatates}) ellipse ({0.5*\DSLargPatates} and {0.5*\DSHauteurPatateF} );
		\foreach \i in {1,...,\DSLstFlen}{%
			\coordinate (F\DSLstF[\i]) at ({\DSEcartIP-0.05*\DSLargPatates},{(\DSLstFlen-\i+1)*\DSEcartIN-\DSOffsetPatates}) ;%
			\filldraw[\DSCouleurF] (F\DSLstF[\i]) circle[radius=1.5pt] node[right,font=\DSPolicePatates] {\DSLstF[\i]} ;%
		}%
		%ARCS
		\foreach \Deb/\Fin in {#4} {%
			\draw[line width=\DSThick,->,>=\DSTypeFleche,\DSCouleurArc] ([xshift=\DSOffset]E\Deb)--([xshift=-\DSOffset]F\Fin) ;
		}%
	\IfBooleanTF{#1}%
		{}%
		{\end{tikzpicture}}%
}

%------Diagramme Sagittal Compo
\defKV[DiagSagittCompo]{%
	E=\def\DSListeEltE{#1},%
	F=\def\DSListeEltF{#1},%
	G=\def\DSListeEltG{#1},%
	DistElem=\def\DSEcartIN{#1},%
	DistEns=\def\DSEcartIP{#1},%
	LargEns=\def\DSLargPatates{#1},%
	NomApplis=\def\DSNomsFcts{#1},%
	CouleurE=\def\DSCouleurE{#1},%
	CouleursAppli=\def\DSCouleursFct{#1},%
	CouleurF=\def\DSCouleurF{#1},%
	CouleursFleches=\def\DSCouleurArc{#1},%
	CouleurG=\def\DSCouleurG{#1},%
	TypeFleche=\def\DSTypeFleche{#1},%
	Epaisseur=\def\DSThick{#1},%
	Police=\def\DSPolicePatates{#1},%
	PoliceLabels=\def\DSPoliceLabels{#1},%
	Ensembles=\def\DSNomEns{#1},%
	PosLabels=\def\DSPosLabels{#1},%
	Offset=\def\DSOffset{#1}
}

\setKVdefault[DiagSagittCompo]{%
	DistElem=0.75,%
	DistEns=4,%
	LargEns=1.5,%
	NomApplis={$f$/$g$},%
	CouleurE={blue},%
	CouleursAppli={violet},%
	CouleurF={red},%
	CouleurG={gray},%
	CouleursFleches={teal},%
	TypeFleche=Latex,%
	Epaisseur=0.8pt,%
	Police={},%
	NoirBlanc=false,%
	Labels=true,%
	Ensembles={$\mathcal{E}$/$\mathcal{F}$/$\mathcal{G}$},%
	PosLabels=bas,%
	PoliceLabels={},%
	Offset=2pt
}

\NewDocumentCommand\DiagrammeSagittalCompo{s O{} D<>{} m m }{%
	\restoreKV[DiagSagittCompo]%paramètres par défaut
	\setKV[DiagSagittCompo]{#2}%
	\readlist*\DSLstE{\DSListeEltE}%
	\readlist*\DSLstF{\DSListeEltF}%
	\readlist*\DSLstG{\DSListeEltG}%
	\def\DSHauteurPatateE{\fpeval{\DSEcartIN*(1+\DSLstElen)}}%
	\def\DSHauteurPatateF{\fpeval{1.1*\DSEcartIN*(1+\DSLstFlen)}}%
	\def\DSHauteurPatateG{\fpeval{\DSEcartIN*(1+\DSLstGlen)}}%
	\def\DSMaxHauteursPatates{\fpeval{max(\DSHauteurPatateE,\DSHauteurPatateF,\DSHauteurPatateG)}}%
	\def\DSOffsetPatateF{\fpeval{0.5*\DSHauteurPatateF-0.5*\DSHauteurPatateE}}%
	\def\DSOffsetPatateG{\fpeval{0.5*\DSHauteurPatateG-0.5*\DSHauteurPatateE}}%
	\IfStrEq{\DSPosLabels}{bas}%
		{%
			\def\DSHautLegende{\fpeval{min(0,-\DSOffsetPatateF,-\DSOffsetPatateG)-0.5*\DSEcartIN}}%
			\def\DSHautCompo{\fpeval{max(\DSHauteurPatateE,\DSHauteurPatateF-\DSOffsetPatateF,\DSHauteurPatateG-\DSOffsetPatateG)+0.5*\DSEcartIN}}%
			\def\DSposlabelcompo{above}%
		}{}%
	\IfStrEq{\DSPosLabels}{haut}%
		{%
			\def\DSHautLegende{\fpeval{max(\DSHauteurPatateE,\DSHauteurPatateF-\DSOffsetPatateF,\DSHauteurPatateG-\DSOffsetPatateG)+0.5*\DSEcartIN}}%
			\def\DSHautCompo{\fpeval{min(0,-\DSOffsetPatateF,-\DSOffsetPatateG)-0.5*\DSEcartIN}}%
			\def\DSposlabelcompo{below}%
		}{}
	%découpage des couleurs et des noms
	\IfSubStr{\DSCouleursFct}{/}%
		{%
			\StrCut{\DSCouleursFct}{/}{\DSCouleursFctF}{\DSCouleursFctG}%
		}%
		{%
			\def\DSCouleursFctF{\DSCouleursFct}\def\DSCouleursFctG{\DSCouleursFct}%
		}%
	\IfSubStr{\DSCouleurArc}{/}%
		{%
			\StrCut{\DSCouleurArc}{/}{\DSCouleurArcF}{\DSCouleurArcG}%
		}%
		{%
			\def\DSCouleurArcF{\DSCouleurArc}\def\DSCouleurArcG{\DSCouleurArc}%
		}%
	\ifboolKV[DiagSagittCompo]{NoirBlanc}%
		{%
			\def\DSCouleurE{black}%
			\def\DSCouleurF{black}%
			\def\DSCouleurG{black}%
			\def\DSCouleurArcF{black}%
			\def\DSCouleurArcG{black}%
			\def\DSCouleurArcG{black}%
			\def\DSCouleurFctF{black}%
			\def\DSCouleurFctG{black}%
		}{}%
	%CONSTRUCTION
	\IfBooleanTF{#1}%
	{}%
	{\begin{tikzpicture}[#3]}%
		%LABELS
		%\draw[lightgray,thin,->] (-1,0)--++({3*\DSEcartIP},0) ;
		\ifboolKV[DiagSagittCompo]{Labels}%
		{%
			\saveexpandmode\expandarg
			%découpage des noms d'ensembles
			\StrBefore{\DSNomEns}{/}[\DSNomE]
			\StrBetween[1,2]{\DSNomEns}{/}{/}[\DSNomF]
			\StrBehind[2]{\DSNomEns}{/}[\DSNomG]
			%découpage des fonctions
			\StrCut{\DSNomsFcts}{/}{\DSNomFctF}{\DSNomFctG}%
			\restoreexpandmode
			\draw (0,{\DSHautLegende}) node[\DSCouleurE,inner sep=1pt,font=\DSPoliceLabels] {\DSNomE} ;
			\draw ({\DSEcartIP},{\DSHautLegende}) node[\DSCouleurF,inner sep=1pt,font=\DSPoliceLabels] {\DSNomF} ;
			\draw ({2*\DSEcartIP},{\DSHautLegende}) node[\DSCouleurG,inner sep=1pt,font=\DSPoliceLabels] {\DSNomG} ;
			\draw (0,{\DSHautCompo}) node[\DSCouleurE,inner sep=1pt,font=\DSPoliceLabels] {\DSNomE} ;
			\draw ({2*\DSEcartIP},{\DSHautCompo}) node[\DSCouleurG,inner sep=1pt,font=\DSPoliceLabels] {\DSNomG} ;
			\draw[line width=\DSThick,->,>=\DSTypeFleche] ({0.45},{\DSHautLegende})--({\DSEcartIP-0.45},{\DSHautLegende}) node[midway,above=2pt,inner sep=1pt,text=\DSCouleursFctF,font=\DSPoliceLabels] {\DSNomFctF} ;
			\draw[line width=\DSThick,->,>=\DSTypeFleche] ({\DSEcartIP+0.45},{\DSHautLegende})--({2*\DSEcartIP-0.45},{\DSHautLegende}) node[midway,above=2pt,inner sep=1pt,text=\DSCouleursFctG,font=\DSPoliceLabels] {\DSNomFctG} ;
			\draw[line width=\DSThick,->,>=\DSTypeFleche] ({0.45},{\DSHautCompo}) -- ({2*\DSEcartIP-0.45},{\DSHautCompo}) node[midway,\DSposlabelcompo=2pt,inner sep=1pt,font=\DSPoliceLabels] {\textcolor{\DSCouleursFctG}{\DSNomFctG}{\small\,$\circ$\,}\textcolor{\DSCouleursFctF}{\DSNomFctF}} ;
		}{}%
		%PATATE_E (ok)
		\draw[line width=\DSThick] (0,{0.5*\DSHauteurPatateE}) ellipse ({0.5*\DSLargPatates} and {0.5*\DSHauteurPatateE} );
		\foreach \i in {1,...,\DSLstElen}{%
			\coordinate (E\DSLstE[\i]) at ({0.05*\DSLargPatates},{(\DSLstElen-\i+1)*\DSEcartIN}) ;%
			\filldraw[\DSCouleurE] (E\DSLstE[\i]) circle[radius=1.5pt] node[left,font=\DSPolicePatates] {\DSLstE[\i]} ;%
		}%
		%PATATE_F (ok)
		\draw[line width=\DSThick] ({\DSEcartIP},{0.5*\DSHauteurPatateF-\DSOffsetPatateF}) ellipse ({0.5*\DSLargPatates} and {0.5*\DSHauteurPatateF} );
		\foreach \i in {1,...,\DSLstFlen}{%
			\coordinate (F\DSLstF[\i]) at ({\DSEcartIP},{(\DSLstFlen-\i+1)*1.1*\DSEcartIN-\DSOffsetPatateF}) ;%
			\filldraw[\DSCouleurF] (F\DSLstF[\i]) circle[radius=1.5pt] node[above=0pt,font=\DSPolicePatates] {\DSLstF[\i]} ;%
		}%
		%PATATE_G (ok)
		\draw[line width=\DSThick] ({2*\DSEcartIP},{0.5*\DSHauteurPatateG-\DSOffsetPatateG}) ellipse ({0.5*\DSLargPatates} and {0.5*\DSHauteurPatateG} );
		\foreach \i in {1,...,\DSLstGlen}{%
			\coordinate (G\DSLstG[\i]) at ({2*\DSEcartIP-0.05*\DSLargPatates},{(\DSLstGlen-\i+1)*\DSEcartIN-\DSOffsetPatateG}) ;%
			\filldraw[\DSCouleurG] (G\DSLstG[\i]) circle[radius=1.5pt] node[right,font=\DSPolicePatates] {\DSLstG[\i]} ;%
		}%
		%ARCSf
		\foreach \Deb/\Fin in {#4} {%
			\draw[line width=\DSThick,->,>=\DSTypeFleche,\DSCouleurArcF] ([xshift=\DSOffset]E\Deb)--([xshift=-\DSOffset]F\Fin) ;
		}%
		%ARCSg
		\foreach \Deb/\Fin in {#5} {%
			\draw[line width=\DSThick,->,>=\DSTypeFleche,\DSCouleurArcG] ([xshift=\DSOffset]F\Deb)--([xshift=-\DSOffset]G\Fin) ;
		}%
		\IfBooleanTF{#1}%
		{}%
		{\end{tikzpicture}}%
}

%------Table de vérité
\ifluatex
\RequirePackage{xkeyval}
\RequirePackage{luacode}
\RequirePackage{nicematrix}

%patchs pour luatruthtable (échange 1ère ligne <-> dernière ligne), à voir si le package sera patché pour éviter de "piquer" le code !
%patchs from luatruthtable
\begin{luacode*}
local function toBinary(x,y)
	y = y or math.max(1, select(2, math.frexp(x)))
	local res = {}
	for i = y, 1, -1 do
		res[i] = math.fmod(x, 2)
		x = math.floor((x - res[i]) / 2)
	end
	return res
end

local function _not(a)
	if a ==0 then return 1
	else return 0 end
end

local lognot = {}

local not_mt= {
	__mul = function(a,b)
	return _not(b)
end
}

setmetatable(lognot, not_mt)
_G.lognot = lognot

local function _and(a, b)
	if a == 1 and b == 1 then return 1
	else return 0 end
end

local tmp1 = {}
local logand = {}
local v1 = 0

local and_mt= {
	__mul = function(a,b)
	if b==logand then
		v1 = v1 + 1 
		tmp1[v1]=a
		return tmp1
	elseif a == tmp1 then
		local w1 = _and(tmp1[v1], b)
		v1 = v1 - 1
		return w1
	end
end
}

setmetatable(tmp1, and_mt)
setmetatable(logand, and_mt)
_G.logand = logand

local function _or(a, b)
  if a == 0 and b == 0 then return 0
	else return 1 end
end

local tmp2 = {}
local logor = {}
local v2 = 0

local or_mt= {
	__mul = function(a,b)
	if b==logor then
		 v2 = v2 + 1 
		tmp2[v2] = a
	return tmp2
	elseif a == tmp2 then
		local w2 =  _or(tmp2[v2], b)
		v2 = v2 - 1
		return w2
	end
end
}

setmetatable(tmp2, or_mt)
setmetatable(logor, or_mt)
_G.logor = logor

local function _imp(a, b)
	if a == 1 and b == 0 then return 0
	else return 1 end
end

local tmp3 = {}
local imp = {}
local v3 = 0

local imp_mt= {
	__mul = function(a,b)
	if b==imp then
		 v3 = v3 + 1
		tmp3[v3]=a
		return tmp3
	elseif a == tmp3 then
		local w3 =  _imp(tmp3[v3], b)
		v3 = v3 - 1
		return w3
	end
end
}

setmetatable(tmp3, imp_mt)
setmetatable(imp, imp_mt)
_G.imp = imp

local function _iff(a, b)
	if a == b then return 1
	else return 0 end
end

local tmp4 = {}
local iff = {}
local v4 = 0

local iff_mt= {
	__mul = function(a,b)
	if b==iff then
		v4 = v4 + 1 
		tmp4[v4]=a
		return tmp4
	elseif a == tmp4 then
		local w4 = _iff(tmp4[v4], b)
		v4 = v4 - 1
		return w4
	end
end
}

setmetatable(tmp4, iff_mt)
setmetatable(iff, iff_mt)
_G.iff = iff

local function _xor(a, b)
	if a ~= b then return 1
	else return 0 end
end

local tmp5 = {}
local logxor = {}
local v5 = 0

local xor_mt= {
	__mul = function(a,b)
	if b==logxor then
	 v5 = v5 + 1 
		tmp5[v5]=a
		return tmp5
	elseif a == tmp5 then
		local w5 = _xor(tmp5[v5], b)
		v5 = v5 - 1
		return w5
	end
end
}

setmetatable(tmp5, xor_mt)
setmetatable(logxor, xor_mt)
_G.logxor = logxor

local function _nand(a, b)
	if a ==1 and b == 1 then return 0
	else return 1 end
end

local tmp6 = {}
local lognand = {}
local v6 = 0

local nand_mt= {
	__mul = function(a,b)
	if b==lognand then
		 v6 = v6 + 1 
		tmp6[v6]=a
		return tmp6
	elseif a == tmp6 then
		local w6 =  _nand(tmp6[v6], b)
		v6 = v6 - 1
		return w6
	end
end
}

setmetatable(tmp6, nand_mt)
setmetatable(lognand, nand_mt)
_G.lognand = lognand

local function _nor(a, b)
	if a ==0 and b == 0 then return 1
	else return 0 end
end

local tmp7 = {}
local lognor = {}
local v7 = 0

local nor_mt= {
	__mul = function(a,b)
	if b==lognor then
		v7 = v7 + 1 
		tmp7[v7]=a
		return tmp7
	elseif a == tmp7 then
		local w7 = _nor(tmp7[v7], b)
		v7 = v7 - 1
		return w7
	end
end
}

setmetatable(tmp7, nor_mt)
setmetatable(lognor, nor_mt)
_G.lognor = lognor

local function _xnor(a, b)
	if a == b then return 1
	else return 0 end
end

local tmp8 = {}
local logxnor = {}
local v8 = 0

local xnor_mt= {
	__mul = function(a,b)
	if b==logxnor then
		v8 = v8 + 1 
		tmp8[v8]=a
		return tmp8
	elseif a == tmp8 then
		local w8 =  _xnor(tmp8[v8], b)
		v8 = v8 - 1
		return w8
	end
end
}

setmetatable(tmp8, xnor_mt)
setmetatable(logxnor, xnor_mt)
_G.logxnor = logxnor

function TruthTbl(str0,str,trtext,fltext)
	local eval=""
	local names={lognot=lognot,logand=logand,logor=logor, imp=imp, iff=iff, logxor=logxor,lognand=lognand,lognor=lognor, logxnor=logxnor}
	local vars={}
	local expr={}
	local countexp = 1
	local countvars =1
	local res=""
	local sep=" & "
	trtext = trtext or "$T$"
	fltext = fltext or "$F$"
	for variables in string.gmatch(str0, '([^,]+)') do
		vars[countvars] = variables
		countvars = countvars + 1
	end
	for subexp in string.gmatch(str, '([^,]+)') do
		expr[countexp] = subexp
		countexp = countexp + 1
	end
	local n =#vars
	for i =1,2^n do
		itr = toBinary(i,n)
		for j=1, #itr do
			names[vars[j]] = itr[j]
		end
		for k = 1, #expr do
			res= res ..sep.. load("return " .. expr[k],nil,"t",names)()
		end
		if i~=2^n then
			eval = eval .. table.concat(toBinary(i,n)," & ") .. res .. "\\\\"
		else
			eval = table.concat(toBinary(i,n)," & ") .. res .. "\\\\" .. eval
		end
		res=""
	end
	eval=eval:sub(1,-3)
	if trtext:gsub("%s+", "") =="0" or trtext:gsub("%s+", "") == "$0$" or fltext:gsub("%s+", "") =="1" or fltext:gsub("%s+", "") == "$1$" then
		eval=eval
	else
		eval=eval:gsub(0,fltext):gsub(1,trtext)
	end
	return eval
end

function TruthTblSwap(str0,str,trtext,fltext)
	local eval=""
	local names={lognot=lognot,logand=logand,logor=logor, imp=imp, iff=iff, logxor=logxor,lognand=lognand,lognor=lognor, logxnor=logxnor}
	local vars={}
	local expr={}
	local countexp = 1
	local countvars =1
	local res=""
	local sep=" & "
	trtext = trtext or "$T$"
	fltext = fltext or "$F$"
	for variables in string.gmatch(str0, '([^,]+)') do
		vars[countvars] = variables
		countvars = countvars + 1
	end
	for subexp in string.gmatch(str, '([^,]+)') do
		expr[countexp] = subexp
		countexp = countexp + 1
	end
	local n =#vars
	for i =1,2^n do
		itr = toBinary(i,n)
		for j=1, #itr do
			names[vars[j]] = itr[j]
		end
		for k = 1, #expr do
			res= res ..sep.. load("return " .. expr[k],nil,"t",names)()
		end
		if i~=2^n then
			eval = table.concat(toBinary(i,n)," & ") .. res .. "\\\\" .. eval
		else
			eval = eval .. table.concat(toBinary(i,n)," & ") .. res .. "\\\\"
		end
		res=""
	end
	eval=eval:sub(1,-3)
	if trtext:gsub("%s+", "") =="0" or trtext:gsub("%s+", "") == "$0$" or fltext:gsub("%s+", "") =="1" or fltext:gsub("%s+", "") == "$1$" then
		eval=eval
	else
		eval=eval:gsub(0,fltext):gsub(1,trtext)
	end
	return eval
end
\end{luacode*}

\define@key{LuaTruthTable}{trtext}{\def\luatrtbl@trtext{#1}}
\define@key{LuaTruthTable}{fltext}{\def\luatrtbl@fltext{#1}}
\setkeys{LuaTruthTable}{trtext=$T$,fltext=$F$}%

\NewDocumentCommand\GenTruthTable{ s O{} m m }{%1=swap
	\setkeys{LuaTruthTable}{#2}%
	\IfBooleanTF{#1}%
		{%
			\directlua{tex.sprint(TruthTblSwap(\luastringN{#3},\luastringN{#4},'\luatrtbl@trtext','\luatrtbl@fltext'))}%
		}%
		{%
			\directlua{tex.sprint(TruthTbl(\luastringN{#3},\luastringN{#4},'\luatrtbl@trtext','\luatrtbl@fltext'))}%
		}%
}

\defKV[tableverite]{%
	VF=\def\TTABLEtruefalse{#1},%
	LargeursColonnes=\def\TTABLElargeurs{#1},%
	CouleurEnonce=\def\TTABLEcoul{#1},%
	CodeAvant=\def\TTABLEcodebefore{#1},%
	CodeApres=\def\TTABLEcodeafter{#1}
}

\setKVdefault[tableverite]{%
	VF={V/F},%
	LargeursColonnes=auto,%
	CouleurEnonce={},
	CodeAvant={},%
	CodeApres={},%
	Swap=false
}

\NewDocumentCommand\TableVerite{ O{} D<>{} m m m m }{%
	%1=options/clés
	%2=variables
	%3=colonnes des variables
	%4=calculs
	%5=colonne des calculs
	\useKVdefault[tableverite]%
	\setKV[tableverite]{#1}%
	\setsepchar{,}%
	\readlist*\TableVeriteVariables{#4}%
	\readlist*\TableVeriteEnonce{#5}%
	\readlist*\TableVeriteCalculs{#6}%
	\StrCut{\TTABLEtruefalse}{/}{\TTTrue}{\TTFalse}%
	\xdef\TTNbCol{\fpeval{\TableVeriteVariableslen+\TableVeriteEnoncelen}}%\TTNbCol%
	\IfStrEq{\TTABLElargeurs}{auto}%
		{%
			\begin{NiceTabular}[cell-space-limits=3pt,#2]{|*{\TTNbCol}{c|}}%
		}%
		{%
			\IfSubStr{\TTABLElargeurs}{/}%
				{%
					\StrCut{\TTABLElargeurs}{/}{\TTlargvars}{\TTlargcals}%
				}%
				{%
					\def\TTlargvars{\TTABLElargeurs}\def\TTlargcals{\TTABLElargeurs}%
				}%
			\begin{NiceTabular}[cell-space-limits=3pt,#2]{|*{\TableVeriteVariableslen}{W{c}{\TTlargvars}|}*{\TableVeriteEnoncelen}{W{c}{\TTlargcals}|}}%
		}%
		\CodeBefore
			\IfStrEq{\TTABLEcodebefore}{}{}{\TTABLEcodebefore}%
			\IfStrEq{\TTABLEcoul}{}{}{\rowcolor{\TTABLEcoul}{1}}%
		\Body
		\hline
		{\TableVeriteVariables[1]}\xintifboolexpr{\TableVeriteVariableslen==1}{}{\xintFor*##1in{\xintSeq{2}{\TableVeriteVariableslen}}\do{&\TableVeriteVariables[##1]}}&\TableVeriteCalculs[1]\xintifboolexpr{\TableVeriteCalculslen==1}{}{\xintFor*##1in{\xintSeq{2}{\TableVeriteCalculslen}}\do{&\TableVeriteCalculs[##1]}} \\ \hline
		\ifboolKV[tableverite]{Swap}%
			{%
				\GenTruthTable[trtext=\TTTrue,fltext=\TTFalse]{#3}{#5} \\ \hline
			}%
			{%
				\GenTruthTable*[trtext=\TTTrue,fltext=\TTFalse]{#3}{#5} \\ \hline
			}%
		\CodeAfter
			\IfStrEq{\TTABLEcodeafter}{}{}{\TTABLEcodeafter}%
	\end{NiceTabular}%
}

\fi

\endinput