mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-06-29 16:20:46 +00:00
documentation updates
Former-commit-id: 39653082c9cd026299f6fcabef7446d569704e1f
This commit is contained in:
@ -213,7 +213,7 @@
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
\ifdefined\Shaded\renewenvironment{Shaded}{\begin{tcolorbox}[sharp corners, borderline west={3pt}{0pt}{shadecolor}, enhanced, breakable, interior hidden, frame hidden, boxrule=0pt]}{\end{tcolorbox}}\fi
|
||||
\ifdefined\Shaded\renewenvironment{Shaded}{\begin{tcolorbox}[frame hidden, borderline west={3pt}{0pt}{shadecolor}, sharp corners, boxrule=0pt, enhanced, interior hidden, breakable]}{\end{tcolorbox}}\fi
|
||||
|
||||
\renewcommand*\contentsname{Table of contents}
|
||||
{
|
||||
@ -1746,47 +1746,75 @@ language}\label{function-defined-in-the-language}}
|
||||
\subsection*{Instrospection functions}\label{instrospection-functions}}
|
||||
\addcontentsline{toc}{subsection}{Instrospection functions}
|
||||
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
\texttt{len(x)}is a generic function allowing to retreive the size of
|
||||
a object. It returns the length of a sequences, the number of element
|
||||
in a map like \texttt{annotations}, the number of elements in an
|
||||
array. The reurned value is an \texttt{int}.
|
||||
\end{itemize}
|
||||
\begin{description}
|
||||
\item[\textbf{\texttt{len(x)}}]
|
||||
It is a generic function allowing to retreive the size of a object. It
|
||||
returns the length of a sequences, the number of element in a map like
|
||||
\texttt{annotations}, the number of elements in an array. The reurned
|
||||
value is an \texttt{int}.
|
||||
\item[\textbf{\texttt{contains(map,key)}}]
|
||||
Tests if the \texttt{map} contains a value assciated to \texttt{key}
|
||||
\end{description}
|
||||
|
||||
\hypertarget{cast-functions}{%
|
||||
\subsection*{Cast functions}\label{cast-functions}}
|
||||
\addcontentsline{toc}{subsection}{Cast functions}
|
||||
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
\texttt{int(x)} converts if possible the \texttt{x} value to an
|
||||
integer value. The function returns an \texttt{int}.
|
||||
\item
|
||||
\texttt{numeric(x)} converts if possible the \texttt{x} value to a
|
||||
float value. The function returns a \texttt{float}.
|
||||
\item
|
||||
\texttt{bool(x)} converts if possible the \texttt{x} value to a
|
||||
boolean value. The function returns a \texttt{bool}.
|
||||
\end{itemize}
|
||||
\begin{description}
|
||||
\item[\textbf{\texttt{int(x)}}]
|
||||
Converts if possible the \texttt{x} value to an integer value. The
|
||||
function returns an \texttt{int}.
|
||||
\item[\textbf{\texttt{numeric(x)}}]
|
||||
Converts if possible the \texttt{x} value to a float value. The function
|
||||
returns a \texttt{float}.
|
||||
\item[\textbf{\texttt{bool(x)}}]
|
||||
Converts if possible the \texttt{x} value to a boolean value. The
|
||||
function returns a \texttt{bool}.
|
||||
\end{description}
|
||||
|
||||
\hypertarget{string-related-functions}{%
|
||||
\subsection*{String related functions}\label{string-related-functions}}
|
||||
\addcontentsline{toc}{subsection}{String related functions}
|
||||
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
\texttt{printf(format,...)} allows to combine several values to build
|
||||
a string. \texttt{format} follows the classical C \texttt{printf}
|
||||
syntax. The function returns a \texttt{string}.
|
||||
\item
|
||||
\texttt{subspc(x)} substitutes every space in the \texttt{x} string by
|
||||
the underscore (\texttt{\_}) character. The function returns a
|
||||
\texttt{string}.
|
||||
\end{itemize}
|
||||
\begin{description}
|
||||
\item[\textbf{\texttt{printf(format,...)}}]
|
||||
Allows to combine several values to build a string. \texttt{format}
|
||||
follows the classical C \texttt{printf} syntax. The function returns a
|
||||
\texttt{string}.
|
||||
\item[\textbf{\texttt{subspc(x)}}]
|
||||
substitutes every space in the \texttt{x} string by the underscore
|
||||
(\texttt{\_}) character. The function returns a \texttt{string}.
|
||||
\end{description}
|
||||
|
||||
\hypertarget{condition-function}{%
|
||||
\subsection*{Condition function}\label{condition-function}}
|
||||
\addcontentsline{toc}{subsection}{Condition function}
|
||||
|
||||
\begin{description}
|
||||
\item[\textbf{\texttt{ifelse(condition,val1,val2)}}]
|
||||
The \texttt{condition} value has to be a \texttt{bool} value. If it is
|
||||
\texttt{true} the function returns \texttt{val1}, otherwise, it is
|
||||
returning \texttt{val2}.
|
||||
\end{description}
|
||||
|
||||
\hypertarget{sequence-analysis-related-function}{%
|
||||
\subsection{Sequence analysis related
|
||||
function}\label{sequence-analysis-related-function}}
|
||||
|
||||
\begin{description}
|
||||
\item[\textbf{\texttt{composition(sequence)}}]
|
||||
The nucleotide composition of the sequence is returned as as map indexed
|
||||
by \texttt{a}, \texttt{c}, \texttt{g}, or \texttt{t} and each value is
|
||||
the number of occurrences of that nucleotide. A fifth key
|
||||
\texttt{others} accounts for all others symboles.
|
||||
\item[\textbf{\texttt{gcskew(sequence)}}]
|
||||
Computes the excess of g compare to c of the sequence, known as the GC
|
||||
skew.
|
||||
|
||||
\[
|
||||
Skew_{GC}=\frac{G-C}{G+C}
|
||||
\]
|
||||
\end{description}
|
||||
|
||||
\hypertarget{accessing-to-the-sequence-annotations}{%
|
||||
\section{Accessing to the sequence
|
||||
@ -1825,6 +1853,12 @@ methods of the \texttt{sequence} object.
|
||||
THe sequence definition : \texttt{Definition()}
|
||||
\end{itemize}
|
||||
|
||||
\begin{Shaded}
|
||||
\begin{Highlighting}[]
|
||||
\NormalTok{sequence}\OperatorTok{.}\NormalTok{Id}\OperatorTok{()}
|
||||
\end{Highlighting}
|
||||
\end{Shaded}
|
||||
|
||||
\hypertarget{metabarcode-design-and-quality-assessment}{%
|
||||
\chapter{Metabarcode design and quality
|
||||
assessment}\label{metabarcode-design-and-quality-assessment}}
|
||||
@ -1851,6 +1885,9 @@ Replace the \texttt{ecoPCR} original \emph{OBITools}
|
||||
\hypertarget{obitag}{%
|
||||
\section{\texorpdfstring{\texttt{obitag}}{obitag}}\label{obitag}}
|
||||
|
||||
\hypertarget{obitagpcr}{%
|
||||
\section{\texorpdfstring{\texttt{obitagpcr}}{obitagpcr}}\label{obitagpcr}}
|
||||
|
||||
\hypertarget{computations-on-sequences}{%
|
||||
\chapter{Computations on sequences}\label{computations-on-sequences}}
|
||||
|
||||
@ -2061,6 +2098,50 @@ Sequences can be selected on several of their caracteristics, their
|
||||
length, their id, their sequence. Options allow for specifying the
|
||||
condition if selection.
|
||||
|
||||
\textbf{Selection based on the sequence}
|
||||
|
||||
Sequence records can be selected according if they match or not with a
|
||||
pattern. The simplest pattern is as short sequence (\emph{e.g}
|
||||
\texttt{AACCTT}). But the usage of regular patterns allows for looking
|
||||
for more complex pattern. As example, \texttt{A{[}TG{]}C+G} matches a
|
||||
\texttt{A}, followed by a \texttt{T} or a \texttt{G}, then one or
|
||||
several \texttt{C} and endly a \texttt{G}.
|
||||
|
||||
\begin{description}
|
||||
\item[\textbf{-\/-sequence}\textbar{}\textbf{-s} \emph{PATTERN}]
|
||||
Regular expression pattern to be tested against the sequence itself. The
|
||||
pattern is case insensitive. A complete description of the regular
|
||||
pattern grammar is available
|
||||
\href{https://yourbasic.org/golang/regexp-cheat-sheet/\#cheat-sheet}{here}.
|
||||
\item[\emph{Examples:}]
|
||||
Selects only the sequence records that contain an \emph{EcoRI}
|
||||
restriction site.
|
||||
\end{description}
|
||||
|
||||
\begin{Shaded}
|
||||
\begin{Highlighting}[]
|
||||
\ExtensionTok{obigrep} \AttributeTok{{-}s} \StringTok{\textquotesingle{}GAATTC\textquotesingle{}}\NormalTok{ seq1.fasta }\OperatorTok{\textgreater{}}\NormalTok{ seq2.fasta}
|
||||
\end{Highlighting}
|
||||
\end{Shaded}
|
||||
|
||||
: Selects only the sequence records that contain a stretch of at least
|
||||
10 \texttt{A}.
|
||||
|
||||
\begin{Shaded}
|
||||
\begin{Highlighting}[]
|
||||
\ExtensionTok{obigrep} \AttributeTok{{-}s} \StringTok{\textquotesingle{}A\{10,\}\textquotesingle{}}\NormalTok{ seq1.fasta }\OperatorTok{\textgreater{}}\NormalTok{ seq2.fasta}
|
||||
\end{Highlighting}
|
||||
\end{Shaded}
|
||||
|
||||
: Selects only the sequence records that do not contain ambiguous
|
||||
nucleotides.
|
||||
|
||||
\begin{Shaded}
|
||||
\begin{Highlighting}[]
|
||||
\ExtensionTok{obigrep} \AttributeTok{{-}s} \StringTok{\textquotesingle{}\^{}[ACGT]+$\textquotesingle{}}\NormalTok{ seq1.fasta }\OperatorTok{\textgreater{}}\NormalTok{ seq2.fasta}
|
||||
\end{Highlighting}
|
||||
\end{Shaded}
|
||||
|
||||
\begin{description}
|
||||
\item[\textbf{-\/-min-count} \textbar{} \textbf{-c} \emph{COUNT}]
|
||||
only sequences reprensenting at least \emph{COUNT} reads will be
|
||||
@ -2072,7 +2153,7 @@ only sequences reprensenting no more than \emph{COUNT} reads will be
|
||||
selected. That option rely on the \texttt{count} attribute. If the
|
||||
\texttt{count} attribute is not defined for a sequence record, it is
|
||||
assumed equal to \(1\).
|
||||
\item[Example]
|
||||
\item[\emph{Examples}]
|
||||
Selecting sequence records representing at least five reads in the
|
||||
dataset.
|
||||
\end{description}
|
||||
@ -2495,25 +2576,18 @@ A function consuming a \texttt{obiiter.IBioSequence} and returning two
|
||||
\chapter{Annexes}\label{annexes}}
|
||||
|
||||
\hypertarget{sequence-attributes}{%
|
||||
\subsection{Sequence attributes}\label{sequence-attributes}}
|
||||
\section{Sequence attributes}\label{sequence-attributes}}
|
||||
|
||||
\hypertarget{reserved-sequence-attributes}{%
|
||||
\subsubsection{Reserved sequence
|
||||
attributes}\label{reserved-sequence-attributes}}
|
||||
\textbf{ali\_dir (\texttt{string})}
|
||||
|
||||
\hypertarget{ali_dir}{%
|
||||
\paragraph{\texorpdfstring{\texttt{ali\_dir}}{ali\_dir}}\label{ali_dir}}
|
||||
|
||||
\hypertarget{type-string}{%
|
||||
\subparagraph{\texorpdfstring{Type :
|
||||
\texttt{string}}{Type : string}}\label{type-string}}
|
||||
|
||||
The attribute can contain 2 string values \texttt{"left"} or
|
||||
\texttt{"right".}
|
||||
|
||||
\hypertarget{set-by-the-obipairing-tool}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
|
||||
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\item
|
||||
The attribute can contain 2 string values \texttt{left} or
|
||||
\texttt{right}.
|
||||
\end{itemize}
|
||||
|
||||
The alignment generated by \emph{obipairing} is a 3'-end gap free
|
||||
algorithm. Two cases can occur when aligning the forward and reverse
|
||||
@ -2524,46 +2598,44 @@ the paired reads overlap by their 5' ends, and the complete barcode is
|
||||
sequenced by both the reads. In that later case, \texttt{ali\_dir} is
|
||||
set to \emph{right}.
|
||||
|
||||
\hypertarget{ali_length}{%
|
||||
\paragraph{\texorpdfstring{\texttt{ali\_length}}{ali\_length}}\label{ali_length}}
|
||||
\textbf{ali\_length (\texttt{int})}
|
||||
|
||||
\hypertarget{set-by-the-obipairing-tool-1}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
|
||||
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-1}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\end{itemize}
|
||||
|
||||
Length of the aligned parts when merging forward and reverse reads
|
||||
|
||||
\hypertarget{count-the-number-of-sequence-occurrences}{%
|
||||
\paragraph{\texorpdfstring{\texttt{count} : the number of sequence
|
||||
occurrences}{count : the number of sequence occurrences}}\label{count-the-number-of-sequence-occurrences}}
|
||||
\textbf{count (\texttt{int})}
|
||||
|
||||
\hypertarget{set-by-the-obiuniq-tool}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obiuniq}
|
||||
tool}{Set by the obiuniq tool}}\label{set-by-the-obiuniq-tool}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obiuniq} tool
|
||||
\item
|
||||
Getter : method \texttt{Count()}
|
||||
\item
|
||||
Setter : method \texttt{SetCount(int)}
|
||||
\end{itemize}
|
||||
|
||||
The \texttt{count} attribute indicates how-many strictly identical
|
||||
sequences have been merged in a single record. It contains an integer
|
||||
value. If it is absent this means that the sequence record represents a
|
||||
single occurrence of the sequence.
|
||||
|
||||
\hypertarget{getter-method-count}{%
|
||||
\subparagraph{\texorpdfstring{Getter : method
|
||||
\texttt{Count()}}{Getter : method Count()}}\label{getter-method-count}}
|
||||
The \texttt{count} attribute indicates how-many strictly identical reads
|
||||
have been merged in a single record. It contains an integer value. If it
|
||||
is absent this means that the sequence record represents a single
|
||||
occurrence of the sequence.
|
||||
|
||||
The \texttt{Count()} method allows to access to the count attribute as
|
||||
an integer value. If the \texttt{count} attribute is not defined for the
|
||||
given sequence, the value \emph{1} is returned
|
||||
|
||||
\hypertarget{merged_}{%
|
||||
\paragraph{\texorpdfstring{\texttt{merged\_*}}{merged\_*}}\label{merged_}}
|
||||
\textbf{merged\_* (\texttt{map{[}string{]}int})}
|
||||
|
||||
\hypertarget{type-mapstringint}{%
|
||||
\subparagraph{\texorpdfstring{Type :
|
||||
\texttt{map{[}string{]}int}}{Type : map{[}string{]}int}}\label{type-mapstringint}}
|
||||
|
||||
\hypertarget{set-by-the-obiuniq-tool-1}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obiuniq}
|
||||
tool}{Set by the obiuniq tool}}\label{set-by-the-obiuniq-tool-1}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obiuniq} tool
|
||||
\end{itemize}
|
||||
|
||||
The \texttt{-m} option of the \emph{obiuniq} tools allows for keeping
|
||||
track of the distribution of the values stored in given attribute of
|
||||
@ -2574,47 +2646,98 @@ the name of the monitored attribute. If \texttt{-m} option is used with
|
||||
the attribute \emph{sample}, then this attribute names
|
||||
\emph{merged\_sample}.
|
||||
|
||||
\hypertarget{mode}{%
|
||||
\paragraph{\texorpdfstring{\texttt{mode}}{mode}}\label{mode}}
|
||||
\textbf{mode (\texttt{string})}
|
||||
|
||||
\hypertarget{set-by-the-obipairing-tool-2}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
|
||||
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-2}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\item
|
||||
The attribute can contain 2 string values \texttt{join} or
|
||||
\texttt{alignment}.
|
||||
\end{itemize}
|
||||
|
||||
\textbf{\texttt{obitag\_ref\_index}}
|
||||
\textbf{obitag\_ref\_index (\texttt{map{[}string{]}string})}
|
||||
|
||||
\hypertarget{set-by-the-obirefidx-tool.}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obirefidx}
|
||||
tool.}{Set by the obirefidx tool.}}\label{set-by-the-obirefidx-tool.}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obirefidx} tool.
|
||||
\end{itemize}
|
||||
|
||||
It resumes to which taxonomic annotation a match to that sequence must
|
||||
lead according to the number of differences existing between the query
|
||||
sequence and the reference sequence having that tag.
|
||||
|
||||
\hypertarget{getter-method-count-1}{%
|
||||
\subparagraph{\texorpdfstring{Getter : method
|
||||
\texttt{Count()}}{Getter : method Count()}}\label{getter-method-count-1}}
|
||||
\begin{Shaded}
|
||||
\begin{Highlighting}[]
|
||||
\FunctionTok{\{}\DataTypeTok{"0"}\FunctionTok{:}\StringTok{"9606@Homo sapiens@species"}\FunctionTok{,}
|
||||
\DataTypeTok{"2"}\FunctionTok{:}\StringTok{"207598@Homininae@subfamily"}\FunctionTok{,}
|
||||
\DataTypeTok{"3"}\FunctionTok{:}\StringTok{"9604@Hominidae@family"}\FunctionTok{,}
|
||||
\DataTypeTok{"8"}\FunctionTok{:}\StringTok{"314295@Hominoidea@superfamily"}\FunctionTok{,}
|
||||
\DataTypeTok{"10"}\FunctionTok{:}\StringTok{"9526@Catarrhini@parvorder"}\FunctionTok{,}
|
||||
\DataTypeTok{"12"}\FunctionTok{:}\StringTok{"1437010@Boreoeutheria@clade"}\FunctionTok{,}
|
||||
\DataTypeTok{"16"}\FunctionTok{:}\StringTok{"9347@Eutheria@clade"}\FunctionTok{,}
|
||||
\DataTypeTok{"17"}\FunctionTok{:}\StringTok{"40674@Mammalia@class"}\FunctionTok{,}
|
||||
\DataTypeTok{"22"}\FunctionTok{:}\StringTok{"117571@Euteleostomi@clade"}\FunctionTok{,}
|
||||
\DataTypeTok{"25"}\FunctionTok{:}\StringTok{"7776@Gnathostomata@clade"}\FunctionTok{,}
|
||||
\DataTypeTok{"29"}\FunctionTok{:}\StringTok{"33213@Bilateria@clade"}\FunctionTok{,}
|
||||
\DataTypeTok{"30"}\FunctionTok{:}\StringTok{"6072@Eumetazoa@clade"}\FunctionTok{\}}
|
||||
\end{Highlighting}
|
||||
\end{Shaded}
|
||||
|
||||
\hypertarget{pairing_mismatches}{%
|
||||
\paragraph{\texorpdfstring{\texttt{pairing\_mismatches}}{pairing\_mismatches}}\label{pairing_mismatches}}
|
||||
\textbf{pairing\_mismatches (\texttt{map{[}string{]}string})}
|
||||
|
||||
\hypertarget{set-by-the-obipairing-tool-3}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
|
||||
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-3}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\end{itemize}
|
||||
|
||||
\hypertarget{score}{%
|
||||
\paragraph{\texorpdfstring{\texttt{score}}{score}}\label{score}}
|
||||
\textbf{seq\_a\_single (\texttt{int})}
|
||||
|
||||
\hypertarget{set-by-the-obipairing-tool-4}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
|
||||
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-4}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\end{itemize}
|
||||
|
||||
\hypertarget{score_norm}{%
|
||||
\paragraph{\texorpdfstring{\texttt{score\_norm}}{score\_norm}}\label{score_norm}}
|
||||
\textbf{seq\_ab\_match (\texttt{int})}
|
||||
|
||||
\hypertarget{set-by-the-obipairing-tool-5}{%
|
||||
\subparagraph{\texorpdfstring{Set by the \emph{obipairing}
|
||||
tool}{Set by the obipairing tool}}\label{set-by-the-obipairing-tool-5}}
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\end{itemize}
|
||||
|
||||
\textbf{seq\_b\_single (\texttt{int})}
|
||||
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\end{itemize}
|
||||
|
||||
\textbf{score (\texttt{int})}
|
||||
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\end{itemize}
|
||||
|
||||
\textbf{score\_norm (\texttt{float})}
|
||||
|
||||
\begin{itemize}
|
||||
\tightlist
|
||||
\item
|
||||
Set by the \emph{obipairing} tool
|
||||
\item
|
||||
The value ranges between 0 and 1.
|
||||
\end{itemize}
|
||||
|
||||
Score of the alignment between forward and reverse reads expressed as a
|
||||
fraction of identity.
|
||||
|
||||
\hypertarget{references}{%
|
||||
\chapter*{References}\label{references}}
|
||||
|
@ -4,3 +4,4 @@
|
||||
|
||||
## `obitag`
|
||||
|
||||
## `obitagpcr`
|
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
Before Width: | Height: | Size: 61 KiB |
@ -17,6 +17,10 @@ Several OBITools (*e.g.* obigrep, obiannotate) allow the user to specify some si
|
||||
the length of a sequences, the number of element in a map like `annotations`, the number
|
||||
of elements in an array. The reurned value is an `int`.
|
||||
|
||||
**`contains(map,key)`**
|
||||
|
||||
: Tests if the `map` contains a value assciated to `key`
|
||||
|
||||
### Cast functions {.unnumbered}
|
||||
|
||||
**`int(x)`**
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 46 KiB |
Binary file not shown.
Before Width: | Height: | Size: 45 KiB |
Binary file not shown.
Binary file not shown.
@ -19,11 +19,11 @@ for f in $(egrep "gb(${DIV})[0-9]+\.seq\.gz" index.html \
|
||||
fi
|
||||
|
||||
while [[ ! -f $f ]] ; do
|
||||
echo downloading
|
||||
wget2 --progress bar -v -o - $URL$f
|
||||
if [[ -f $f ]] ; then
|
||||
gzip -t $f && echo " ok" || rm -f $f
|
||||
fi
|
||||
echo downloading
|
||||
wget2 --progress bar -v -o - $URL$f
|
||||
if [[ -f $f ]] ; then
|
||||
gzip -t $f && echo " ok" || rm -f $f
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
|
BIN
doc/build/_book/OBITools-V4.epub
vendored
BIN
doc/build/_book/OBITools-V4.epub
vendored
Binary file not shown.
BIN
doc/build/_book/OBITools-V4.pdf
vendored
BIN
doc/build/_book/OBITools-V4.pdf
vendored
Binary file not shown.
4
doc/build/_book/comm_annotation.html
vendored
4
doc/build/_book/comm_annotation.html
vendored
@ -217,6 +217,7 @@ ul.task-list li input[type="checkbox"] {
|
||||
<ul>
|
||||
<li><a href="#obiannotate" id="toc-obiannotate" class="nav-link active" data-scroll-target="#obiannotate"><span class="toc-section-number">10.1</span> <code>obiannotate</code></a></li>
|
||||
<li><a href="#obitag" id="toc-obitag" class="nav-link" data-scroll-target="#obitag"><span class="toc-section-number">10.2</span> <code>obitag</code></a></li>
|
||||
<li><a href="#obitagpcr" id="toc-obitagpcr" class="nav-link" data-scroll-target="#obitagpcr"><span class="toc-section-number">10.3</span> <code>obitagpcr</code></a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
@ -245,6 +246,9 @@ ul.task-list li input[type="checkbox"] {
|
||||
</section>
|
||||
<section id="obitag" class="level2" data-number="10.2">
|
||||
<h2 data-number="10.2" class="anchored" data-anchor-id="obitag"><span class="header-section-number">10.2</span> <code>obitag</code></h2>
|
||||
</section>
|
||||
<section id="obitagpcr" class="level2" data-number="10.3">
|
||||
<h2 data-number="10.3" class="anchored" data-anchor-id="obitagpcr"><span class="header-section-number">10.3</span> <code>obitagpcr</code></h2>
|
||||
|
||||
|
||||
</section>
|
||||
|
4
doc/build/_book/expressions.html
vendored
4
doc/build/_book/expressions.html
vendored
@ -329,6 +329,10 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
|
||||
<dd>
|
||||
<p>It is a generic function allowing to retreive the size of a object. It returns the length of a sequences, the number of element in a map like <code>annotations</code>, the number of elements in an array. The reurned value is an <code>int</code>.</p>
|
||||
</dd>
|
||||
<dt><strong><code>contains(map,key)</code></strong></dt>
|
||||
<dd>
|
||||
<p>Tests if the <code>map</code> contains a value assciated to <code>key</code></p>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section id="cast-functions" class="level3 unnumbered">
|
||||
|
21
doc/build/_book/search.json
vendored
21
doc/build/_book/search.json
vendored
@ -137,14 +137,14 @@
|
||||
"href": "expressions.html#function-defined-in-the-language",
|
||||
"title": "7 OBITools expression language",
|
||||
"section": "7.2 Function defined in the language",
|
||||
"text": "7.2 Function defined in the language\n\nInstrospection functions\n\nlen(x)is a generic function allowing to retreive the size of a object. It returns the length of a sequences, the number of element in a map like annotations, the number of elements in an array. The reurned value is an int.\n\n\n\nCast functions\n\nint(x) converts if possible the x value to an integer value. The function returns an int.\nnumeric(x) converts if possible the x value to a float value. The function returns a float.\nbool(x) converts if possible the x value to a boolean value. The function returns a bool.\n\n\n\nString related functions\n\nprintf(format,...) allows to combine several values to build a string. format follows the classical C printf syntax. The function returns a string.\nsubspc(x) substitutes every space in the x string by the underscore (_) character. The function returns a string."
|
||||
"text": "7.2 Function defined in the language\n\nInstrospection functions\n\nlen(x)\n\nIt is a generic function allowing to retreive the size of a object. It returns the length of a sequences, the number of element in a map like annotations, the number of elements in an array. The reurned value is an int.\n\ncontains(map,key)\n\nTests if the map contains a value assciated to key\n\n\n\n\nCast functions\n\nint(x)\n\nConverts if possible the x value to an integer value. The function returns an int.\n\nnumeric(x)\n\nConverts if possible the x value to a float value. The function returns a float.\n\nbool(x)\n\nConverts if possible the x value to a boolean value. The function returns a bool.\n\n\n\n\nString related functions\n\nprintf(format,...)\n\nAllows to combine several values to build a string. format follows the classical C printf syntax. The function returns a string.\n\nsubspc(x)\n\nsubstitutes every space in the x string by the underscore (_) character. The function returns a string.\n\n\n\n\nCondition function\n\nifelse(condition,val1,val2)\n\nThe condition value has to be a bool value. If it is true the function returns val1, otherwise, it is returning val2.\n\n\n\n\n7.2.1 Sequence analysis related function\n\ncomposition(sequence)\n\nThe nucleotide composition of the sequence is returned as as map indexed by a, c, g, or t and each value is the number of occurrences of that nucleotide. A fifth key others accounts for all others symboles.\n\ngcskew(sequence)\n\nComputes the excess of g compare to c of the sequence, known as the GC skew.\n\\[\nSkew_{GC}=\\frac{G-C}{G+C}\n\\]"
|
||||
},
|
||||
{
|
||||
"objectID": "expressions.html#accessing-to-the-sequence-annotations",
|
||||
"href": "expressions.html#accessing-to-the-sequence-annotations",
|
||||
"title": "7 OBITools expression language",
|
||||
"section": "7.3 Accessing to the sequence annotations",
|
||||
"text": "7.3 Accessing to the sequence annotations\nThe annotations variable is a map object containing all the annotations associated to the currently processed sequence. Index of the map are the attribute names. It exists to possibillities to retreive an annotation. It is possible to use the classical [] indexing operator, putting the attribute name quoted by double quotes between them.\nannotations[\"direction\"]\nThe above code retreives the direction annotation. A second notation using the dot (.) is often more convenient.\nannotations.direction\nSpecial attributes of the sequence are accessible only by dedicated methods of the sequence object.\n\nThe sequence identifier : Id()\nTHe sequence definition : Definition()"
|
||||
"text": "7.3 Accessing to the sequence annotations\nThe annotations variable is a map object containing all the annotations associated to the currently processed sequence. Index of the map are the attribute names. It exists to possibillities to retreive an annotation. It is possible to use the classical [] indexing operator, putting the attribute name quoted by double quotes between them.\nannotations[\"direction\"]\nThe above code retreives the direction annotation. A second notation using the dot (.) is often more convenient.\nannotations.direction\nSpecial attributes of the sequence are accessible only by dedicated methods of the sequence object.\n\nThe sequence identifier : Id()\nTHe sequence definition : Definition()\n\nsequence.Id()"
|
||||
},
|
||||
{
|
||||
"objectID": "comm_metabarcode_design.html#obipcr",
|
||||
@ -174,6 +174,13 @@
|
||||
"section": "10.2 obitag",
|
||||
"text": "10.2 obitag"
|
||||
},
|
||||
{
|
||||
"objectID": "comm_annotation.html#obitagpcr",
|
||||
"href": "comm_annotation.html#obitagpcr",
|
||||
"title": "10 Sequence annotations",
|
||||
"section": "10.3 obitagpcr",
|
||||
"text": "10.3 obitagpcr"
|
||||
},
|
||||
{
|
||||
"objectID": "comm_computation.html#obipairing",
|
||||
"href": "comm_computation.html#obipairing",
|
||||
@ -214,7 +221,7 @@
|
||||
"href": "comm_sampling.html#obigrep-filters-sequence-files-according-to-numerous-conditions",
|
||||
"title": "12 Sequence sampling and filtering",
|
||||
"section": "12.1 obigrep – filters sequence files according to numerous conditions",
|
||||
"text": "12.1 obigrep – filters sequence files according to numerous conditions\nThe obigrep command is somewhat analogous to the standard Unix grep command. It selects a subset of sequence records from a sequence file. A sequence record is a complex object consisting of an identifier, a set of attributes (a key, defined by its name, associated with a value), a definition, and the sequence itself. Instead of working text line by text line like the standard Unix tool, obigrep selection is done sequence record by sequence record. A large number of options allow you to refine the selection on any element of the sequence. obigrep allows you to specify multiple conditions simultaneously (which take on the value TRUE or FALSE) and only those sequence records which meet all conditions (all conditions are TRUE) are selected. obigrep is able to work on two paired read files. The selection criteria apply to one or the other of the readings in each pair depending on the mode chosen (--paired-mode option). In all cases the selection is applied in the same way to both files, thus maintaining their consistency.\n\n12.1.1 The options usable with obigrep\n\n12.1.1.1 Selecting sequences based on their caracteristics\nSequences can be selected on several of their caracteristics, their length, their id, their sequence. Options allow for specifying the condition if selection.\n\n--min-count | -c COUNT\n\nonly sequences reprensenting at least COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\n--max-count | -C COUNT\n\nonly sequences reprensenting no more than COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\nExample\n\nSelecting sequence records representing at least five reads in the dataset.\n\n\nobigrep -c 5 data_SPER01.fasta > data_norare_SPER01.fasta"
|
||||
"text": "12.1 obigrep – filters sequence files according to numerous conditions\nThe obigrep command is somewhat analogous to the standard Unix grep command. It selects a subset of sequence records from a sequence file. A sequence record is a complex object consisting of an identifier, a set of attributes (a key, defined by its name, associated with a value), a definition, and the sequence itself. Instead of working text line by text line like the standard Unix tool, obigrep selection is done sequence record by sequence record. A large number of options allow you to refine the selection on any element of the sequence. obigrep allows you to specify multiple conditions simultaneously (which take on the value TRUE or FALSE) and only those sequence records which meet all conditions (all conditions are TRUE) are selected. obigrep is able to work on two paired read files. The selection criteria apply to one or the other of the readings in each pair depending on the mode chosen (--paired-mode option). In all cases the selection is applied in the same way to both files, thus maintaining their consistency.\n\n12.1.1 The options usable with obigrep\n\n12.1.1.1 Selecting sequences based on their caracteristics\nSequences can be selected on several of their caracteristics, their length, their id, their sequence. Options allow for specifying the condition if selection.\nSelection based on the sequence\nSequence records can be selected according if they match or not with a pattern. The simplest pattern is as short sequence (e.g AACCTT). But the usage of regular patterns allows for looking for more complex pattern. As example, A[TG]C+G matches a A, followed by a T or a G, then one or several C and endly a G.\n\n--sequence|-s PATTERN\n\nRegular expression pattern to be tested against the sequence itself. The pattern is case insensitive. A complete description of the regular pattern grammar is available here.\n\nExamples:\n\nSelects only the sequence records that contain an EcoRI restriction site.\n\n\nobigrep -s 'GAATTC' seq1.fasta > seq2.fasta\n: Selects only the sequence records that contain a stretch of at least 10 A.\nobigrep -s 'A{10,}' seq1.fasta > seq2.fasta\n: Selects only the sequence records that do not contain ambiguous nucleotides.\nobigrep -s '^[ACGT]+$' seq1.fasta > seq2.fasta\n\n--min-count | -c COUNT\n\nonly sequences reprensenting at least COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\n--max-count | -C COUNT\n\nonly sequences reprensenting no more than COUNT reads will be selected. That option rely on the count attribute. If the count attribute is not defined for a sequence record, it is assumed equal to \\(1\\).\n\nExamples\n\nSelecting sequence records representing at least five reads in the dataset.\n\n\nobigrep -c 5 data_SPER01.fasta > data_norare_SPER01.fasta"
|
||||
},
|
||||
{
|
||||
"objectID": "comm_utilities.html#obicount",
|
||||
@ -252,11 +259,11 @@
|
||||
"text": "The sequence iterator\nThe pakage obiter provides an iterator mecanism for manipulating sequences. The main class provided by this package is obiiter.IBioSequence. An IBioSequence iterator provides batch of sequences.\n\nBasic usage of a sequence iterator\nMany functions, among them functions reading sequences from a text file, return a IBioSequence iterator. The iterator class provides two main methods:\n\nNext() bool\nGet() obiiter.BioSequenceBatch\n\nThe Next method moves the iterator to the next value, while the Get method returns the currently pointed value. Using them, it is possible to loop over the data as in the following code chunk.\nimport (\n \"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiformats\"\n)\n\nfunc main() {\n mydata := obiformats.ReadFastSeqFromFile(\"myfile.fasta\")\n \n for mydata.Next() {\n data := mydata.Get()\n //\n // Whatever you want to do with the data chunk\n //\n }\n}\nAn obiseq.BioSequenceBatch instance is a set of sequences stored in an obiseq.BioSequenceSlice and a sequence number. The number of sequences in a batch is not defined. A batch can even contain zero sequences, if for example all sequences initially included in the batch have been filtered out at some stage of their processing.\n\n\nThe Pipable functions\nA function consuming a obiiter.IBioSequence and returning a obiiter.IBioSequence is of class obiiter.Pipable.\n\n\nThe Teeable functions\nA function consuming a obiiter.IBioSequence and returning two obiiter.IBioSequence instance is of class obiiter.Teeable."
|
||||
},
|
||||
{
|
||||
"objectID": "annexes.html",
|
||||
"href": "annexes.html",
|
||||
"objectID": "annexes.html#sequence-attributes",
|
||||
"href": "annexes.html#sequence-attributes",
|
||||
"title": "Appendix A — Annexes",
|
||||
"section": "",
|
||||
"text": "A.0.1 Sequence attributes\n\nA.0.1.1 Reserved sequence attributes\n\nA.0.1.1.1 ali_dir\n\nA.0.1.1.1.1 Type : string\nThe attribute can contain 2 string values \"left\" or \"right\".\n\n\nA.0.1.1.1.2 Set by the obipairing tool\nThe alignment generated by obipairing is a 3’-end gap free algorithm. Two cases can occur when aligning the forward and reverse reads. If the barcode is long enough, both the reads overlap only on their 3’ ends. In such case, the alignment direction ali_dir is set to left. If the barcode is shorter than the read length, the paired reads overlap by their 5’ ends, and the complete barcode is sequenced by both the reads. In that later case, ali_dir is set to right.\n\n\n\nA.0.1.1.2 ali_length\n\nA.0.1.1.2.1 Set by the obipairing tool\nLength of the aligned parts when merging forward and reverse reads\n\n\n\nA.0.1.1.3 count : the number of sequence occurrences\n\nA.0.1.1.3.1 Set by the obiuniq tool\nThe count attribute indicates how-many strictly identical sequences have been merged in a single record. It contains an integer value. If it is absent this means that the sequence record represents a single occurrence of the sequence.\n\n\nA.0.1.1.3.2 Getter : method Count()\nThe Count() method allows to access to the count attribute as an integer value. If the count attribute is not defined for the given sequence, the value 1 is returned\n\n\n\nA.0.1.1.4 merged_*\n\nA.0.1.1.4.1 Type : map[string]int\n\n\nA.0.1.1.4.2 Set by the obiuniq tool\nThe -m option of the obiuniq tools allows for keeping track of the distribution of the values stored in given attribute of interest. Often this option is used to summarise distribution of a sequence variant accross samples when obiuniq is run after running obimultiplex. The actual name of the attribute depends on the name of the monitored attribute. If -m option is used with the attribute sample, then this attribute names merged_sample.\n\n\n\nA.0.1.1.5 mode\n\nA.0.1.1.5.1 Set by the obipairing tool\nobitag_ref_index\n\n\nA.0.1.1.5.2 Set by the obirefidx tool.\nIt resumes to which taxonomic annotation a match to that sequence must lead according to the number of differences existing between the query sequence and the reference sequence having that tag.\n\n\nA.0.1.1.5.3 Getter : method Count()\n\n\n\nA.0.1.1.6 pairing_mismatches\n\nA.0.1.1.6.1 Set by the obipairing tool\n\n\n\nA.0.1.1.7 score\n\nA.0.1.1.7.1 Set by the obipairing tool\n\n\n\nA.0.1.1.8 score_norm\n\nA.0.1.1.8.1 Set by the obipairing tool"
|
||||
"section": "A.1 Sequence attributes",
|
||||
"text": "A.1 Sequence attributes\nali_dir (string)\n\nSet by the obipairing tool\nThe attribute can contain 2 string values left or right.\n\nThe alignment generated by obipairing is a 3’-end gap free algorithm. Two cases can occur when aligning the forward and reverse reads. If the barcode is long enough, both the reads overlap only on their 3’ ends. In such case, the alignment direction ali_dir is set to left. If the barcode is shorter than the read length, the paired reads overlap by their 5’ ends, and the complete barcode is sequenced by both the reads. In that later case, ali_dir is set to right.\nali_length (int)\n\nSet by the obipairing tool\n\nLength of the aligned parts when merging forward and reverse reads\ncount (int)\n\nSet by the obiuniq tool\nGetter : method Count()\nSetter : method SetCount(int)\n\nThe count attribute indicates how-many strictly identical reads have been merged in a single record. It contains an integer value. If it is absent this means that the sequence record represents a single occurrence of the sequence.\nThe Count() method allows to access to the count attribute as an integer value. If the count attribute is not defined for the given sequence, the value 1 is returned\nmerged_* (map[string]int)\n\nSet by the obiuniq tool\n\nThe -m option of the obiuniq tools allows for keeping track of the distribution of the values stored in given attribute of interest. Often this option is used to summarise distribution of a sequence variant accross samples when obiuniq is run after running obimultiplex. The actual name of the attribute depends on the name of the monitored attribute. If -m option is used with the attribute sample, then this attribute names merged_sample.\nmode (string)\n\nSet by the obipairing tool\nThe attribute can contain 2 string values join or alignment.\n\nobitag_ref_index (map[string]string)\n\nSet by the obirefidx tool.\n\nIt resumes to which taxonomic annotation a match to that sequence must lead according to the number of differences existing between the query sequence and the reference sequence having that tag.\n {\"0\":\"9606@Homo sapiens@species\",\n \"2\":\"207598@Homininae@subfamily\",\n \"3\":\"9604@Hominidae@family\",\n \"8\":\"314295@Hominoidea@superfamily\",\n \"10\":\"9526@Catarrhini@parvorder\",\n \"12\":\"1437010@Boreoeutheria@clade\",\n \"16\":\"9347@Eutheria@clade\",\n \"17\":\"40674@Mammalia@class\",\n \"22\":\"117571@Euteleostomi@clade\",\n \"25\":\"7776@Gnathostomata@clade\",\n \"29\":\"33213@Bilateria@clade\",\n \"30\":\"6072@Eumetazoa@clade\"}\npairing_mismatches (map[string]string)\n\nSet by the obipairing tool\n\nseq_a_single (int)\n\nSet by the obipairing tool\n\nseq_ab_match (int)\n\nSet by the obipairing tool\n\nseq_b_single (int)\n\nSet by the obipairing tool\n\nscore (int)\n\nSet by the obipairing tool\n\nscore_norm (float)\n\nSet by the obipairing tool\nThe value ranges between 0 and 1.\n\nScore of the alignment between forward and reverse reads expressed as a fraction of identity."
|
||||
},
|
||||
{
|
||||
"objectID": "references.html",
|
||||
|
1704
doc/build/_book/site_libs/bootstrap/bootstrap-icons.css
vendored
Normal file
1704
doc/build/_book/site_libs/bootstrap/bootstrap-icons.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/build/_book/site_libs/bootstrap/bootstrap-icons.woff
vendored
Normal file
BIN
doc/build/_book/site_libs/bootstrap/bootstrap-icons.woff
vendored
Normal file
Binary file not shown.
10
doc/build/_book/site_libs/bootstrap/bootstrap.min.css
vendored
Normal file
10
doc/build/_book/site_libs/bootstrap/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
doc/build/_book/site_libs/bootstrap/bootstrap.min.js
vendored
Normal file
7
doc/build/_book/site_libs/bootstrap/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
9
doc/build/_book/site_libs/quarto-html/anchor.min.js
vendored
Normal file
9
doc/build/_book/site_libs/quarto-html/anchor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
doc/build/_book/site_libs/quarto-html/popper.min.js
vendored
Normal file
6
doc/build/_book/site_libs/quarto-html/popper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
171
doc/build/_book/site_libs/quarto-html/quarto-syntax-highlighting.css
vendored
Normal file
171
doc/build/_book/site_libs/quarto-html/quarto-syntax-highlighting.css
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
/* quarto syntax highlight colors */
|
||||
:root {
|
||||
--quarto-hl-ot-color: #003B4F;
|
||||
--quarto-hl-at-color: #657422;
|
||||
--quarto-hl-ss-color: #20794D;
|
||||
--quarto-hl-an-color: #5E5E5E;
|
||||
--quarto-hl-fu-color: #4758AB;
|
||||
--quarto-hl-st-color: #20794D;
|
||||
--quarto-hl-cf-color: #003B4F;
|
||||
--quarto-hl-op-color: #5E5E5E;
|
||||
--quarto-hl-er-color: #AD0000;
|
||||
--quarto-hl-bn-color: #AD0000;
|
||||
--quarto-hl-al-color: #AD0000;
|
||||
--quarto-hl-va-color: #111111;
|
||||
--quarto-hl-bu-color: inherit;
|
||||
--quarto-hl-ex-color: inherit;
|
||||
--quarto-hl-pp-color: #AD0000;
|
||||
--quarto-hl-in-color: #5E5E5E;
|
||||
--quarto-hl-vs-color: #20794D;
|
||||
--quarto-hl-wa-color: #5E5E5E;
|
||||
--quarto-hl-do-color: #5E5E5E;
|
||||
--quarto-hl-im-color: #00769E;
|
||||
--quarto-hl-ch-color: #20794D;
|
||||
--quarto-hl-dt-color: #AD0000;
|
||||
--quarto-hl-fl-color: #AD0000;
|
||||
--quarto-hl-co-color: #5E5E5E;
|
||||
--quarto-hl-cv-color: #5E5E5E;
|
||||
--quarto-hl-cn-color: #8f5902;
|
||||
--quarto-hl-sc-color: #5E5E5E;
|
||||
--quarto-hl-dv-color: #AD0000;
|
||||
--quarto-hl-kw-color: #003B4F;
|
||||
}
|
||||
|
||||
/* other quarto variables */
|
||||
:root {
|
||||
--quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
pre > code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
div.sourceCode,
|
||||
div.sourceCode pre.sourceCode {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code span.ot {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code span.at {
|
||||
color: #657422;
|
||||
}
|
||||
|
||||
code span.ss {
|
||||
color: #20794D;
|
||||
}
|
||||
|
||||
code span.an {
|
||||
color: #5E5E5E;
|
||||
}
|
||||
|
||||
code span.fu {
|
||||
color: #4758AB;
|
||||
}
|
||||
|
||||
code span.st {
|
||||
color: #20794D;
|
||||
}
|
||||
|
||||
code span.cf {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code span.op {
|
||||
color: #5E5E5E;
|
||||
}
|
||||
|
||||
code span.er {
|
||||
color: #AD0000;
|
||||
}
|
||||
|
||||
code span.bn {
|
||||
color: #AD0000;
|
||||
}
|
||||
|
||||
code span.al {
|
||||
color: #AD0000;
|
||||
}
|
||||
|
||||
code span.va {
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
code span.pp {
|
||||
color: #AD0000;
|
||||
}
|
||||
|
||||
code span.in {
|
||||
color: #5E5E5E;
|
||||
}
|
||||
|
||||
code span.vs {
|
||||
color: #20794D;
|
||||
}
|
||||
|
||||
code span.wa {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code span.do {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code span.im {
|
||||
color: #00769E;
|
||||
}
|
||||
|
||||
code span.ch {
|
||||
color: #20794D;
|
||||
}
|
||||
|
||||
code span.dt {
|
||||
color: #AD0000;
|
||||
}
|
||||
|
||||
code span.fl {
|
||||
color: #AD0000;
|
||||
}
|
||||
|
||||
code span.co {
|
||||
color: #5E5E5E;
|
||||
}
|
||||
|
||||
code span.cv {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code span.cn {
|
||||
color: #8f5902;
|
||||
}
|
||||
|
||||
code span.sc {
|
||||
color: #5E5E5E;
|
||||
}
|
||||
|
||||
code span.dv {
|
||||
color: #AD0000;
|
||||
}
|
||||
|
||||
code span.kw {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
.prevent-inlining {
|
||||
content: "</";
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */
|
770
doc/build/_book/site_libs/quarto-html/quarto.js
vendored
Normal file
770
doc/build/_book/site_libs/quarto-html/quarto.js
vendored
Normal file
@ -0,0 +1,770 @@
|
||||
const sectionChanged = new CustomEvent("quarto-sectionChanged", {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: false,
|
||||
});
|
||||
|
||||
window.document.addEventListener("DOMContentLoaded", function (_event) {
|
||||
const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
|
||||
const sidebarEl = window.document.getElementById("quarto-sidebar");
|
||||
const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
|
||||
const marginSidebarEl = window.document.getElementById(
|
||||
"quarto-margin-sidebar"
|
||||
);
|
||||
// function to determine whether the element has a previous sibling that is active
|
||||
const prevSiblingIsActiveLink = (el) => {
|
||||
const sibling = el.previousElementSibling;
|
||||
if (sibling && sibling.tagName === "A") {
|
||||
return sibling.classList.contains("active");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
|
||||
function fireSlideEnter(e) {
|
||||
const event = window.document.createEvent("Event");
|
||||
event.initEvent("slideenter", true, true);
|
||||
window.document.dispatchEvent(event);
|
||||
}
|
||||
const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
|
||||
tabs.forEach((tab) => {
|
||||
tab.addEventListener("shown.bs.tab", fireSlideEnter);
|
||||
});
|
||||
|
||||
// fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
|
||||
document.addEventListener("tabby", fireSlideEnter, false);
|
||||
|
||||
// Track scrolling and mark TOC links as active
|
||||
// get table of contents and sidebar (bail if we don't have at least one)
|
||||
const tocLinks = tocEl
|
||||
? [...tocEl.querySelectorAll("a[data-scroll-target]")]
|
||||
: [];
|
||||
const makeActive = (link) => tocLinks[link].classList.add("active");
|
||||
const removeActive = (link) => tocLinks[link].classList.remove("active");
|
||||
const removeAllActive = () =>
|
||||
[...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
|
||||
|
||||
// activate the anchor for a section associated with this TOC entry
|
||||
tocLinks.forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
if (link.href.indexOf("#") !== -1) {
|
||||
const anchor = link.href.split("#")[1];
|
||||
const heading = window.document.querySelector(
|
||||
`[data-anchor-id=${anchor}]`
|
||||
);
|
||||
if (heading) {
|
||||
// Add the class
|
||||
heading.classList.add("reveal-anchorjs-link");
|
||||
|
||||
// function to show the anchor
|
||||
const handleMouseout = () => {
|
||||
heading.classList.remove("reveal-anchorjs-link");
|
||||
heading.removeEventListener("mouseout", handleMouseout);
|
||||
};
|
||||
|
||||
// add a function to clear the anchor when the user mouses out of it
|
||||
heading.addEventListener("mouseout", handleMouseout);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const sections = tocLinks.map((link) => {
|
||||
const target = link.getAttribute("data-scroll-target");
|
||||
if (target.startsWith("#")) {
|
||||
return window.document.getElementById(decodeURI(`${target.slice(1)}`));
|
||||
} else {
|
||||
return window.document.querySelector(decodeURI(`${target}`));
|
||||
}
|
||||
});
|
||||
|
||||
const sectionMargin = 200;
|
||||
let currentActive = 0;
|
||||
// track whether we've initialized state the first time
|
||||
let init = false;
|
||||
|
||||
const updateActiveLink = () => {
|
||||
// The index from bottom to top (e.g. reversed list)
|
||||
let sectionIndex = -1;
|
||||
if (
|
||||
window.innerHeight + window.pageYOffset >=
|
||||
window.document.body.offsetHeight
|
||||
) {
|
||||
sectionIndex = 0;
|
||||
} else {
|
||||
sectionIndex = [...sections].reverse().findIndex((section) => {
|
||||
if (section) {
|
||||
return window.pageYOffset >= section.offsetTop - sectionMargin;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (sectionIndex > -1) {
|
||||
const current = sections.length - sectionIndex - 1;
|
||||
if (current !== currentActive) {
|
||||
removeAllActive();
|
||||
currentActive = current;
|
||||
makeActive(current);
|
||||
if (init) {
|
||||
window.dispatchEvent(sectionChanged);
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const inHiddenRegion = (top, bottom, hiddenRegions) => {
|
||||
for (const region of hiddenRegions) {
|
||||
if (top <= region.bottom && bottom >= region.top) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const categorySelector = "header.quarto-title-block .quarto-category";
|
||||
const activateCategories = (href) => {
|
||||
// Find any categories
|
||||
// Surround them with a link pointing back to:
|
||||
// #category=Authoring
|
||||
try {
|
||||
const categoryEls = window.document.querySelectorAll(categorySelector);
|
||||
for (const categoryEl of categoryEls) {
|
||||
const categoryText = categoryEl.textContent;
|
||||
if (categoryText) {
|
||||
const link = `${href}#category=${encodeURIComponent(categoryText)}`;
|
||||
const linkEl = window.document.createElement("a");
|
||||
linkEl.setAttribute("href", link);
|
||||
for (const child of categoryEl.childNodes) {
|
||||
linkEl.append(child);
|
||||
}
|
||||
categoryEl.appendChild(linkEl);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors
|
||||
}
|
||||
};
|
||||
function hasTitleCategories() {
|
||||
return window.document.querySelector(categorySelector) !== null;
|
||||
}
|
||||
|
||||
function offsetRelativeUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
return offset ? offset + url : url;
|
||||
}
|
||||
|
||||
function offsetAbsoluteUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
const baseUrl = new URL(offset, window.location);
|
||||
|
||||
const projRelativeUrl = url.replace(baseUrl, "");
|
||||
if (projRelativeUrl.startsWith("/")) {
|
||||
return projRelativeUrl;
|
||||
} else {
|
||||
return "/" + projRelativeUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// read a meta tag value
|
||||
function getMeta(metaName) {
|
||||
const metas = window.document.getElementsByTagName("meta");
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
if (metas[i].getAttribute("name") === metaName) {
|
||||
return metas[i].getAttribute("content");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
async function findAndActivateCategories() {
|
||||
const currentPagePath = offsetAbsoluteUrl(window.location.href);
|
||||
const response = await fetch(offsetRelativeUrl("listings.json"));
|
||||
if (response.status == 200) {
|
||||
return response.json().then(function (listingPaths) {
|
||||
const listingHrefs = [];
|
||||
for (const listingPath of listingPaths) {
|
||||
const pathWithoutLeadingSlash = listingPath.listing.substring(1);
|
||||
for (const item of listingPath.items) {
|
||||
if (
|
||||
item === currentPagePath ||
|
||||
item === currentPagePath + "index.html"
|
||||
) {
|
||||
// Resolve this path against the offset to be sure
|
||||
// we already are using the correct path to the listing
|
||||
// (this adjusts the listing urls to be rooted against
|
||||
// whatever root the page is actually running against)
|
||||
const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
|
||||
const baseUrl = window.location;
|
||||
const resolvedPath = new URL(relative, baseUrl);
|
||||
listingHrefs.push(resolvedPath.pathname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const nearestListing = findNearestParentListing(
|
||||
offsetAbsoluteUrl(window.location.pathname),
|
||||
listingHrefs
|
||||
);
|
||||
if (nearestListing) {
|
||||
activateCategories(nearestListing);
|
||||
} else {
|
||||
// See if the referrer is a listing page for this item
|
||||
const referredRelativePath = offsetAbsoluteUrl(document.referrer);
|
||||
const referrerListing = listingHrefs.find((listingHref) => {
|
||||
const isListingReferrer =
|
||||
listingHref === referredRelativePath ||
|
||||
listingHref === referredRelativePath + "index.html";
|
||||
return isListingReferrer;
|
||||
});
|
||||
|
||||
if (referrerListing) {
|
||||
// Try to use the referrer if possible
|
||||
activateCategories(referrerListing);
|
||||
} else if (listingHrefs.length > 0) {
|
||||
// Otherwise, just fall back to the first listing
|
||||
activateCategories(listingHrefs[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (hasTitleCategories()) {
|
||||
findAndActivateCategories();
|
||||
}
|
||||
|
||||
const findNearestParentListing = (href, listingHrefs) => {
|
||||
if (!href || !listingHrefs) {
|
||||
return undefined;
|
||||
}
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const relativeParts = href.substring(1).split("/");
|
||||
while (relativeParts.length > 0) {
|
||||
const path = relativeParts.join("/");
|
||||
for (const listingHref of listingHrefs) {
|
||||
if (listingHref.startsWith(path)) {
|
||||
return listingHref;
|
||||
}
|
||||
}
|
||||
relativeParts.pop();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const manageSidebarVisiblity = (el, placeholderDescriptor) => {
|
||||
let isVisible = true;
|
||||
|
||||
return (hiddenRegions) => {
|
||||
if (el === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the last element of the TOC
|
||||
const lastChildEl = el.lastElementChild;
|
||||
|
||||
if (lastChildEl) {
|
||||
// Find the top and bottom o the element that is being managed
|
||||
const elTop = el.offsetTop;
|
||||
const elBottom =
|
||||
elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
|
||||
|
||||
// Converts the sidebar to a menu
|
||||
const convertToMenu = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 0;
|
||||
child.style.overflow = "hidden";
|
||||
}
|
||||
|
||||
const toggleContainer = window.document.createElement("div");
|
||||
toggleContainer.style.width = "100%";
|
||||
toggleContainer.classList.add("zindex-over-content");
|
||||
toggleContainer.classList.add("quarto-sidebar-toggle");
|
||||
toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
|
||||
toggleContainer.id = placeholderDescriptor.id;
|
||||
toggleContainer.style.position = "fixed";
|
||||
|
||||
const toggleIcon = window.document.createElement("i");
|
||||
toggleIcon.classList.add("quarto-sidebar-toggle-icon");
|
||||
toggleIcon.classList.add("bi");
|
||||
toggleIcon.classList.add("bi-caret-down-fill");
|
||||
|
||||
const toggleTitle = window.document.createElement("div");
|
||||
const titleEl = window.document.body.querySelector(
|
||||
placeholderDescriptor.titleSelector
|
||||
);
|
||||
if (titleEl) {
|
||||
toggleTitle.append(titleEl.innerText, toggleIcon);
|
||||
}
|
||||
toggleTitle.classList.add("zindex-over-content");
|
||||
toggleTitle.classList.add("quarto-sidebar-toggle-title");
|
||||
toggleContainer.append(toggleTitle);
|
||||
|
||||
const toggleContents = window.document.createElement("div");
|
||||
toggleContents.classList = el.classList;
|
||||
toggleContents.classList.add("zindex-over-content");
|
||||
toggleContents.classList.add("quarto-sidebar-toggle-contents");
|
||||
for (const child of el.children) {
|
||||
if (child.id === "toc-title") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const clone = child.cloneNode(true);
|
||||
clone.style.opacity = 1;
|
||||
clone.style.display = null;
|
||||
toggleContents.append(clone);
|
||||
}
|
||||
toggleContents.style.height = "0px";
|
||||
toggleContainer.append(toggleContents);
|
||||
el.parentElement.prepend(toggleContainer);
|
||||
|
||||
// Process clicks
|
||||
let tocShowing = false;
|
||||
// Allow the caller to control whether this is dismissed
|
||||
// when it is clicked (e.g. sidebar navigation supports
|
||||
// opening and closing the nav tree, so don't dismiss on click)
|
||||
const clickEl = placeholderDescriptor.dismissOnClick
|
||||
? toggleContainer
|
||||
: toggleTitle;
|
||||
|
||||
const closeToggle = () => {
|
||||
if (tocShowing) {
|
||||
toggleContainer.classList.remove("expanded");
|
||||
toggleContents.style.height = "0px";
|
||||
tocShowing = false;
|
||||
}
|
||||
};
|
||||
|
||||
const positionToggle = () => {
|
||||
// position the element (top left of parent, same width as parent)
|
||||
const elRect = el.getBoundingClientRect();
|
||||
toggleContainer.style.left = `${elRect.left}px`;
|
||||
toggleContainer.style.top = `${elRect.top}px`;
|
||||
toggleContainer.style.width = `${elRect.width}px`;
|
||||
};
|
||||
|
||||
// Get rid of any expanded toggle if the user scrolls
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
closeToggle();
|
||||
}, 50)
|
||||
);
|
||||
|
||||
// Handle positioning of the toggle
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
positionToggle();
|
||||
}, 50)
|
||||
);
|
||||
positionToggle();
|
||||
|
||||
// Process the click
|
||||
clickEl.onclick = () => {
|
||||
if (!tocShowing) {
|
||||
toggleContainer.classList.add("expanded");
|
||||
toggleContents.style.height = null;
|
||||
tocShowing = true;
|
||||
} else {
|
||||
closeToggle();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Converts a sidebar from a menu back to a sidebar
|
||||
const convertToSidebar = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 1;
|
||||
child.style.overflow = null;
|
||||
}
|
||||
|
||||
const placeholderEl = window.document.getElementById(
|
||||
placeholderDescriptor.id
|
||||
);
|
||||
if (placeholderEl) {
|
||||
placeholderEl.remove();
|
||||
}
|
||||
|
||||
el.classList.remove("rollup");
|
||||
};
|
||||
|
||||
if (isReaderMode()) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
} else {
|
||||
if (!isVisible) {
|
||||
// If the element is current not visible reveal if there are
|
||||
// no conflicts with overlay regions
|
||||
if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToSidebar();
|
||||
isVisible = true;
|
||||
}
|
||||
} else {
|
||||
// If the element is visible, hide it if it conflicts with overlay regions
|
||||
// and insert a placeholder toggle (or if we're in reader mode)
|
||||
if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Find any conflicting margin elements and add margins to the
|
||||
// top to prevent overlap
|
||||
const marginChildren = window.document.querySelectorAll(
|
||||
".column-margin.column-container > * "
|
||||
);
|
||||
|
||||
nexttick(() => {
|
||||
let lastBottom = 0;
|
||||
for (const marginChild of marginChildren) {
|
||||
const top = marginChild.getBoundingClientRect().top + window.scrollY;
|
||||
if (top < lastBottom) {
|
||||
const margin = lastBottom - top;
|
||||
marginChild.style.marginTop = `${margin}px`;
|
||||
}
|
||||
const styles = window.getComputedStyle(marginChild);
|
||||
const marginTop = parseFloat(styles["marginTop"]);
|
||||
|
||||
lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
|
||||
}
|
||||
});
|
||||
|
||||
// Manage the visibility of the toc and the sidebar
|
||||
const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
|
||||
id: "quarto-toc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
|
||||
id: "quarto-sidebarnav-toggle",
|
||||
titleSelector: ".title",
|
||||
dismissOnClick: false,
|
||||
});
|
||||
let tocLeftScrollVisibility;
|
||||
if (leftTocEl) {
|
||||
tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
|
||||
id: "quarto-lefttoc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Find the first element that uses formatting in special columns
|
||||
const conflictingEls = window.document.body.querySelectorAll(
|
||||
'[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
|
||||
);
|
||||
|
||||
// Filter all the possibly conflicting elements into ones
|
||||
// the do conflict on the left or ride side
|
||||
const arrConflictingEls = Array.from(conflictingEls);
|
||||
const leftSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return false;
|
||||
}
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("right") &&
|
||||
!className.endsWith("container") &&
|
||||
className !== "column-margin"
|
||||
);
|
||||
});
|
||||
});
|
||||
const rightSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const hasMarginCaption = Array.from(el.classList).find((className) => {
|
||||
return className == "margin-caption";
|
||||
});
|
||||
if (hasMarginCaption) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
!className.endsWith("container") &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("left")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const kOverlapPaddingSize = 10;
|
||||
function toRegions(els) {
|
||||
return els.map((el) => {
|
||||
const top =
|
||||
el.getBoundingClientRect().top +
|
||||
document.documentElement.scrollTop -
|
||||
kOverlapPaddingSize;
|
||||
return {
|
||||
top,
|
||||
bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const hideOverlappedSidebars = () => {
|
||||
marginScrollVisibility(toRegions(rightSideConflictEls));
|
||||
sidebarScrollVisiblity(toRegions(leftSideConflictEls));
|
||||
if (tocLeftScrollVisibility) {
|
||||
tocLeftScrollVisibility(toRegions(leftSideConflictEls));
|
||||
}
|
||||
};
|
||||
|
||||
window.quartoToggleReader = () => {
|
||||
// Applies a slow class (or removes it)
|
||||
// to update the transition speed
|
||||
const slowTransition = (slow) => {
|
||||
const manageTransition = (id, slow) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
if (slow) {
|
||||
el.classList.add("slow");
|
||||
} else {
|
||||
el.classList.remove("slow");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
manageTransition("TOC", slow);
|
||||
manageTransition("quarto-sidebar", slow);
|
||||
};
|
||||
|
||||
const readerMode = !isReaderMode();
|
||||
setReaderModeValue(readerMode);
|
||||
|
||||
// If we're entering reader mode, slow the transition
|
||||
if (readerMode) {
|
||||
slowTransition(readerMode);
|
||||
}
|
||||
highlightReaderToggle(readerMode);
|
||||
hideOverlappedSidebars();
|
||||
|
||||
// If we're exiting reader mode, restore the non-slow transition
|
||||
if (!readerMode) {
|
||||
slowTransition(!readerMode);
|
||||
}
|
||||
};
|
||||
|
||||
const highlightReaderToggle = (readerMode) => {
|
||||
const els = document.querySelectorAll(".quarto-reader-toggle");
|
||||
if (els) {
|
||||
els.forEach((el) => {
|
||||
if (readerMode) {
|
||||
el.classList.add("reader");
|
||||
} else {
|
||||
el.classList.remove("reader");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const setReaderModeValue = (val) => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
window.localStorage.setItem("quarto-reader-mode", val);
|
||||
} else {
|
||||
localReaderMode = val;
|
||||
}
|
||||
};
|
||||
|
||||
const isReaderMode = () => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
return window.localStorage.getItem("quarto-reader-mode") === "true";
|
||||
} else {
|
||||
return localReaderMode;
|
||||
}
|
||||
};
|
||||
let localReaderMode = null;
|
||||
|
||||
// Walk the TOC and collapse/expand nodes
|
||||
// Nodes are expanded if:
|
||||
// - they are top level
|
||||
// - they have children that are 'active' links
|
||||
// - they are directly below an link that is 'active'
|
||||
const walk = (el, depth) => {
|
||||
// Tick depth when we enter a UL
|
||||
if (el.tagName === "UL") {
|
||||
depth = depth + 1;
|
||||
}
|
||||
|
||||
// It this is active link
|
||||
let isActiveNode = false;
|
||||
if (el.tagName === "A" && el.classList.contains("active")) {
|
||||
isActiveNode = true;
|
||||
}
|
||||
|
||||
// See if there is an active child to this element
|
||||
let hasActiveChild = false;
|
||||
for (child of el.children) {
|
||||
hasActiveChild = walk(child, depth) || hasActiveChild;
|
||||
}
|
||||
|
||||
// Process the collapse state if this is an UL
|
||||
if (el.tagName === "UL") {
|
||||
if (depth === 1 || hasActiveChild || prevSiblingIsActiveLink(el)) {
|
||||
el.classList.remove("collapse");
|
||||
} else {
|
||||
el.classList.add("collapse");
|
||||
}
|
||||
|
||||
// untick depth when we leave a UL
|
||||
depth = depth - 1;
|
||||
}
|
||||
return hasActiveChild || isActiveNode;
|
||||
};
|
||||
|
||||
// walk the TOC and expand / collapse any items that should be shown
|
||||
|
||||
if (tocEl) {
|
||||
walk(tocEl, 0);
|
||||
updateActiveLink();
|
||||
}
|
||||
|
||||
// Throttle the scroll event and walk peridiocally
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 5)
|
||||
);
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 10)
|
||||
);
|
||||
hideOverlappedSidebars();
|
||||
highlightReaderToggle(isReaderMode());
|
||||
});
|
||||
|
||||
// grouped tabsets
|
||||
window.addEventListener("pageshow", (_event) => {
|
||||
function getTabSettings() {
|
||||
const data = localStorage.getItem("quarto-persistent-tabsets-data");
|
||||
if (!data) {
|
||||
localStorage.setItem("quarto-persistent-tabsets-data", "{}");
|
||||
return {};
|
||||
}
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
}
|
||||
|
||||
function setTabSettings(data) {
|
||||
localStorage.setItem(
|
||||
"quarto-persistent-tabsets-data",
|
||||
JSON.stringify(data)
|
||||
);
|
||||
}
|
||||
|
||||
function setTabState(groupName, groupValue) {
|
||||
const data = getTabSettings();
|
||||
data[groupName] = groupValue;
|
||||
setTabSettings(data);
|
||||
}
|
||||
|
||||
function toggleTab(tab, active) {
|
||||
const tabPanelId = tab.getAttribute("aria-controls");
|
||||
const tabPanel = document.getElementById(tabPanelId);
|
||||
if (active) {
|
||||
tab.classList.add("active");
|
||||
tabPanel.classList.add("active");
|
||||
} else {
|
||||
tab.classList.remove("active");
|
||||
tabPanel.classList.remove("active");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAll(selectedGroup, selectorsToSync) {
|
||||
for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
|
||||
const active = selectedGroup === thisGroup;
|
||||
for (const tab of tabs) {
|
||||
toggleTab(tab, active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findSelectorsToSyncByLanguage() {
|
||||
const result = {};
|
||||
const tabs = Array.from(
|
||||
document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
|
||||
);
|
||||
for (const item of tabs) {
|
||||
const div = item.parentElement.parentElement.parentElement;
|
||||
const group = div.getAttribute("data-group");
|
||||
if (!result[group]) {
|
||||
result[group] = {};
|
||||
}
|
||||
const selectorsToSync = result[group];
|
||||
const value = item.innerHTML;
|
||||
if (!selectorsToSync[value]) {
|
||||
selectorsToSync[value] = [];
|
||||
}
|
||||
selectorsToSync[value].push(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function setupSelectorSync() {
|
||||
const selectorsToSync = findSelectorsToSyncByLanguage();
|
||||
Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
|
||||
Object.entries(tabSetsByValue).forEach(([value, items]) => {
|
||||
items.forEach((item) => {
|
||||
item.addEventListener("click", (_event) => {
|
||||
setTabState(group, value);
|
||||
toggleAll(value, selectorsToSync[group]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return selectorsToSync;
|
||||
}
|
||||
|
||||
const selectorsToSync = setupSelectorSync();
|
||||
for (const [group, selectedName] of Object.entries(getTabSettings())) {
|
||||
const selectors = selectorsToSync[group];
|
||||
// it's possible that stale state gives us empty selections, so we explicitly check here.
|
||||
if (selectors) {
|
||||
toggleAll(selectedName, selectors);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function throttle(func, wait) {
|
||||
let waiting = false;
|
||||
return function () {
|
||||
if (!waiting) {
|
||||
func.apply(this, arguments);
|
||||
waiting = true;
|
||||
setTimeout(function () {
|
||||
waiting = false;
|
||||
}, wait);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function nexttick(func) {
|
||||
return setTimeout(func, 0);
|
||||
}
|
1
doc/build/_book/site_libs/quarto-html/tippy.css
vendored
Normal file
1
doc/build/_book/site_libs/quarto-html/tippy.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
|
2
doc/build/_book/site_libs/quarto-html/tippy.umd.min.js
vendored
Normal file
2
doc/build/_book/site_libs/quarto-html/tippy.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
doc/build/_book/site_libs/quarto-nav/headroom.min.js
vendored
Normal file
7
doc/build/_book/site_libs/quarto-nav/headroom.min.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it
|
||||
* Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=l<t?"down":"up",a.distance=Math.abs(t-l),a.isOutOfBounds=t<0||o<t+n,a.top=t<=s.offset[a.direction],a.bottom=o<=t+n,a.toleranceExceeded=a.distance>s.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s});
|
221
doc/build/_book/site_libs/quarto-nav/quarto-nav.js
vendored
Normal file
221
doc/build/_book/site_libs/quarto-nav/quarto-nav.js
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
const headroomChanged = new CustomEvent("quarto-hrChanged", {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: false,
|
||||
});
|
||||
|
||||
window.document.addEventListener("DOMContentLoaded", function () {
|
||||
let init = false;
|
||||
|
||||
function throttle(func, wait) {
|
||||
var timeout;
|
||||
return function () {
|
||||
const context = this;
|
||||
const args = arguments;
|
||||
const later = function () {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
func.apply(context, args);
|
||||
};
|
||||
|
||||
if (!timeout) {
|
||||
timeout = setTimeout(later, wait);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function headerOffset() {
|
||||
// Set an offset if there is are fixed top navbar
|
||||
const headerEl = window.document.querySelector("header.fixed-top");
|
||||
if (headerEl) {
|
||||
return headerEl.clientHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function footerOffset() {
|
||||
const footerEl = window.document.querySelector("footer.footer");
|
||||
if (footerEl) {
|
||||
return footerEl.clientHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function updateDocumentOffsetWithoutAnimation() {
|
||||
updateDocumentOffset(false);
|
||||
}
|
||||
|
||||
function updateDocumentOffset(animated) {
|
||||
// set body offset
|
||||
const topOffset = headerOffset();
|
||||
const bodyOffset = topOffset + footerOffset();
|
||||
const bodyEl = window.document.body;
|
||||
bodyEl.setAttribute("data-bs-offset", topOffset);
|
||||
bodyEl.style.paddingTop = topOffset + "px";
|
||||
|
||||
// deal with sidebar offsets
|
||||
const sidebars = window.document.querySelectorAll(
|
||||
".sidebar, .headroom-target"
|
||||
);
|
||||
sidebars.forEach((sidebar) => {
|
||||
if (!animated) {
|
||||
sidebar.classList.add("notransition");
|
||||
// Remove the no transition class after the animation has time to complete
|
||||
setTimeout(function () {
|
||||
sidebar.classList.remove("notransition");
|
||||
}, 201);
|
||||
}
|
||||
|
||||
if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) {
|
||||
sidebar.style.top = "0";
|
||||
sidebar.style.maxHeight = "100vh";
|
||||
} else {
|
||||
sidebar.style.top = topOffset + "px";
|
||||
sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)";
|
||||
}
|
||||
});
|
||||
|
||||
// allow space for footer
|
||||
const mainContainer = window.document.querySelector(".quarto-container");
|
||||
if (mainContainer) {
|
||||
mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)";
|
||||
}
|
||||
|
||||
// link offset
|
||||
let linkStyle = window.document.querySelector("#quarto-target-style");
|
||||
if (!linkStyle) {
|
||||
linkStyle = window.document.createElement("style");
|
||||
window.document.head.appendChild(linkStyle);
|
||||
}
|
||||
while (linkStyle.firstChild) {
|
||||
linkStyle.removeChild(linkStyle.firstChild);
|
||||
}
|
||||
if (topOffset > 0) {
|
||||
linkStyle.appendChild(
|
||||
window.document.createTextNode(`
|
||||
section:target::before {
|
||||
content: "";
|
||||
display: block;
|
||||
height: ${topOffset}px;
|
||||
margin: -${topOffset}px 0 0;
|
||||
}`)
|
||||
);
|
||||
}
|
||||
if (init) {
|
||||
window.dispatchEvent(headroomChanged);
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
// initialize headroom
|
||||
var header = window.document.querySelector("#quarto-header");
|
||||
if (header && window.Headroom) {
|
||||
const headroom = new window.Headroom(header, {
|
||||
tolerance: 5,
|
||||
onPin: function () {
|
||||
const sidebars = window.document.querySelectorAll(
|
||||
".sidebar, .headroom-target"
|
||||
);
|
||||
sidebars.forEach((sidebar) => {
|
||||
sidebar.classList.remove("sidebar-unpinned");
|
||||
});
|
||||
updateDocumentOffset();
|
||||
},
|
||||
onUnpin: function () {
|
||||
const sidebars = window.document.querySelectorAll(
|
||||
".sidebar, .headroom-target"
|
||||
);
|
||||
sidebars.forEach((sidebar) => {
|
||||
sidebar.classList.add("sidebar-unpinned");
|
||||
});
|
||||
updateDocumentOffset();
|
||||
},
|
||||
});
|
||||
headroom.init();
|
||||
|
||||
let frozen = false;
|
||||
window.quartoToggleHeadroom = function () {
|
||||
if (frozen) {
|
||||
headroom.unfreeze();
|
||||
frozen = false;
|
||||
} else {
|
||||
headroom.freeze();
|
||||
frozen = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Observe size changed for the header
|
||||
const headerEl = window.document.querySelector("header.fixed-top");
|
||||
if (headerEl && window.ResizeObserver) {
|
||||
const observer = new window.ResizeObserver(
|
||||
updateDocumentOffsetWithoutAnimation
|
||||
);
|
||||
observer.observe(headerEl, {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
characterData: true,
|
||||
});
|
||||
} else {
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(updateDocumentOffsetWithoutAnimation, 50)
|
||||
);
|
||||
}
|
||||
setTimeout(updateDocumentOffsetWithoutAnimation, 250);
|
||||
|
||||
// fixup index.html links if we aren't on the filesystem
|
||||
if (window.location.protocol !== "file:") {
|
||||
const links = window.document.querySelectorAll("a");
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
links[i].href = links[i].href.replace(/\/index\.html/, "/");
|
||||
}
|
||||
|
||||
// Fixup any sharing links that require urls
|
||||
// Append url to any sharing urls
|
||||
const sharingLinks = window.document.querySelectorAll(
|
||||
"a.sidebar-tools-main-item"
|
||||
);
|
||||
for (let i = 0; i < sharingLinks.length; i++) {
|
||||
const sharingLink = sharingLinks[i];
|
||||
const href = sharingLink.getAttribute("href");
|
||||
if (href) {
|
||||
sharingLink.setAttribute(
|
||||
"href",
|
||||
href.replace("|url|", window.location.href)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll the active navigation item into view, if necessary
|
||||
const navSidebar = window.document.querySelector("nav#quarto-sidebar");
|
||||
if (navSidebar) {
|
||||
// Find the active item
|
||||
const activeItem = navSidebar.querySelector("li.sidebar-item a.active");
|
||||
if (activeItem) {
|
||||
// Wait for the scroll height and height to resolve by observing size changes on the
|
||||
// nav element that is scrollable
|
||||
const resizeObserver = new ResizeObserver((_entries) => {
|
||||
// The bottom of the element
|
||||
const elBottom = activeItem.offsetTop;
|
||||
const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight;
|
||||
|
||||
// The element height and scroll height are the same, then we are still loading
|
||||
if (viewBottom !== navSidebar.scrollHeight) {
|
||||
// Determine if the item isn't visible and scroll to it
|
||||
if (elBottom >= viewBottom) {
|
||||
navSidebar.scrollTop = elBottom;
|
||||
}
|
||||
|
||||
// stop observing now since we've completed the scroll
|
||||
resizeObserver.unobserve(navSidebar);
|
||||
}
|
||||
});
|
||||
resizeObserver.observe(navSidebar);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
3
doc/build/_book/site_libs/quarto-search/autocomplete.umd.js
vendored
Normal file
3
doc/build/_book/site_libs/quarto-search/autocomplete.umd.js
vendored
Normal file
File diff suppressed because one or more lines are too long
9
doc/build/_book/site_libs/quarto-search/fuse.min.js
vendored
Normal file
9
doc/build/_book/site_libs/quarto-search/fuse.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1123
doc/build/_book/site_libs/quarto-search/quarto-search.js
vendored
Normal file
1123
doc/build/_book/site_libs/quarto-search/quarto-search.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user