% Custom generic preamble; supports texlive 2022
\ProvidesPackage{preamble}

% ----- Package options -----

% initialize options

\newif\ifopt@tikz\opt@tikztrue  % default true
\newif\ifopt@pgfexternal\opt@pgfexternalfalse
\newif\ifopt@circuits\opt@circuitsfalse
\newif\ifopt@enumerate\opt@enumeratefalse
\newif\ifopt@colorlinks\opt@colorlinksfalse

\newif\ifopt@lecturenewpage\opt@lecturenewpagefalse
\newif\ifopt@tcbtheorems\opt@tcbtheoremsfalse
\newif\ifopt@fancysections\opt@fancysectionsfalse
\newif\ifopt@bibtex\opt@bibtexfalse
\newif\ifopt@refsegments\opt@refsegmentsfalse

\newif\ifopt@cheatsheetlengths\opt@cheatsheetlengthsfalse
\newif\ifopt@smallercomponents\opt@smallercomponentsfalse
\newif\ifopt@narrowmargins\opt@narrowmarginsfalse
\newif\ifopt@minipagerestore\opt@minipagerestoretrue  % default true

\newif\ifopt@asymptote\opt@asymptotefalse
\newif\ifopt@minted\opt@mintedfalse
\newif\ifopt@tcbminted\opt@tcbmintedfalse

\newif\ifopt@times\opt@timesfalse

\newif\ifoptgroup@homework\optgroup@homeworkfalse
\newif\ifoptgroup@lecture\optgroup@lecturefalse
\newif\ifoptgroup@cheatsheet\optgroup@cheatsheetfalse
\newif\ifoptgroup@beamer\optgroup@beamerfalse
\newif\ifoptgroup@exam\optgroup@examfalse

\gdef\auxdir{out}

% declare options

\DeclareOption{tikz}{%
    \opt@tikztrue%
    \opt@circuitstrue%
}
\DeclareOption{circuits}{\opt@circuitstrue}  % enable circuits
\DeclareOption{pgfexternal}{\opt@pgfexternaltrue}  % enable externalizing pgf figures

\DeclareOption{lecturenewpage}{\opt@lecturenewpagetrue}  % add \newpage after every lecture
\DeclareOption{tcbtheorems}{\opt@tcbtheoremstrue}  % tcolorbox for theorems
\DeclareOption{bibtex}{\opt@bibtextrue}  % use bibtex
\DeclareOption{nobibtex}{\opt@bibtexfalse}  % disable bibtex
\DeclareOption{refsegments}{\opt@refsegmentstrue}  % add reference sections around each lecture section

\DeclareOption{asymptote}{\opt@asymptotetrue}
\DeclareOption{enumerate}{\opt@enumeratetrue}

\DeclareOption{narrowmargins}{\opt@narrowmarginstrue}
\DeclareOption{cheatsheetlengths}{\opt@cheatsheetlengthstrue}
\DeclareOption{smallercomponents}{\opt@smallercomponentstrue}
\DeclareOption{minipagerestore}{\opt@minipagerestoretrue}
\DeclareOption{fancysections}{\opt@fancysectionstrue}
\DeclareOption{minted}{\opt@mintedtrue}
\DeclareOption{tcbminted}{\opt@mintedtrue\opt@tcbmintedtrue}
\DeclareOption{colorlinks}{\opt@colorlinkstrue}

\DeclareOption{notikz}{\opt@tikzfalse}
\DeclareOption{nocircuits}{\opt@circuitsfalse}
\DeclareOption{notcbtheorems}{\opt@tcbtheoremsfalse}
\DeclareOption{nocheatsheetlengths}{\opt@cheatsheetlengthsfalse}
\DeclareOption{nosmallercomponents}{\opt@smallercomponentsfalse}
\DeclareOption{nominipagerestore}{\opt@minipagerestorefalse}
\DeclareOption{nofancysections}{\opt@fancysectionsfalse}
\DeclareOption{noenumerate}{\opt@enumeratefalse}

\DeclareOption{times}{\opt@timestrue}

% option groups

\DeclareOption{homework}{%
    \optgroup@homeworktrue%
    \opt@tikztrue%
    \opt@circuitstrue%
    %\opt@enumeratetrue%
}

\DeclareOption{lecture}{%
    \optgroup@lecturetrue%
    \opt@tikztrue%
    \opt@circuitstrue%
    \opt@tcbtheoremstrue%
    \opt@fancysectionstrue%
    \opt@bibtextrue%
}

\DeclareOption{cheatsheet}{%
    \optgroup@cheatsheettrue%
    \opt@tikztrue%
    \opt@circuitstrue%
    \opt@narrowmarginstrue%
    \opt@cheatsheetlengthstrue%
    \opt@smallercomponentstrue%
}

\DeclareOption{beamer}{%
    \optgroup@beamertrue%
    \opt@tikztrue%
    \opt@circuitstrue%
}

\DeclareOption{exam}{%
    \optgroup@examtrue%
    \opt@tikztrue%
    \opt@circuitstrue%
}

\DeclareOption*{%
    \PackageWarning{preamble}{Unknown option '\CurrentOption'}
}

\ExecuteOptions{}
\ProcessOptions*

% ----- Packages -----

\RequirePackage{mathdots}  % more dots in math mode; before amsmath because of warnings

% AMS
\RequirePackage{amsmath}
\ifoptgroup@beamer
    % beamer conflicts with amsthm
\else
    \RequirePackage{amsthm}
\fi

% Font
\ifoptgroup@beamer
    \usefonttheme{professionalfonts}
\fi
\RequirePackage[T1]{fontenc}

\ifopt@times
    \RequirePackage{newtxtext}
    \RequirePackage[smallerops]{newtxmath}
\else
    \RequirePackage{amssymb}
    \RequirePackage{anyfontsize}
    \RequirePackage{fourier}
    \RequirePackage{mathrsfs}
    \RequirePackage[cal=cm]{mathalpha}
    %\DeclareMathAlphabet{\mathcal}{OMS}{cmsy}{m}{n}
    % sans-serif font
    \usepackage[semibold,scale=0.97]{sourcesanspro}
    % no small caps + italic, so just use small caps
    \AtBeginDocument{\DeclareFontShape{T1}{futs}{m}{scit}{<->ssub*futs/m/sc}{}}
    \usepackage{pifont}  % for dingbats and other symbols
\fi

\RequirePackage[table]{xcolor}  % Colored text
% dark green definition, as green is too bright
\colorlet{darkgreen}{green!60!black}
% dark red definition
\colorlet{darkred}{red!60!black}
% dark blue definition
\colorlet{darkblue}{blue!60!black}

% Math shortcuts
\RequirePackage{siunitx}  % formatting SI units (loaded before physics to avoid warning)
\RequirePackage{physics-minimal, systeme, mathtools, nccmath}
\RequirePackage{centernot}  % \centernot command
\RequirePackage{cancel}  % cancel numbers
\RequirePackage{signchart}  % sign charts
\RequirePackage{multirow}
\RequirePackage{thmtools}
% \RequirePackage{kbordermatrix}  % border text on matrices
\RequirePackage[short]{optidef}  % optimization problem definitions
\RequirePackage[single]{accents}  % fixes some nested accent issues with amsmath, adds manual accent set
\RequirePackage[replace]{widebar}  % custom package for wider/better \bar{}
\RequirePackage{xfrac}  % fraction types
\RequirePackage{stackrel}

% siunitx per symbol
\sisetup{per-mode=symbol}

% Math font
% \RequirePackage{mathrsfs}  % Raph Smith's Formal Script font

% Tables
\RequirePackage{booktabs}  % Improved tables
\RequirePackage{threeparttable}  % Footnotes in tables

% Graphics
\RequirePackage{graphicx}  % External graphics
\RequirePackage[all]{xy}  % Diagrams
\RequirePackage{caption, subcaption}  % subfigures
\captionsetup{labelfont+=bf,format=hang}
\ifoptgroup@beamer
    % geometry package already loaded; causes conflicts
\else
    \ifopt@narrowmargins
        \RequirePackage[margin=0.6in, headheight=14pt, headsep=10pt]{geometry}
    \else
        \RequirePackage[margin=1in, headheight=14pt]{geometry}
    \fi
\fi

\ifoptgroup@lecture
    % change counters to include section number
    \RequirePackage{chngcntr}
    \counterwithin{figure}{section}
    \counterwithin{table}{section}
    \counterwithin{equation}{section}
\fi


% Headers
\ifoptgroup@beamer
    % no headers if beamer
\else
    \ifoptgroup@exam
        % no headers if exam; use exam class headers
    \else
        \RequirePackage{fancyhdr, titling}
        \RequirePackage[explicit]{titlesec}  % fancy section headers
        \RequirePackage{titletoc}
    \fi
\fi

% Formatting
\RequirePackage{multicol}  % Multiple columns in document
\ifopt@tcbtheorems
    \RequirePackage[titles]{tocloft}  % custom table of contents listings; required to be before parskip
\fi
\RequirePackage{parskip, float}
\RequirePackage{microtype}  % Micro-kerning
\RequirePackage{enumitem}  % enumerate item labels
\RequirePackage{aliascnt}  % creating counter aliases
\RequirePackage{bm}
\RequirePackage{changepage}  % custom margin adjustment
\RequirePackage{pdflscape}  % landscape pages
\RequirePackage{oubraces}  % better over/under braces
\RequirePackage{textcomp}
\RequirePackage{soul}

% multicols columnbreak vertical fill
\let\oldcolumnbreak\columnbreak%
\renewcommand\columnbreak{\vfill\null\oldcolumnbreak}

% Code input formatting
\RequirePackage{listings}  % code environment
\RequirePackage{lstautogobble}  % auto-gobble leading whitespace
% Atom One Light color scheme (https://github.com/atom/atom/tree/master/packages/one-light-syntax/styles)
\definecolor{lstfgcolor}{RGB}{56, 58, 66}  % HSL(230, 8%, 24%); black
\definecolor{lstbgcolor}{RGB}{250, 250, 250}  % HSL(230, 1%, 98%); white
\definecolor{lstcommentcolor}{RGB}{160, 161, 167}  % HSL(230, 4%, 64%); gray
\definecolor{lstidentifiercolor}{RGB}{228, 86, 73}  % HSL(5, 74%, 59%); red
\definecolor{lststringcolor}{RGB}{93, 147, 92}  % HSL(119, 23%, 47%); green
\definecolor{lstkeywordcolor}{RGB}{166, 38, 164}  % HSL(301, 63%, 40%); purple
\definecolor{lstlinenumbercolor}{RGB}{157, 157, 159}  % HSL(230, 1%, 62%)
\lstset{%
    autogobble,
    columns=fullflexible,
    numbers=left,
    upquote=true,
    mathescape=true,
    xleftmargin=3pt,
    numbersep=7pt,
    breaklines=true,
    postbreak=\mbox{$\hookrightarrow$\space},
    % colors
    backgroundcolor=\color{lstbgcolor},
    basicstyle=\color{lstfgcolor}\small\ttfamily,
    commentstyle=\color{lstcommentcolor}\itshape,
    identifierstyle={},%\color{lstidentifiercolor},
    stringstyle=\color{lststringcolor},
    keywordstyle=\color{lstkeywordcolor},%\bfseries,
    numberstyle=\color{lstlinenumbercolor}\ttfamily,
}
\lstdefinelanguage{pseudo}{
    morekeywords={
        % Python
        false, true, and, assert, break, class, continue, def, elif, else, for, if, in, is, not, or, pass, return, while,
        % Lua
        end, repeat, do, then, function, until,
        % Other
        to,
    },
    sensitive=false,
    morestring=[b]",
    morestring=[b]',
    morecomment=[l]{//},
    morecomment=[s]{/*}{*/}
}

% Alternative code formatting with minted package
\ifopt@minted
    \RequirePackage[outputdir=out]{minted}
    \RequirePackage{fancyvrb}
    \setminted{%
        autogobble,
        breaklines,
        linenos,
        mathescape,
        python3,
        fontsize=\small,
        %bgcolor=lstbgcolor,  % no bgcolor if using tcolorbox
        numbersep=4pt,
        style=atomonelight,  % custom minted style; falls back to default style
    }
    \renewcommand{\theFancyVerbLine}{\ttfamily \textcolor{lstlinenumbercolor}{\arabic{FancyVerbLine}}}
    \fvset{listparameters=\setlength{\topsep}{0pt}\setlength{\partopsep}{0pt}}

    % tcolorbox integration with minted
    \RequirePackage{tcolorbox}
    \RequirePackage{tikz}
    \tcbuselibrary{breakable, skins, minted, hooks}
    \tcbuselibrary{raster}  % for side-by-side code
    \tcbset{listingoverridestyle/.style={}}
    % Usage: \begin{tminted}[minted options]{language}[tcb options]
    %\newtcblisting{tminted}[2][]{
    %    minted language=#2,
    %    minted options pre={numbersep=7pt},
    %    listing only,
    %    enhanced jigsaw, breakable,
    %    size=small,
    %    coltitle=black, colback=lstbgcolor,
    %    frame hidden, arc=2pt,
    %    grow to left by=1pt, left=0pt,
    %    toptitle=0pt, bottomtitle=2pt,
    %    listingoverridestyle,
    %    #1
    %}
    \NewTCBListing{tminted}{ O{} m !O{} }{%
        minted language=#2,
        minted options pre={numbersep=7pt, #1},
        listing only,
        enhanced jigsaw, breakable,
        size=small,
        coltitle=black, colback=lstbgcolor,
        frame hidden, arc=2pt,
        grow to left by=1pt, left=0pt,
        toptitle=0pt, bottomtitle=2pt,
        listingoverridestyle,
        #3
    }
    \tcbset{
        sidebysideraster/.style={
            enhanced,
            listing only,
            raster columns=2,
            raster equal height=rows,
            raster left skip=0pt, raster right skip=0pt,
            raster column skip=12pt,
            raster column 1/.style={
                sharp corners=east,
                rightrule=0pt
            },
            raster column 2/.style={
                sharp corners=west,
                leftrule=0pt
            }
        }
    }

    % replace default minted environment with tminted
    \ifopt@tcbminted
        \let\oldminted\minted%
        \let\endoldminted\endminted%
        \let\minted\tminted%
        \let\endminted\endtminted%
    \fi
\fi

% Misc.
\RequirePackage{comment}  % Comment environments
\RequirePackage{xr}  % Cross-references between subfiles
\RequirePackage{subfiles}
\RequirePackage{ifthen}  % latex if/else conditionals
\RequirePackage{suffix}  % commands with suffix
\RequirePackage{xparse}  % custom commands
\RequirePackage{xstring}  % string manipulation commands
\RequirePackage{etoolbox}  % various utilities for command creation

% References
\ifoptgroup@beamer
    % hyperref already loaded, cleveref doesn't work with beamer
    \hypersetup{hidelinks}
\else
    \PassOptionsToPackage{hidelinks,hypertexnames=false}{hyperref}  % allow for option overrides
    \RequirePackage{hyperref}  % Links
    \hypersetup{
        hypertexnames=false,  % avoid conflicts in hyperref names
        linktoc=all,  % link toc numbers along with text
    }
    \RequirePackage[capitalize]{cleveref}  % better references

    % setting to color all links
    \ifopt@colorlinks
        \hypersetup{colorlinks=true,linktoc=all,allcolors=blue}
    \fi
\fi
\RequirePackage{bookmark}  % hyperref extension
\robustify{\label}  % protect the label command

% bibtex
\ifopt@bibtex
    \RequirePackage[backend=biber,style=alphabetic,minnames=3,minalphanames=3,maxbibnames=999]{biblatex}  % bibtex citations
    \setlength{\bibitemsep}{\parsep}  % add space between bibliography items
    \setcounter{biburlnumpenalty}{9000}  % allow line breaks on numbers, but inflict high penalty
    % only show URL if DOI not specified
    \DeclareSourcemap{%
        \maps[datatype=bibtex]{%
            \map[overwrite]{%
                \step[fieldsource=doi, final]
                \step[fieldset=url, null]
            }
        }
    }
\fi

% Tikz, pgfplots
\ifopt@tikz
    \RequirePackage{tikz, pgfplots}  % Drawings
    \RequirePackage{tikz-qtree}  % Easy trees in tikz
    \RequirePackage{tikz-3dplot}  % 3d views
    \RequirePackage{pgfplotstable}  % pgfplots tables

    \ifopt@pgfexternal
        \usepgfplotslibrary{external}  % externalize to speed up
        \tikzexternalize
        % use job name (filename) as inner folder
        \tikzsetexternalprefix{figures/\tikzexternalrealjob/}
        %\tikzset{external/force remake}
    \fi

    % Circuits
    \ifopt@circuits
        \RequirePackage[american,oldvoltagedirection,straightlabels,siunitx]{circuitikz}  % Circuits
        \RequirePackage[electronic]{ifsym}  % circuit comparator label with \FallingEdge or \RaisingEdge

        \tikzset{highlight/.style={opacity=0.5, line width=2pt}}
        \ctikzset{monopoles/vcc/arrow={Bar[width=3mm]}}  % Change VDD/VSS arrows to bars
        \ctikzset{monopoles/vee/arrow={Bar[width=3mm]}}

        % resize - characters to occupy same space as +
        \ctikzset{bipoles/vsourceam/inner minus/.initial={$\vphantom{+}-$}}
        \ctikzset{bipoles/cvsourceam/inner minus/.initial={$\vphantom{+}-$}}
        \ctikzset{voltage/american minus/.initial={$\vphantom{+}-$}}

        \ifopt@smallercomponents
            \ctikzset{resistors/scale=0.8, capacitors/scale=0.8, amplifiers/scale=0.8, sources/scale=0.8, csources/scale=0.8, logic ports/scale=0.8}
        \fi
    \fi

    \pgfplotsset{compat=1.17}

    \usetikzlibrary{calc,trees,positioning,arrows,fit,shapes,calc,intersections,fadings,decorations,decorations.markings,decorations.pathmorphing,calligraphy,matrix,math,patterns,patterns.meta}
    \usepgfplotslibrary{fillbetween,patchplots,groupplots,statistics}
    \usepgfplotslibrary{colorbrewer}

    %\pgfkeys{/pgf/plot/gnuplot call={cd \auxdir && gnuplot}}  % set gnuplot directory
    % edit contour gnuplot command, which needs special configuration
    \ifopt@pgfexternal
    \else% only set if not externalize
    \pgfplotsset{
        contour gnuplot/.style={
            contour external={%
                scanline marks=required,
                script={
                    unset surface;
                    \ifx\thecontourlevels\empty
                    set cntrparam levels \thecontournumber;
                    \else
                    set cntrparam levels discrete \thecontourlevels;
                    \fi
                    set contour;
                    set table \"\outfile\";
                    splot \"\infile\";
                },
                cmd={cd \auxdir && gnuplot \"\script\"},%
                #1,%
            },
        },
    }
    \fi

    % set color map limit because zathura can't handle it
    \def\pgfplotscolormappdfmax{1} \def\pgfplotscolormappdfmax@inv{1000}

    % tikz-qtree
    \tikzset{
        /tikz/qtree/.style={
            level distance=20pt,
        },
        /tikz/bracketedges/.style={
            edge from parent/.style={draw, edge from parent path={
                (\tikzparentnode.south) -- +(0,-4pt) -| (\tikzchildnode)}
            }
        },
        /tikz/flatfrontier/.style={frontier/.style={distance from root=#1}},
        /tikz/flatfrontierlevels/.style={frontier/.style={distance from root={#1*20pt}}}
    }

    % Markov chains
    \usetikzlibrary{automata}
    \tikzset{%
        >=latex,
        every state/.style={thick, fill=gray!10},
        /tikz/markov/.style={%
            ->,  % directed edges
            every picture/.style={line width=0.75pt},
            node distance=30pt,
            initial text=$ $,
            every loop/.style={looseness=5},
            loop left/.append style={in=155, out=-155, looseness=5},  % change shape of loops
            loop right/.append style={in=-25, out=25, looseness=5},
            loop above/.append style={in=65, out=115, looseness=5},
            loop below/.append style={in=-115, out=-65, looseness=5},
            /tikz/wide/.style={%
                node distance=50pt
            },
            /tikz/empty/.append style={minimum size=15pt},
            /tikz/narrow/.style={%
                node distance=20pt
            },
        }
    }
    % 3d plots
    \tikzset{%
        /tikz/3dplot/.style={%
            /pgfplots/every axis/.append style={%
                xlabel style={anchor=south west},
                ylabel style={anchor=south west},
                zlabel style={anchor=south west}
            },
            /pgfplots/every axis plot/.append style={surf,shader=faceted,opacity=0.5}
        }
    }
    % arrows on paths
    \tikzset{
        set arrow inside/.code={\pgfqkeys{/tikz/arrow inside}{#1}},
        set arrow inside={end/.initial=>, opt/.initial=},
        /pgf/decoration/Mark/.style={
            mark/.expanded=at position #1 with {
                \noexpand\arrow[\pgfkeysvalueof{/tikz/arrow inside/opt}]{\pgfkeysvalueof{/tikz/arrow inside/end}}
            }
        },
        arrow inside/.style 2 args={
            set arrow inside={#1},
            postaction={
                decorate, decoration={ markings,Mark/.list={#2} }
            }
        },
    }
    % other shapes
    \tikzset{
        triangle/.style={regular polygon, regular polygon sides=3, inner sep=2pt, anchor=north}
    }
    % node fitting around a path
    \tikzset{
        fitting node/.style={
            inner sep=0pt,
            fill=none,
            draw=none,
            reset transform,
            fit={(\pgf@pathminx,\pgf@pathminy) (\pgf@pathmaxx,\pgf@pathmaxy)}
        },
        reset transform/.code={\pgftransformreset}
    }

    % box and pointer diagrams
    \tikzset{
        /tikz/boxandpointer/.style={
            node distance=0pt and 0pt,
            /tikz/element/.append style={
                outer sep=0pt,
                minimum size=20pt
            }
        }
    }

    % tikz array diagram
    % syntax: \tikzarray[start coord]{label prefix}{elements}
    \NewDocumentCommand{\tikzarray}{ O{0,0} m m }{%
        \node[outer sep=0pt, inner sep=0pt] (#2-0) at (#1) {};
        \foreach[count=\i] \x in {#3} {
            \pgfmathtruncatemacro\prev{\i - 1}
            \node[element, draw, right=0pt of #2-\prev] (#2-\i) {\x};
        }
    }
    \NewDocumentCommand{\tikzarrayvert}{ O{0,0} m m }{%
        \node[outer sep=0pt, inner sep=0pt] (#2-0) at (#1) {};
        \foreach[count=\i] \x in {#3} {
            \pgfmathtruncatemacro\prev{\i - 1}
            \node[outer sep=0pt, minimum size=20pt, draw, below=of #2-\prev] (#2-\i) {\x};
        }
    }
    \RequirePackage{xstring}
    \newcommand*{\commalength}[1]{%
        \StrCount{#1,}{,}%
    }
    % tikz linked list diagram
    % syntax: \tikzlinkedlist[start coord][arrow length]{label prefix}{elements}
    \NewDocumentCommand{\tikzlinkedlist}{ s O{0,0} O{0.5} m m }{%
        \edef\startcoord{#2}
        \edef\arrowlength{#3}
        \edef\labelprefix{#4}
        % count elements in list first
        \foreach[count=\i] \x in {#5} { \xdef\numelements{\i} }
        \node[outer sep=0pt, inner sep=0pt] (\labelprefix-arrow-0) at (\startcoord) {};
        \foreach[count=\i] \x in {#5} {
            \pgfmathsetmacro\prev{\i - 1}
            \node[anchor=west, element, draw] at (\labelprefix-arrow-\prev) (\labelprefix-\i) {\x};
            \xdef\last{\i}
            \IfBooleanTF{#1}{
                % don't draw last arrow
                \ifnum\last<\numelements\relax
                    \draw[->] (\labelprefix-\i.east) -- ++(\arrowlength,0) node[outer sep=0pt, inner sep=0pt, minimum size=0pt] (\labelprefix-arrow-\i) {};
                \fi
                }{
                \draw[->] (\labelprefix-\i.east) -- ++(\arrowlength,0) node[outer sep=0pt, inner sep=0pt, minimum size=0pt] (\labelprefix-arrow-\i) {};
            }
        }
        \IfBooleanTF{#1}{}{
            \node[anchor=west] (\labelprefix-end) at (\labelprefix-arrow-\last) {$\emptyset$};
        }
    }

    % 3d cylinder between two points; does NOT work for vertical cylinders (i.e. only changing z coordinate)
    % \tikzcylinderbetween[tikz arguments]{start_x}{start_y}{start_z}{end_x}{end_y}{end_z}
    \NewDocumentCommand{\tikzcylinderbetween}{ O{} m m m m m m m }{%
        \edef\r{(#2)}
        \edef\sx{(#3)}
        \edef\sy{(#4)}
        \edef\sz{(#5)}
        \edef\ex{(#6)}
        \edef\ey{(#7)}
        \edef\ez{(#8)}
        \edef\vx{(\ex-\sx)}
        \edef\vy{(\ey-\sy)}
        \edef\vz{(\ez-\sz)}
        \edef\mag{sqrt(\vx^2 + \vy^2 + \vz^2)}

        % Mathematica code to generate this vector:
        % FullSimplify[
        %   TransformationMatrix[
        %     RotationTransform[{{0, 0, 1}, {Subscript[v, x], Subscript[v, y], Subscript[v, z]}}]
        %   ],
        % Assumptions -> {Subscript[v, x] \[Element] Reals, Subscript[v, y] \[Element] Reals, Subscript[v, z] \[Element] Reals}
        % ]
        % . ( { {r Cos[t]}, {r Sin[t]}, {x}, {1} } )
        % + ( { {Subscript[s, x]}, {Subscript[s, y]}, {Subscript[s, z]}, {0} } )
        \addplot3[domain=0:\mag, domain y=0:360, variable y=t, #1] (
            {\sx + (x*\vx)/\mag + (\r*sin(t)*\vx*\vy*(-1 + \vz/\mag))/(\vx^2 + \vy^2) + (\r*cos(t)*(\vy^2 + (\vx^2*\vz)/\mag))/(\vx^2 + \vy^2)},
            {\sy + (x*\vy)/\mag + (\r*cos(t)*\vx*\vy*(-1 + \vz/\mag))/(\vx^2 + \vy^2) + (\r*sin(t)*(\vx^2 + (\vy^2*\vz)/\mag))/(\vx^2 + \vy^2)},
            {\sz - (\r*cos(t)*\vx)/\mag - (\r*sin(t)*\vy)/\mag + (x*\vz)/\mag}
        );
    }
    % vertical 3D cylinder
    % \tikzcylinderbetween[]{r}{x}{y}{start_z}{end_z}
    \NewDocumentCommand{\tikzcylindervertical}{ O{} m m m m m }{%
        \edef\r{#2}
        \edef\offsetx{#3}
        \edef\offsety{#4}
        \edef\sz{#5}
        \edef\ez{#6}

        \addplot3[domain=\sz:\ez, domain y=0:360, variable y=t, #1] (
            {\offsetx + \r*cos(t)},
            {\offsety + \r*sin(t)},
            {x}
        );
    }
\fi

% Asymptote
\ifopt@asymptote
    \RequirePackage{asymptote}
    \def\asydir{asy}  % Custom directory for asymptote files
\fi

\usepackage[ISO]{diffcoeff}  % derivatives
% change evaluation bar to |
\difdef{f}{}{outer-Ldelim=\left., outer-Rdelim=\right|, sub-nudge=0mu}
\difdef{f}{p}{op-symbol=\partial, outer-Ldelim=\left., outer-Rdelim=\right|, sub-nudge=0mu}
\RenewDocumentCommand\diffp{}{\diff.p.}

% ----- Math Operators -----

\renewcommand{\Re}{\operatorname{Re}}  % real part
\renewcommand{\Im}{\operatorname{Im}}  % imaginary part

\DeclareMathOperator{\proj}{proj}  % Projection
\DeclareMathOperator{\range}{range}  % Range (span of columns)
\DeclareMathOperator{\Range}{R}  % range
\DeclareMathOperator{\Null}{N}  % Null space
\DeclareMathOperator{\Cols}{C}  % Col space
\DeclareMathOperator{\Ker}{Ker}  % Kernel (null space)
\DeclareMathOperator{\Image}{Im}  % Image
\DeclareMathOperator{\trace}{tr}
\DeclareMathOperator{\rank}{rank}
\DeclareMathOperator{\nullity}{null}
\DeclareMathOperator{\Trace}{Tr}
\DeclareMathOperator{\Adj}{Adj}  % Adjoint
\DeclareMathOperator{\id}{id}
\newcommand{\diag}{\opbraces{\operatorname{diag}}}
\DeclareMathOperator{\lcm}{lcm}

\DeclareMathOperator{\erf}{erf}  % Gauss error function
\DeclareMathOperator{\corr}{corr}  % correlation

\newcommand{\Oh}{\opbraces{O}}  % Big oh
\newcommand{\oh}{\opbraces{o}}  % Little oh

\DeclareMathOperator{\sign}{sign}
\DeclareMathOperator{\poly}{poly}  % polynomial
\DeclareMathOperator{\polylog}{polylog}  % polynomial log
\DeclareMathOperator{\size}{size}
\DeclareMathOperator{\depth}{depth}
\DeclareMathOperator{\val}{val}
\DeclareMathOperator{\rev}{rev}
\DeclareMathOperator{\cost}{cost}

\DeclareMathOperator{\diam}{diam}  % diameter
\DeclareMathOperator{\length}{length}  % length
\DeclareMathOperator{\Residue}{Res}  % residue
\DeclareMathOperator{\Log}{Log}  % complex log
\DeclareMathOperator{\Arg}{Arg}  % complex argument

\DeclareMathOperator{\len}{len}  % length
\DeclareMathOperator{\ord}{ord}  % order
\DeclareMathOperator{\orb}{orb}  % orbit
\DeclareMathOperator{\Syl}{Syl}  % Sylow

\DeclareMathOperator{\from}{\colon}
\newcommand{\divides}{\mid}
\newcommand{\notdivides}{\nmid}
\newcommand{\powerset}{\mathscr{P}}
\newcommand{\inj}{\hookrightarrow}  % injection
\newcommand{\surj}{\twoheadrightarrow}  % surjection

\newcommand{\proves}{\vdash}

\newcommand{\mmid}{\mathop{}\middle\vert\mathop{}}  % \middle\vert with spacing

% \Pr consuming parentheses
%\RenewDocumentCommand{\Pr}{s r()}{\operatorname{\mathbb{P}}\mathopen{}\IfBooleanTF{#1}{}{\opbraces{}}[#2]}
\renewcommand{\Pr}{\operatorname{\mathbb{P}}\mathopen{}\opbraces{}}  % Probability
\WithSuffix\newcommand\Pr*{\operatorname{\mathbb{P}}\mathopen{}}  % Probability (no qty)

\newcommand{\Exp}{\operatorname{\mathbb{E}}\mathopen{}\opbraces{}}  % Expected value
\WithSuffix\newcommand\Exp*{\operatorname{\mathbb{E}}\mathopen{}}  % Expected value (no qty)
\newcommand{\LLSE}{\operatorname{\mathbb{L}}\mathopen{}\opbraces{}}  % Linear least squares estimator
\WithSuffix\newcommand\LLSE*{\operatorname{\mathbb{L}}\mathopen{}}  % Linear least squares estimator (no qty)
\newcommand{\Span}{\operatorname{span}\mathopen{}\opbraces{}}  % Vector/Matrix Span
\WithSuffix\newcommand\Span*{\operatorname{span}\mathopen{}}  % Vector/Matrix Span (no qty)
\DeclareMathOperator{\Char}{char}  % characteristic polynomial
\DeclareMathOperator{\Var}{Var}  % Variance
\DeclareMathOperator{\Cov}{Cov}  % Covariance
\DeclareMathOperator{\Corr}{Corr}  % Correlation

\DeclareMathOperator*{\argmax}{argmax}
\DeclareMathOperator*{\argmin}{argmin}

\newcommand{\va}[1]{\vec{\bm{#1}}}  % Vector with italic bold
\ifopt@times
    \newcommand{\vecbar}[1]{\bar{#1}}  % just use \bar if we're using times
\else
    \newcommand{\vecbar}[1]{\,\overline{\!#1}}  % bar to be used over a vector
\fi
\newcommand{\mat}[1]{\mathbf{#1}}  % Matrix variable

% derivatives
\difdef{l}{delta}{op-symbol=\Delta}
\difdef{l}{p}{op-symbol=\partial}
\difdef{l}{0}{outer-Ldelim=}
\newcommand{\dd}{\dl}
\WithSuffix\newcommand\dd*{\dl.0.}  % derivative d without any prior space (to be used by itself with inline text)
\newcommand{\ddel}{\dl.delta.}
\newcommand{\ddp}{\dl.p.}
\newcommand{\pdd}{\dl.p.}  % alias for \ddp

\newcommand{\definedas}{\coloneqq}
\newcommand{\definedby}{\eqqcolon}

% matrix row/column vector rules
% \newcommand{\rowrule}{\rotatebox[origin=c]{90}{$\vert$}}
\newcommand{\rowrule}{\rule[.5ex]{1em}{0.4pt}}
\newcommand{\colrule}{\vert}

\DeclarePairedDelimiter{\pairedabs}{\lvert}{\rvert}
\newcommand{\abs}[1]{\pairedabs*{#1}}
\DeclarePairedDelimiter{\pairednorm}{\lVert}{\rVert}
\newcommand{\norm}[1]{\pairednorm*{#1}}
\DeclarePairedDelimiter{\pairedvinner}{\langle}{\rangle}  % Inner product
\newcommand{\vinner}[1]{\pairedvinner*{#1}}
\DeclarePairedDelimiter{\pairedfloor}{\lfloor}{\rfloor}
\newcommand{\floor}[1]{\pairedfloor*{#1}}
\DeclarePairedDelimiter{\pairedceil}{\lceil}{\rceil}
\newcommand{\ceil}[1]{\pairedceil*{#1}}
\DeclarePairedDelimiter{\pairedround}{\lfloor}{\rceil}
\newcommand{\round}[1]{\pairedround*{#1}}

\DeclarePairedDelimiter{\pairedeval}{.}{\rvert}  % evaluated at bar
\newcommand{\eval}[1]{\pairedeval*{#1}}

\newcommand{\gen}[1]{\pairedvinner*{#1}}  % alias; for <x> as the generating element of a subgroup
\newcommand{\group}[1]{\operatorname{#1}}  % group names (ex. GF(p), GL(n), SO(n), etc.)

% Distributions
\DeclareMathOperator{\Unif}{Uniform}
\DeclareMathOperator{\Bin}{Bin}
\DeclareMathOperator{\Bern}{Bernoulli}
\DeclareMathOperator{\Geom}{Geom}
\DeclareMathOperator{\Pois}{Pois}
\DeclareMathOperator{\Expdist}{Exp}
\DeclareMathOperator{\Norm}{\mathcal{N}}
\DeclareMathOperator{\PP}{PP}
\DeclareMathOperator{\Erlang}{Erlang}

% Redefine symbols
\let\oldemptyset\emptyset%
\let\emptyset\varnothing%

% Miscellaneous symbols
\newcommand\cmark{\text{\ding{51}}}
\newcommand\xmark{\text{\makebox[0pt][l]{\ding{55}}\hphantom{\ding{51}}}}

% mapsfrom
\ifopt@times
    % already defined
\else
    \newcommand\mapsfrom{\mathrel{\reflectbox{\ensuremath{\mapsto}}}}
\fi

\RequirePackage{proof}  % proof diagrams in mathematical logic
\setlength{\inferLabelSkip}{1em}

% ----- Commands -----

% matrix augment
\renewcommand*\env@matrix[1][*\c@MaxMatrixCols c]{%
    \hskip -\arraycolsep%
    \let\@ifnextchar\new@ifnextchar%
    \array{#1}
}

\NewDocumentCommand{\grad}{e{_^}}{% gradient replacement, from egreg
    \mathop{}\!% \mathop for good spacing before \nabla
    \nabla%
    \IfValueT{#1}{_{\!#1}}% tuck in the subscript
    \IfValueT{#2}{^{#2}}% possible superscript
}

% Zero-pad
\ExplSyntaxOn%
\NewExpandableDocumentCommand{\padinteger}{mm}{%
    \int_compare:nNnTF{#2}<{0}{%
        - \kuttens_padinteger:nn { #1 } { -#2 }
        }{%
        \kuttens_padinteger:nn { #1 } { #2 }
    }
}
\cs_new:Nn \kuttens_padinteger:nn{%
    \prg_replicate:nn{#1-\tl_count:f{\int_to_arabic:n{#2}}}{0}
    \int_to_arabic:n{#2}
}
\cs_generate_variant:Nn \tl_count:n{f}
\ExplSyntaxOff%

% include subfiles, with a prefix, in a range of numbers, zero-padded to the left
\newcommand\seqsubfile[4][0]{%
    \ifnum #1=0%
        \def\endidx{#4}
        \StrLen{\endidx}[\endidxlen]
    \else
        \def\endidxlen{#1}
    \fi
    \foreach \idx in {#3, ..., #4}{%
        \ifopt@refsegments
            \newrefsegment
        \fi
        \def\formatidx{\padinteger{\endidxlen}{\idx}}
        \subfile{#2\formatidx.tex}
        \ifopt@refsegments
            \printbibliography[segment=\idx,heading=subbibliography]
        \fi
        % add new page after every lecture
        \ifopt@lecturenewpage\newpage\fi
    }
}

% system of equations with systeme, but aligning on the right side
\NewDocumentCommand{\systemeright}{ >{\SplitList{,}} m m }{%
    \left\{\begin{aligned}\ProcessList{#1}{\systemeright@aligned}\end{aligned}\sysdelim..\systeme{#2}\right.
}
\NewDocumentCommand{\systemeright@aligned}{m}{#1&=\\}

% circled text
\newcommand*\circled[1]{\tikz[baseline=(char.base)]{\node[shape=circle,draw,inner sep=2pt] (char) {#1};}}
% ----- Theorems -----

% define if outside of conditional
\newif\ifintcbthm%

\ifopt@tcbtheorems
    \RequirePackage{xargs}  % multiple optional arguments
    \RequirePackage{tcolorbox}  % colored boxes
    \tcbuselibrary{theorems}  % use of colored boxes for theorem environments
    \tcbuselibrary{breakable}
    \tcbuselibrary{skins}

    % shield from externalize
    \tcbsetforeverylayer{shield externalize}

    % define lists for all of the environments
    \newlistof[section]{tcbtheorem}{theoremlist}{Theorems}
    \newlistof[section]{tcbexample}{examplelist}{Examples}
    \newlistof[section]{tcbdefinition}{definitionlist}{Definitions}
    \newlistof[section]{tcblemma}{lemmalist}{Lemmas}
    \newlistof[section]{tcbcorollary}{corollarylist}{Corollaries}
    \newlistof[section]{tcbproposition}{propositionlist}{Propositions}

    \setlength{\cfttcbtheoremnumwidth}{25pt}
    \setlength{\cfttcbexamplenumwidth}{25pt}
    \setlength{\cfttcbdefinitionnumwidth}{25pt}
    \setlength{\cfttcblemmanumwidth}{25pt}
    \setlength{\cfttcbcorollarynumwidth}{25pt}
    \setlength{\cfttcbpropositionnumwidth}{25pt}

    % theorem defined first so other counters are shared
    \newtcbtheorem[number within=section, list inside=theoremlist, list type=tcbtheorem]{tcbtheorem}{Theorem}{%
        enhanced, breakable,
        colback=blue!5, colbacktitle=blue!20, coltitle=black,
        frame hidden, parbox=false,
        arc=2pt, titlerule=0pt, toptitle=2pt, bottomtitle=2pt,
        fonttitle=\bfseries,
        segmentation style={solid, draw=blue!20, line width=1pt},
        label type=tcb@cnt@tcbtheorem
    }{thm}
    \newenvironmentx{theorem}[2][1={},2={}]{%
        \intcbthmtrue%
        \begin{tcbtheorem}{#1}{#2}%
            }{
        \end{tcbtheorem}
        \intcbthmfalse%
    }

    \newtcbtheorem[use counter from=tcbtheorem, list inside=examplelist, list type=tcbexample]{tcbexample}{Example}{%
        colback=gray!5, colbacktitle=gray!40, coltitle=black,
        frame hidden, arc=2pt, titlerule=0pt, toptitle=2pt, bottomtitle=2pt,
        fonttitle=\bfseries, breakable, enhanced, parbox=false,
        label type=tcb@cnt@tcbexample
    }{ex}
    \newenvironmentx{example}[2][1={},2={}]{%
        \begin{tcbexample}{#1}{#2}
            }{%
        \end{tcbexample}
    }
    \newtcbtheorem[use counter from=tcbtheorem, list inside=definitionlist, list type=tcbdefinition]{tcbdefinition}{Definition}{%
        colback=red!5, colbacktitle=red!20, coltitle=black,
        frame hidden, arc=2pt, titlerule=0pt, toptitle=2pt, bottomtitle=2pt,
        fonttitle=\bfseries, breakable, enhanced, parbox=false,
        label type=tcb@cnt@tcbdefinition
    }{def}
    \newenvironmentx{definition}[2][1={},2={}]{%
        \begin{tcbdefinition}{#1}{#2}
            }{%
        \end{tcbdefinition}
    }
    \newtcbtheorem[use counter from=tcbtheorem, list inside=lemmalist, list type=tcblemma]{tcblemma}{Lemma}{%
        enhanced, breakable,
        colback=blue!5, colbacktitle=blue!20, coltitle=black,
        frame hidden, parbox=false,
        arc=2pt, titlerule=0pt, toptitle=2pt, bottomtitle=2pt,
        fonttitle=\bfseries,
        segmentation style={solid, draw=blue!20, line width=1pt},
        label type=tcb@cnt@tcblemma
    }{lem}
    \newenvironmentx{lemma}[2][1={},2={}]{%
        \intcbthmtrue%
        \begin{tcblemma}{#1}{#2}
            }{%
        \end{tcblemma}
        \intcbthmfalse%
    }
    \newtcbtheorem[use counter from=tcbtheorem, list inside=corollarylist, list type=tcbcorollary]{tcbcorollary}{Corollary}{%
        enhanced, breakable,
        colback=blue!5, colbacktitle=blue!20, coltitle=black,
        frame hidden, parbox=false,
        arc=2pt, titlerule=0pt, toptitle=2pt, bottomtitle=2pt,
        fonttitle=\bfseries,
        segmentation style={solid, draw=blue!20, line width=1pt},
        label type=tcb@cnt@tcbcorollary
    }{cor}
    \newenvironmentx{corollary}[2][1={},2={}]{%
        \intcbthmtrue%
        \begin{tcbcorollary}{#1}{#2}
            }{%
        \end{tcbcorollary}
        \intcbthmfalse%
    }
    \newtcbtheorem[use counter from=tcbtheorem, list inside=propositionlist, list type=tcbproposition]{tcbproposition}{Proposition}{%
        enhanced, breakable,
        colback=blue!5, colbacktitle=blue!20, coltitle=black,
        frame hidden, parbox=false,
        arc=2pt, titlerule=0pt, toptitle=2pt, bottomtitle=2pt,
        fonttitle=\bfseries,
        segmentation style={solid, draw=blue!20, line width=1pt},
        label type=tcb@cnt@tcbproposition
    }{prop}
    \newenvironmentx{proposition}[2][1={},2={}]{%
        \intcbthmtrue%
        \begin{tcbproposition}{#1}{#2}
            }{%
        \end{tcbproposition}
        \intcbthmfalse%
    }
    % redefine proof environment
    \expandafter\let\expandafter\oldproof\csname\string\proof\endcsname%
    \let\oldendproof\endproof%
    \renewenvironment{proof}[1][\proofname]{%
        \ifintcbthm\tcbline*\fi
        \oldproof[#1]
        }{
        \oldendproof%
    }
    % cleveref definitions
    % \crefname{tcb@cnt@tcbexample}{example}{examples}
    \Crefname{tcb@cnt@tcbexample}{Example}{Examples}
    % \crefname{tcb@cnt@tcbdefinition}{definition}{definitions}
    \Crefname{tcb@cnt@tcbdefinition}{Definition}{Definitions}
    % \crefname{tcb@cnt@tcbtheorem}{theorem}{theorems}
    \Crefname{tcb@cnt@tcbtheorem}{Theorem}{Theorems}
    % \crefname{tcb@cnt@tcblemma}{lemma}{lemmas}
    \Crefname{tcb@cnt@tcblemma}{Lemma}{Lemmas}
    % \crefname{tcb@cnt@tcbcorollary}{corollary}{corollaries}
    \Crefname{tcb@cnt@tcbcorollary}{Corollary}{Corollaries}
    % \crefname{tcb@cnt@tcbproposition}{proposition}{propositions}
    \Crefname{tcb@cnt@tcbproposition}{Proposition}{Propositions}
\else
    \ifoptgroup@beamer
        % beamer overrides theorem environments
    \else
        % plain theorems
        \newtheorem{theorem}{Theorem}[section]
        \newtheorem{lemma}{Lemma}[section]
        \newtheorem{definition}{Definition}[section]
    \fi
\fi

% Fancy section titles
\ifopt@fancysections
    \def\sec@sectiondate{}
    \def\sec@sectiondesc{}
    \newcommand\sectiondate[1]{\def\sec@sectiondate{#1}}
    \newcommand\sectiondesc[1]{\def\sec@sectiondesc{#1}}

    \titleclass{\lecturesection}[0]{straight}%[\chapter]
    \newcommand{\toclevel@lecturesection}{1}
    \renewcommand{\ttll@lecturesection}{1}
    \newcommand{\thelecturesection}{\arabic{lecturesection}}
    %\titleclass{\section}{straight}{\chapter}
    \newaliascnt{lecturesection}{section}
    \contentsmargin{2.5em}
    \titlecontents{lecturesection}[1.5em]{\addvspace{1em}\bfseries}{\contentslabel{1.5em}}{}{\hfill\contentspage}
    \titlespacing*{\lecturesection}{0pt}{2\baselineskip}{1\baselineskip}

    \newcommand\lecture[2][]{\ifthenelse{\equal{#1}{}}{\sectiondate{}}{\sectiondate{#1}
        \ifopt@pgfexternal\tikzsetfigurename{lec\thesection-}\fi}
    \sectiondesc{#2}\lecturesection[#2]{Lecture \thesection}}

    \titleformat{\lecturesection}[frame]
    {\normalfont}
    {\ifthenelse{\equal{\sec@sectiondate}{}}{}{\filright\enspace\itshape\sec@sectiondate\enspace}}
    {3pt}
    {\centering{\Large\bfseries\filcenter#1}
    \ifthenelse{\equal{\sec@sectiondesc}{}}{}{\\[3pt] {\normalsize\itshape\sec@sectiondesc}}}
    [\def\sec@sectiondate{}\def\sec@sectiondesc{}]

    % replace bibliography section
    % \patchcmd{\thebibliography}{\section*{\refname}}{\lecturesection*{\refname}}
    \defbibheading{bibliography}[\refname]{\lecturesection*{#1}\markboth{#1}{#1}}
\fi

% ----- Environments -----
\colorlet{answercolor}{blue!80!black}
\colorlet{mintedanswercolor}{blue!3!white}
\ifoptgroup@exam
    \newenvironment{answer}{%
        \begin{solution}
    }{
        \end{solution}
    }
\else
    \newenvironment{answer}{%
        \begin{adjustwidth}{1.25em}{1.25em}
            \color{answercolor}
            \tikzset{color=answercolor}
            \ifopt@minted
                \ifopt@tcbminted
                    \tcbset{listingoverridestyle/.style={colback=mintedanswercolor}}
                \else
                    \setminted{bgcolor=mintedanswercolor}
                \fi
            \fi
            }{%
            \tikzset{color=black}
            \ifopt@minted
                \ifopt@tcbminted
                    \tcbset{listingoverridestyle/.style={}}
                \else
                    \setminted{bgcolor=lstbgcolor}
                \fi
            \fi
        \end{adjustwidth}
    }
\fi

% ----- Enumerate labels -----

\ifopt@enumerate
    \setlist[enumerate, 1]{label=(\alph*)}
    \setlist[enumerate, 2]{label=(\roman*)}
\fi

% ----- Spacing -----

% displaymath spacing
\setlength{\abovedisplayskip}{5pt}
\setlength{\abovedisplayshortskip}{4pt}
\setlength{\belowdisplayskip}{5pt}
\setlength{\belowdisplayshortskip}{4pt}
\allowdisplaybreaks[1]

% add table of contents as a bookmark
\pretocmd{\tableofcontents}{\belowpdfbookmark{\contentsname}{toc}}{}{}

% edit lengths for cheatsheet
\ifopt@cheatsheetlengths
    % change at beginning of document because they reset
    \AtBeginDocument{%
        \setlength{\abovedisplayskip}{2pt plus 1pt minus 2pt}
        \setlength{\belowdisplayskip}{2pt plus 1pt minus 2pt}
        \setlength{\abovedisplayshortskip}{0pt}
        \setlength{\belowdisplayshortskip}{0pt}
        \setlength{\multicolsep}{4pt plus 1pt minus 1pt}
        \setlength{\jot}{2pt}
        \setlength{\columnsep}{3pt}
        \setlength{\parskip}{2pt}
        %\setlength{\topskip}{0pt}
    }

    % lengths for enumerate lists
    \setlist{nosep, leftmargin=10pt}
\fi

% restore minipage lengths
\ifopt@minipagerestore
    \newcommand{\@minipagerestore}{
        \setlength{\parskip}{\medskipamount}
    }
\fi

\ifoptgroup@beamer
    \pdfstringdefDisableCommands{\def\translate#1{#1}}  % \translate causes warning
\fi

% set higher matrix column limit
\setcounter{MaxMatrixCols}{30}
