From adc8aac70e857e33411dcf1d2fdb8913bf35ff3e Mon Sep 17 00:00:00 2001
From: hadjipantelis
Date: Sat, 24 Feb 2018 22:09:07 +0000
Subject: [PATCH] Deleting PDF vignette.
---
vignettes/Sweavel.sty | 82 -----
vignettes/fdapaceVignetteKnitr.Rnw | 294 ----------------
vignettes/framed.sty | 548 -----------------------------
3 files changed, 924 deletions(-)
delete mode 100644 vignettes/Sweavel.sty
delete mode 100644 vignettes/fdapaceVignetteKnitr.Rnw
delete mode 100644 vignettes/framed.sty
diff --git a/vignettes/Sweavel.sty b/vignettes/Sweavel.sty
deleted file mode 100644
index 252b4925..00000000
--- a/vignettes/Sweavel.sty
+++ /dev/null
@@ -1,82 +0,0 @@
-% Originally from Frank Harrell's group at
-% .
-% Some small modifications by Kieran Healy .
-
-
-% Replaces Sweave.sty
-% Uses Listings package to allow for more flexible formatting of R
-% output in Sweave documents (color backgrounds, etc)
-% Usage: \usepackage{Sweavel}
-
-% This version of Sweavel uses color names specified in the
-% option to the latex xcolor package. See xcolor package
-% documentation Section 4.3 "Colors via svgnames option" for names.
-
-% To change size of R code and output, use e.g.: \def\Sweavesize{\normalsize}
-% To change colors of R code, output, and commands, use e.g.:
-% \def\Rcolor{\color{black}}
-% \def\Routcolor{\color{green}}
-% \def\Rcommentcolor{\color{red}}
-% To change background color or R code and/or output, use e.g.:
-% \def\Rbackground{\color{white}}
-% \def\Routbackground{\color{white}}
-% To use rgb specifications use \color[rgb]{ , , }
-% To use gray scale use e.g. \color[gray]{0.5}
-% If you change any of these after the first chunk is produced, the
-% changes will have effect only for the next chunk.
-
-
-
-\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{Sweavel}{} % substitute for Sweave.sty using
- % listings package with relsize
-\RequirePackage{graphicx}
-\RequirePackage[svgnames]{xcolor}
-\RequirePackage{listings,fancyvrb,relsize,ae}
-\RequirePackage[T1]{fontenc}
-\IfFileExists{upquote.sty}{\RequirePackage{upquote}}{}
-
-\providecommand{\Sweavesize}{\smaller}
-
-\providecommand{\Rcolor}{\color{Black}}
-\providecommand{\Routcolor}{\color{NavyBlue}}
-\providecommand{\Rcommentcolor}{\color[rgb]{0.101, 0.043, 0.432}}
-
-\providecommand{\Rbackground}{\color{White}}
-%\providecommand{\Routbackground}{\color[gray]{0.935}}
-\providecommand{\Routbackground}{\color{White}}
-% Can specify \color[gray]{1} for white background or just \color{white}
-
-
-\lstdefinestyle{Rstyle}{fancyvrb=false,escapechar=`,language=R,%
- basicstyle={\Rcolor\Sweavesize\ttfamily},%
- backgroundcolor=\Rbackground,%
- showstringspaces=false,%
- keywordstyle=\Rcolor,%
- commentstyle={\Rcommentcolor\ttfamily\itshape},%
- literate={<-}{{$\leftarrow$}}2{<<-}{{$\twoheadleftarrow$}}2{~}{{$\sim$}}1{<=}{{$\leq$}}2{>=}{{$\geq$}}2{^}{{$^{\scriptstyle\wedge}$}}1,%
- alsoother={$},%
- alsoletter={.<-},%
- otherkeywords={!,!=,~,$,*,\&,\%/\%,\%*\%,\%\%,<-,<<-,/},%
- escapeinside={(*}{*)},
- frame=false,framerule=0.1pt,framesep=1pt,rulecolor=\color{Black},
- numbers=left,numberstyle=\tiny,stepnumber=1,numbersep=7pt,
- keywordstyle={\Rcolor}}
-
-%
-% Other options of interest:
-
-\lstdefinestyle{Routstyle}{fancyvrb=false,literate={~}{{$\sim$}}1{R^2}{{$R^{2}$}}2{^}{{$^{\scriptstyle\wedge}$}}1{R-squared}{{$R^{2}$}}2,%
- basicstyle={\Routcolor\Sweavesize\ttfamily},%
- backgroundcolor=\Routbackground}
-
-\newenvironment{Schunk}{}{}
-\lstnewenvironment{Sinput}{\lstset{style=Rstyle}}{}
-\lstnewenvironment{Scode}{\lstset{style=Rstyle}}{}
-\lstnewenvironment{Soutput}{\lstset{style=Routstyle}}{}
-\lstnewenvironment{Sinputsmall}{%
- \lstset{style=Rstyle,basicstyle={\color{Rcolor}\small}}}{}
-\lstnewenvironment{Sinputsmaller}{%
- \lstset{style=Rstyle,basicstyle={\color{Rcolor}\smaller}}}{}
-
-\endinput
diff --git a/vignettes/fdapaceVignetteKnitr.Rnw b/vignettes/fdapaceVignetteKnitr.Rnw
deleted file mode 100644
index 5cf6a2e1..00000000
--- a/vignettes/fdapaceVignetteKnitr.Rnw
+++ /dev/null
@@ -1,294 +0,0 @@
-\documentclass[11pt,english]{article}
-%\VignetteIndexEntry{fdapaceVignette}
-%\VignetteEngine{knitr::knitr}
-\graphicspath{{figure/}}
-
-\usepackage{palatino,avant,graphicx,color,amsmath,verbatim,url, wrapfig}
-\usepackage{caption,subcaption,morefloats}
-\usepackage{pdflscape}
-\usepackage{amsmath, amssymb} % To use mathematics sybmols
-\usepackage{verbatim} % To use comments
-% \usepackage[makeroom]{cancel} % To cross out an equation
-% \usepackage{tikz}
-% \usetikzlibrary{arrows,matrix,positioning}
-\usepackage{listings} % To use code listings
-
-
-
-
-\usepackage [english]{babel}
-\usepackage{geometry}
-\geometry{
- body={7.13in, 9.75in},
- left=1in,
- right=1in,
- top=1in,
- bottom=1in,
-}
-
-\begin{document}
-% \SweaveOpts{concordance=TRUE}
-
-\title{Functional PCA in R \\ \textit{A software primer using fdapace}}
-\author{Hadjipantelis, Dai, Ji, M\"uller \& Wang - UC Davis, USA}
-\maketitle
-\vspace{-.61cm}
-<>=
-library("knitr")
-opts_chunk$set(warning=FALSE, fig.width=6, fig.height=6, fig.align='center', cache=TRUE, background='white', highlight=FALSE)
-# Set hooks
-render_listings()
-@
-
-\lstset{
-language=R,
-basicstyle=\scriptsize\ttfamily,
-commentstyle=\ttfamily\color{gray},
-numbers=left,
-numberstyle=\ttfamily\color{gray}\footnotesize,
-stepnumber=1,
-numbersep=6pt,
-backgroundcolor=\color{white},
-showspaces=false,
-showstringspaces=false,
-showtabs=false,
-frame=false,
-tabsize=2,
-captionpos=b,
-breaklines=true,
-breakatwhitespace=true,
-escapeinside={},
-keywordstyle={},
-morekeywords={}
-}
-\section{Overview}
-
-
-The basic work-flow behind the PACE approach for sparse \footnote{As a working assumption a dataset is treated as sparse if it has on average less than 20, potentially irregularly sampled, measurements per subject. A user can manually change the automatically determined \texttt{dataType} if that is necessary.} functional data is as follows (see eg. \cite{Yao05, Liu09} for more information):
-\begin{enumerate}
-\item Calculate the smoothed mean $\hat{\mu}$ (using local linear smoothing) aggregating all the available readings together.
-\item Calculate for each curve seperately its own raw covariance and then aggregate all these raw covariances to generate the sample raw covariance.
-\item Use the off-diagonal elements of the sample raw covariance to estimate the smooth covariance.
-\item Perform eigenanalysis on the smoothed covariance to obtain the estimated eigenfunctions $\hat{\phi}$ and eigenvalues $\hat{\lambda}$, then project that smoothed covariance on a positive semi-definite surface \cite{Hall2008}.
-\item Use Conditional Expectation (PACE step) to estimate the corresponding scores $\hat{\xi}$.
-%ie. \newline
-%$\hat{\xi}_{ik} = \hat{E}[\hat{\xi}_{ik}|Y_i] = \hat{\lambda}_k \hat{\phi}_{ik}^T \Sigma_{Y_i}^{-1}(Y_i-\hat{\mu}_i)$.
-\end{enumerate}
-For densely observed functional data simplified procedures are available to obtain the eigencomponents and associated functional principal components scores (see eg. \cite{Castro86} for more information). In particular in this case we:
-\begin{enumerate}
-\item Calculate the cross-sectional mean $\hat{\mu}$.
-\item Calculate the cross-sectional covariance surface (which is guaranteed to be positive semi-definite).
-\item Perform eigenanalysis on the covariance to estimate the eigenfunctions $\hat{\phi}$ and eigenvalues $\hat{\lambda}$.
-\item Use numerical integration to estimate the corresponding scores $\hat{\xi}$.
-% ie. \newline
-% $\hat{\xi}_{ik} = \int_0^T [ y(t) - \hat{\mu}(t)] \phi_i(t) dt$
-\end{enumerate}
-% Which is part of (sparse and then dense) FPCA you believe it is the most computationally intensive?
-In the case of sparse FPCA the most computational intensive part is the smoothing of the sample's raw covariance function. For this, we employ a local weighted bilinear smoother.
-
-A sibling MATLAB package for \texttt{fdapace} can be found in \url{http://www.stat.ucdavis.edu/PACE}.
-\section{FPCA in R using fdapace}
-
-The simplest scenario is that one has two lists \texttt{yList} and \texttt{tList} where \texttt{yList} is a list of vectors, each containing the observed values $Y_{ij}$ for the $i$th subject and \texttt{tList} is a list of vectors containing corresponding time points. In this case one uses:
-
-<>=
-FPCAobj <- FPCA(Ly=yList, Lt=tList)
-@
-The generated \texttt{FPCAobj} will contain all the basic information regarding the desired FPCA.
-
-
-\subsection{Generating a toy dense functional dataset from scratch}
-
-<>=
- library(fdapace)
- #devtools::load_all('.') # So we use the new interfaces
-
- # Set the number of subjects (N) and the
- # number of measurements per subjects (M)
- N <- 200;
- M <- 100;
- set.seed(123)
-
- # Define the continuum
- s <- seq(0,10,length.out = M)
-
- # Define the mean and 2 eigencomponents
- meanFunct <- function(s) s + 10*exp(-(s-5)^2)
- eigFunct1 <- function(s) +cos(2*s*pi/10) / sqrt(5)
- eigFunct2 <- function(s) -sin(2*s*pi/10) / sqrt(5)
-
- # Create FPC scores
- Ksi <- matrix(rnorm(N*2), ncol=2);
- Ksi <- apply(Ksi, 2, scale)
- Ksi <- Ksi %*% diag(c(5,2))
-
- # Create Y_true
- yTrue <- Ksi %*% t(matrix(c(eigFunct1(s),eigFunct2(s)), ncol=2)) + t(matrix(rep(meanFunct(s),N), nrow=M))
-@
-
-\subsection{Running FPCA on a dense dataset }
-\begin{minipage}[l]{0.5\textwidth}
-<>=
- L3 <- MakeFPCAInputs(IDs = rep(1:N, each=M),tVec=rep(s,N), t(yTrue))
- FPCAdense <- FPCA(L3$Ly, L3$Lt)
-
- # Plot the FPCA object
- plot(FPCAdense)
-
- # Find the standard deviation associated with each component
- sqrt(FPCAdense$lambda)
-@
-\end{minipage}
-\begin{minipage}[r]{0.495\textwidth}
- \includegraphics[width=\textwidth]{denseSim-1.pdf}
-\end{minipage}
-
-\subsection{Running FPCA on a sparse and noisy dataset }
-
-\begin{minipage}[l]{0.51\textwidth}
-<>=
- # Create sparse sample
- # Each subject has one to five readings (median: 3)
- set.seed(123)
- ySparse <- Sparsify(yTrue, s, sparsity = c(1:5))
-
- # Give your sample a bit of noise
- ySparse$yNoisy <- lapply(ySparse$Ly, function(x) x + 0.5*rnorm(length(x)))
-
-
- # Do FPCA on this sparse sample
- # Notice that sparse FPCA will smooth the data internally (Yao et al., 2005)
- # Smoothing is the main computational cost behind sparse FPCA
- FPCAsparse <- FPCA(ySparse$yNoisy, ySparse$Lt, list(plot = TRUE))
-
-@
-\end{minipage}
-\begin{minipage}[r]{0.49\textwidth}
- \includegraphics[width=\textwidth]{sparseSim-1.pdf}
-\end{minipage}
-
-\newpage
-\section{Further functionality}
-
-%\begin{itemize}
-
-\texttt{FPCA} calculates the bandwidth utilized by each smoother using generalised cross-validation or $k$-fold cross-validation automatically. Dense data are not smoothed by default. The argument \texttt{methodMuCovEst} can be switched between \texttt{smooth} and \texttt{cross-sectional} if one wants to utilize different estimation techniques when work with dense data.
-%Which was the bandwidth used to calculate the smoothed mean in \texttt{FPCAdense} and in \texttt{FPCAsparse}?
-%Was the bandwidth used for the calculation of $\hat{\mu}$ larger or smaller than the bandwidth used for smoothing the covariance surface? (Check \texttt{...\$bwMu} and \texttt{...\$bwCov} respectively).\newline
-The bandwidth used for estimating the smoothed mean and the smoothed covariance are available under \texttt{...\$bwMu} and \texttt{...\$bwCov} respectively. Users can nevertheless provide their own bandwidth estimates:
-<<>>=
- FPCAsparseMuBW5 <- FPCA(ySparse$yNoisy, ySparse$Lt, optns= list(userBwMu = 5))
-@
-Visualising the fitted trajectories is a good way to see if the new bandwidth made any sense:
-%par(mfrow=c(1,2))
-<>=
-CreatePathPlot( FPCAsparse, subset = 1:3, main = "GCV bandwidth", pch = 16)
-CreatePathPlot( FPCAsparseMuBW5, subset = 1:3, main = "User-defined bandwidth", pch = 16)
-@
-%\includegraphics[width=\textwidth]{DifferentBandwidths}
-\texttt{FPCA} uses a Gaussian kernel when smoothing sparse functional data; other kernel types (eg. Epanechnikov/\texttt{epan}) are also available (see \texttt{?FPCA}). The kernel used for smoothing the mean and covariance surface is the same. It can be found under \texttt{...\$optns\$kernel} of the returned object. For instance, one can switch the default Gaussian kernel (\texttt{gauss}) for a rectangular kernel (\texttt{rect}) as follows:
-
-<<>>=
- FPCAsparseRect <- FPCA(ySparse$yNoisy, ySparse$Lt, optns = list(kernel = 'rect')) # Use rectangular kernel
-@
-
-\texttt{FPCA} returns automatically the smallest number of components required to explain 99.99\% of a sample's variance. Using the function \texttt{selectK} one can determine the number of relevant components according to AIC, BIC or a different Fraction-of-Variance-Explained threshold. For example:
-<>=
-SelectK( FPCAsparse, criterion = 'FVE', FVEthreshold = 0.95) # K = 2
-SelectK( FPCAsparse, criterion = 'AIC') # K = 2
-@
-When working with functional data (usually not very sparse) the estimation of derivatives is often of interest. Using \texttt{fitted.FPCA} one can directly obtain numerical derivatives by defining the appropriate order \texttt{p}; \texttt{fdapace} provides for the first two derivatives (\texttt{p = 1} or \texttt{2}). Because the numerically differentiated data are smoothed the user can define smoothing specific arguments (see \texttt{?fitted.FPCA} for more information); the derivation is done by using the derivative of the linear fit. Similarly using the function \texttt{FPCAder}, one can augment an \texttt{FPCA} object with functional derivatives of a sample's mean function and eigenfunctions.
-
-<<>>=
-fittedCurvesP0 <- fitted(FPCAsparse) # equivalent: fitted(FPCAsparse, derOptns=list(p = 0));
-# Get first order derivatives of fitted curves, smooth using Epanechnikov kernel
-fittedCurcesP1 <- fitted(FPCAsparse, derOptns=list(p = 1, kernelType = 'epan'))
-@
-
-\section{A real-world example}
-
-We use the \texttt{medfly25} dataset that this available with \texttt{fdapace} to showcase \texttt{FPCA} and its related functionality. \texttt{medfly25} is a dataset containing the eggs laid from 789 medflies (Mediterranean fruit flies, Ceratitis capitata) during the first 25 days of their lives. It is a subset of the dataset used by Carey at al. (1998) \cite{Carey98}; only flies having lived at least 25 days are shown. The data are rather noisy, dense and with a characteristic flat start. For that reason in contrast with above we will use a smoothing estimating procedure despite having dense data.
-
-\begin{minipage}[l]{0.5\textwidth}
-<>=
- # load data
- data(medfly25)
-
- # Turn the original data into a list of paired amplitude and timing lists
- Flies <- MakeFPCAInputs(medfly25$ID, medfly25$Days, medfly25$nEggs)
- fpcaObjFlies <- FPCA(Flies$Ly, Flies$Lt, list(plot = TRUE, methodMuCovEst = 'smooth', userBwCov = 2))
-@
-\end{minipage}
-\begin{minipage}[r]{0.495\textwidth}
- \includegraphics[width=\textwidth]{medfly-1.pdf}
-\end{minipage}
-
-Based on the scree-plot we see that the first three components appear to encapsulate most of the relevant variation. The number of eigencomponents to reach a $99.99\%$ FVE is $11$ but just $3$ eigencomponents are enough to reach a $95.0\%$. We can easily inspect the following visually, using the \texttt{CreatePathPlot} command.
- % par(mfrow=c(1,2))
-<>=
- CreatePathPlot(fpcaObjFlies, subset = c(3,5,135), main = 'K = 11', pch = 4); grid()
- CreatePathPlot(fpcaObjFlies, subset = c(3,5,135), K = 3, main = 'K = 3', pch = 4) ; grid()
-@
-
-%\includegraphics[width=0.9\textwidth]{PathFlies}
-
-One can perform outlier detection \cite{Febrero2007} as well as visualize data using a functional box-plot. To achieve these tasks one can use the functions \texttt{CreateOutliersPlot} and \texttt{CreateFuncBoxPlot}. Different ranking methodologies (KDE, bagplot \cite{Rousseeuw1999,Hyndman2010} or point-wise) are available and can potentially identify different aspects of a sample. For example here it is notable that the kernel density estimator \texttt{KDE} variant identifies two main clusters within the main body of sample. By construction the \texttt{bagplot} method would use a single \textit{bag} and this feature would be lost. Both functions return a (temporarily) invisible copy of a list containing the labels associated with each of sample curve. \texttt{CreateOutliersPlot} returns a (temporarily) invisible copy of a list containing the labels associated with each of sample curve.
-% par(mfrow=c(1,2))
-<>=
- CreateOutliersPlot(fpcaObjFlies, optns = list(K = 3, variant = 'KDE'))
- CreateFuncBoxPlot(fpcaObjFlies, xlab = 'Days', ylab = '# of eggs laid', optns = list(K =3, variant='bagplot'))
-@
-
-Functional data lend themselves naturally to questions about their rate of change; their derivatives. As mentioned previously using \texttt{fdapace} one can generate estimates of the sample's derivatives (\texttt{fitted.FPCA}) or the derivatives of the principal modes of variation (\texttt{FPCAder}). In all cases, one defines a \texttt{derOptns} list of options to control the derivation parameters. Getting derivatives is obtained by using a local linear smoother as above.
-
-<>=
- CreatePathPlot(fpcaObjFlies, subset = c(3,5,135), K = 3, main = 'K = 3', showObs = FALSE) ; grid()
- CreatePathPlot(fpcaObjFlies, subset = c(3,5,135), K = 3, main = 'K = 3', showObs = FALSE, derOptns = list(p = 1, bw = 1.01 , kernelType = 'epan') ) ; grid()
-@
-
-We note that if finite support kernel types are used (eg. \texttt{rect} or \texttt{epan}), bandwidths smaller than the distance between two adjacent points over which the data are registered onto will lead to (expected) \texttt{NaN} estimates. In case of dense data, the grid used is (by default) equal to the grid the data were originally registered on; in the case of sparse data, the grid used (by default) spans the range of the sample's supports and uses 51 points. A user can change the number of points using the argument \texttt{nRegGrid}.
-One can investigate the effect a particular kernel type (\texttt{kernelType}) or bandwidth size (\texttt{bw}) has on the generated derivatives by using the function \texttt{CreateBWPlot} and providing a relevant \texttt{derOptns} list. This will generate estimates about the mean function $\mu(t)$ as well as the first two principal modes of variation $\phi_1(t)$ and $\phi_2(t)$ for different multiples of \texttt{bw}.
-
-<>=
-fpcaObjFlies79 <- FPCA(Flies$Ly, Flies$Lt, list(nRegGrid = 79, methodMuCovEst = 'smooth', userBwCov = 2)) # Use 79 equidistant points for the support
-CreateBWPlot(fpcaObjFlies79 , derOptns = list(p = 1, bw = 2.0 , kernelType = 'rect') )
-@
-
-%' \begin{minipage}[l]{0.5\textwidth}
-%' <>=
-%' fpcaObjFlies79 <- FPCA(Flies$Ly, Flies$Lt, list(plot = TRUE, nRegGrid = 79, methodMuCovEst = 'smooth', userBwCov = 2)) # Use 79 equidistant points for the support
-%'
-%' CreateBWPlot(fpcaObjFlies79 , derOptns = list(p = 1, bw = 2.0 , kernelType = 'rect') )
-%' @
-%' \end{minipage}
-%' \begin{minipage}[r]{0.495\textwidth}
-%' \includegraphics[width=\textwidth]{bwPlot-1.pdf}
-%' \end{minipage}
-%' \includegraphics[width=0.9\textwidth]{bwPlot-2.pdf}
-
-
-
-As the \texttt{medfly} sample is dense we can immediately use standard multivaritte clustering functionality to identify potential subgroups within it; the function \texttt{FClust} is the wrapper around the clustering functionality provided by \texttt{fdapace}. By default \texttt{FClust} utilises a Gaussian Mixture Model approach based on the package \texttt{Rmixmod} \cite{Biernacki2006}, as a general rule clustering optimality is based on negative entropy criterion. In the \texttt{medfly} dataset clustering the data allows to immediately recognise a particular subgroup of flies that lay no or very few eggs during the period examined.
-
-% <>=
-% A <- FClust(Flies$Ly, Flies$Lt, optnsFPCA = list(methodMuCovEst = 'smooth', userBwCov = 2, FVEthreshold = 0.90))
-% B <- FClust(Flies$Ly, Flies$Lt, optnsFPCA = list(methodMuCovEst = 'smooth', userBwCov = 2, FVEthreshold = 0.90), k = 2)
-% # A$clusterObj@bestResult@criterionValue is greater than B$clusterObj@bestResult@criterionValue
-% CreatePathPlot( fpcaObjFlies, K=2, showObs=FALSE, lty=1, col= B$cluster, xlab = 'Days', ylab = '# of eggs laid')
-% grid()
-% @
-
-<>=
-A <- FClust(Flies$Ly, Flies$Lt, optnsFPCA = list(methodMuCovEst = 'smooth', userBwCov = 2, FVEthreshold = 0.90), k = 2)
-# The Neg-Entropy Criterion can be found as: A$clusterObj@bestResult@criterionValue
-CreatePathPlot( fpcaObjFlies, K=2, showObs=FALSE, lty=1, col= A$cluster, xlab = 'Days', ylab = '# of eggs laid')
-grid()
-@
-
-
-
-\bibliographystyle{plain}
-\bibliography{roxygen}%
-
-
-\end{document}
diff --git a/vignettes/framed.sty b/vignettes/framed.sty
deleted file mode 100644
index b044e965..00000000
--- a/vignettes/framed.sty
+++ /dev/null
@@ -1,548 +0,0 @@
-% framed.sty v 0.96 2011/10/22
-% Copyright (C) 1992-2011 by Donald Arseneau (asnd@triumf.ca)
-% These macros may be freely transmitted, reproduced, or modified
-% for any purpose provided that this notice is left intact.
-%
-%====================== Begin Instructions =======================
-%
-% framed.sty
-% ~~~~~~~~~~
-% Create framed, shaded, or differently highlighted regions that can
-% break across pages. The environments defined are
-% framed - ordinary frame box (\fbox) with edge at margin
-% oframed - framed with open top/bottom at page breaks
-% shaded - shaded background (\colorbox) bleeding into margin
-% shaded* - shaded background (\colorbox) with edge at margin
-% snugshade - shaded with tight fit around text (esp. in lists)
-% snugshade* - like snugshade with shading edge at margin
-% leftbar - thick vertical line in left margin
-%
-% to be used like
-% \begin{framed}
-% copious text
-% \end{framed}
-%
-% But the more general purpose of this package is to facilitate the
-% definition of new environments that take multi-line material,
-% wrap it with some non-breakable formatting (some kind of box or
-% decoration) and allow page breaks in the material. Such environments
-% are defined to declare (or use) \FrameCommand for applying the boxy
-% decoration, and \MakeFramed{settings} ... \endMakeFramed wrapped
-% around the main text argument (environment body).
-%
-% The "framed" environment uses "\fbox", by default, as its "\FrameCommand"
-% with the additional settings "\fboxrule=\FrameRule" and "\fboxsep=\FrameSep".
-% You can change these lengths (using "\setlength") and you can change
-% the definition of "\FrameCommand" to use much fancier boxes.
-%
-% In fact, the "shaded" environment just redefines \FrameCommand to be
-% "\colorbox{shadecolor}" (and you have to define the color `"shadecolor"':
-% "\definecolor{shadecolor}...").
-%
-% Although the intention is for other packages to define the varieties
-% of decoration, a command "\OpenFbox" is defined for frames with open
-% tops or bottoms, and used for the "oframed" environment. This facility
-% is based on a more complex and capable command "\CustomFBox" which can
-% be used for a wider range of frame styles. One such style of a title-bar
-% frame with continuation marks is provided as an example. It is used by
-% the "titled-frame" environment. To make use of "titled-frame" in your
-% document, or the "\TitleBarFrame" command in your own environment
-% definitions, you must define the colors TFFrameColor (for the frame)
-% and a contrasting TFTitleColor (for the title text).
-%
-% A page break is allowed, and even encouraged, before the framed
-% environment. If you want to attach some text (a box title) to the
-% frame, then the text should be inserted by \FrameCommand so it cannot
-% be separated from the body.
-%
-% The contents of the framed regions are restricted:
-% Floats, footnotes, marginpars and head-line entries will be lost.
-% (Some of these may be handled in a later version.)
-% This package will not work with the page breaking of multicol.sty,
-% or other systems that perform column-balancing.
-%
-% The MakeFramed environment does the work. Its `settings' argument
-% should contain any adjustments to the text width (via a setting of
-% "\hsize"). Here, the parameter "\width" gives the measured extra width
-% added by the frame, so a common setting is "\advance\hsize-\width"
-% which reduces the width of the text just enough that the outer edge
-% of the frame aligns with the margins. The `settings' should also
-% include a `restore' command -- "\@parboxrestore" or "\FrameRestore"
-% or something similar; for instance, the snugshade environment uses
-% settings to eliminate list indents and vertical space, but uses
-% "\hspace" in "\FrameCommand" to reproduce the list margin ouside the
-% shading.
-%
-% There are actually four variants of "\FrameCommand" to allow different
-% formatting for each part of an environment broken over pages. Unbroken
-% text is adorned by "\FrameCommand", whereas split text first uses
-% "\FirstFrameCommand", possibly followed by "\MidFrameCommand", and
-% finishing with "\LastFrameCommand". The default definitions for
-% these three just invokes "\FrameCommand", so that all portions are
-% framed the same way. See the oframe environment for use of distinct
-% First/Mid/Last frames.
-%
-% Expert commands:
-% \MakeFramed, \endMakeFramed: the "MakeFramed" environment
-% \FrameCommand: command to draw the frame around its argument
-% \FirstFrameCommand: the frame for the first part of a split environment
-% \LastFrameCommand: for the last portion
-% \MidFrameCommand: for any intermediate segments
-% \FrameRestore: restore some text settings, but fewer than \@parboxrestore
-% \FrameRule: length register; \fboxrule for default "framed".
-% \FrameSep: length register; \fboxsep for default "framed".
-% \FrameHeightAdjust: macro; height of frame above baseline at top of page
-% \OuterFrameSep: vertical space before and after the framed env. Defaults to "\topsep"
-%
-% This is still a `pre-production' version because I can think of many
-% features/improvements that should be made. Also, a detailed manual needs
-% to be written. Nevertheless, starting with version 0.5 it should be bug-free.
-%
-% ToDo:
-% Test more varieties of list
-% Improve and correct documentation
-% Propagation of \marks
-% Handle footnotes (how??) floats (?) and marginpars.
-% Stretchability modification.
-% Make inner contents height/depth influence placement.
-%======================== End Instructions ========================
-
-\ProvidesPackage{framed}[2011/10/22 v 0.96:
- framed or shaded text with page breaks]
-
-\newenvironment{framed}% using default \FrameCommand
- {\MakeFramed {\advance\hsize-\width \FrameRestore}}%
- {\endMakeFramed}
-
-\newenvironment{shaded}{%
- \def\FrameCommand{\fboxsep=\FrameSep \colorbox{shadecolor}}%
- \MakeFramed {\FrameRestore}}%
- {\endMakeFramed}
-
-\newenvironment{shaded*}{%
- \def\FrameCommand{\fboxsep=\FrameSep \colorbox{shadecolor}}%
- \MakeFramed {\advance\hsize-\width \FrameRestore}}%
- {\endMakeFramed}
-
-\newenvironment{leftbar}{%
- \def\FrameCommand{\vrule width 3pt \hspace{10pt}}%
- \MakeFramed {\advance\hsize-\width \FrameRestore}}%
- {\endMakeFramed}
-
-% snugshde: Shaded environment that
-% -- uses the default \fboxsep instead of \FrameSep
-% -- leaves the text indent unchanged (shading bleeds out)
-% -- eliminates possible internal \topsep glue (\@setminipage)
-% -- shrinks inside the margins for lists
-% An \item label will tend to hang outside the shading, thanks to
-% the small \fboxsep.
-
-\newenvironment{snugshade}{%
- \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep
- \colorbox{shadecolor}{##1}\hskip-\fboxsep
- % There is no \@totalrightmargin, so:
- \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
- \MakeFramed {\advance\hsize-\width
- \@totalleftmargin\z@ \linewidth\hsize
- \@setminipage}%
- }{\par\unskip\@minipagefalse\endMakeFramed}
-
-\newenvironment{snugshade*}{%
- \def\FrameCommand##1{\hskip\@totalleftmargin
- \colorbox{shadecolor}{##1}%
- % There is no \@totalrightmargin, so:
- \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
- \MakeFramed {\advance\hsize-\width
- \@totalleftmargin\z@ \linewidth\hsize
- \advance\labelsep\fboxsep
- \@setminipage}%
- }{\par\unskip\@minipagefalse\endMakeFramed}
-
-\newenvironment{oframed}{% open (top or bottom) framed
- \def\FrameCommand{\OpenFBox\FrameRule\FrameRule}%
- \def\FirstFrameCommand{\OpenFBox\FrameRule\z@}%
- \def\MidFrameCommand{\OpenFBox\z@\z@}%
- \def\LastFrameCommand{\OpenFBox\z@\FrameRule}%
- \MakeFramed {\advance\hsize-\width \FrameRestore}%
- }{\endMakeFramed}
-
-% A simplified entry to \CustomFBox with two customized parameters:
-% the thicknesses of the top and bottom rules. Perhaps we want to
-% use less \fboxsep on the open edges?
-
-\def\OpenFBox#1#2{\fboxsep\FrameSep
- \CustomFBox{}{}{#1}{#2}\FrameRule\FrameRule}
-
-% \CustomFBox is like an amalgamation of \fbox and \@frameb@x,
-% so it can be used by an alternate to \fbox or \fcolorbox, but
-% it has more parameters for various customizations.
-% Parameter #1 is inserted (in vmode) right after the top rule
-% (useful for a title or assignments), and #2 is similar, but
-% inserted right above the bottom rule.
-% The thicknesses of the top, bottom, left, and right rules are
-% given as parameters #3,#4,#5,#6 respectively. They should be
-% \fboxrule or \z@ (or some other thickness).
-% The text argument is #7.
-% An instance of this can be used for the frame of \fcolorbox by
-% locally defining \fbox before \fcolorbox; e.g.,
-% \def\fbox{\CustomFBox{}{}\z@\z@\fboxrule\fboxrule}\fcolorbox
-%
-% Do we need to use different \fboxsep on different sides too?
-%
-\long\def\CustomFBox#1#2#3#4#5#6#7{%
- \leavevmode\begingroup
- \setbox\@tempboxa\hbox{%
- \color@begingroup
- \kern\fboxsep{#7}\kern\fboxsep
- \color@endgroup}%
- \hbox{%
- % Here we calculate and shift for the depth. Done in
- % a group because one of the arguments might be \@tempdima
- % (we could use \dimexpr instead without grouping).
- \begingroup
- \@tempdima#4\relax
- \advance\@tempdima\fboxsep
- \advance\@tempdima\dp\@tempboxa
- \expandafter\endgroup\expandafter
- \lower\the\@tempdima\hbox{%
- \vbox{%
- \hrule\@height#3\relax
- #1%
- \hbox{%
- \vrule\@width#5\relax
- \vbox{%
- \vskip\fboxsep % maybe these should be parameters too
- \copy\@tempboxa
- \vskip\fboxsep}%
- \vrule\@width#6\relax}%
- #2%
- \hrule\@height#4\relax}%
- }%
- }%
- \endgroup
-}
-
-
-% A particular type of titled frame with continuation marks.
-% Parameter #1 is the title, repeated on each page.
-\newenvironment{titled-frame}[1]{%
- \def\FrameCommand{\fboxsep8pt\fboxrule2pt
- \TitleBarFrame{\textbf{#1}}}%
- \def\FirstFrameCommand{\fboxsep8pt\fboxrule2pt
- \TitleBarFrame[$\blacktriangleright$]{\textbf{#1}}}%
- \def\MidFrameCommand{\fboxsep8pt\fboxrule2pt
- \TitleBarFrame[$\blacktriangleright$]{\textbf{#1\ (cont)}}}%
- \def\LastFrameCommand{\fboxsep8pt\fboxrule2pt
- \TitleBarFrame{\textbf{#1\ (cont)}}}%
- \MakeFramed{\advance\hsize-20pt \FrameRestore}}%
-% note: 8 + 2 + 8 + 2 = 20. Don't use \width because the frame title
-% could interfere with the width measurement.
- {\endMakeFramed}
-
-% \TitleBarFrame[marker]{title}{contents}
-% Frame with a label at top, optional continuation marker at bottom right.
-% Frame color is TFFrameColor and title color is a contrasting TFTitleColor;
-% both need to be defined before use. The frame itself use \fboxrule and
-% \fboxsep. If the title is omitted entirely, the title bar is omitted
-% (use a blank space to force a blank title bar).
-%
-\newcommand\TitleBarFrame[3][]{\begingroup
- \ifx\delimiter#1\delimiter
- \let\TF@conlab\@empty
- \else
- \def\TF@conlab{% continuation label
- \nointerlineskip
- \smash{\rlap{\kern\wd\@tempboxa\kern\fboxrule\kern\fboxsep #1}}}%
- \fi
- \let\TF@savecolor\current@color
- \textcolor{TFFrameColor}{%
- \CustomFBox
- {\TF@Title{#2}}{\TF@conlab}%
- \fboxrule\fboxrule\fboxrule\fboxrule
- {\let\current@color\TF@savecolor\set@color #3}%
- }\endgroup
-}
-
-% The title bar for \TitleBarFrame
-\newcommand\TF@Title[1]{%
- \ifx\delimiter#1\delimiter\else
- \kern-0.04pt\relax
- \begingroup
- \setbox\@tempboxa\vbox{%
- \kern0.8ex
- \hbox{\kern\fboxsep\textcolor{TFTitleColor}{#1}\vphantom{Tj)}}%
- \kern0.8ex}%
- \hrule\@height\ht\@tempboxa
- \kern-\ht\@tempboxa
- \box\@tempboxa
- \endgroup
- \nointerlineskip
- \kern-0.04pt\relax
- \fi
-}
-
-\chardef\FrameRestore=\catcode`\| % for debug
-\catcode`\|=\catcode`\% % (debug: insert space after backslash)
-
-\newlength\OuterFrameSep \OuterFrameSep=\maxdimen \relax
-
-\def\MakeFramed#1{\par
- % apply default \OuterFrameSep = \topsep
- \ifdim\OuterFrameSep=\maxdimen \OuterFrameSep\topsep \fi
- % measure added width and height; call result \width and \height
- \fb@sizeofframe\FrameCommand
- \let\width\fb@frw \let\height\fb@frh
- % insert pre-penalties and skips
- \begingroup
- \skip@\lastskip
- \if@nobreak\else
- \penalty9999 % updates \page parameters
- \ifdim\pagefilstretch=\z@ \ifdim\pagefillstretch=\z@
- % not infinitely stretchable, so encourage a page break here
- \edef\@tempa{\the\skip@}%
- \ifx\@tempa\zero@glue \penalty-30
- \else \vskip-\skip@ \penalty-30 \vskip\skip@
- \fi\fi\fi
- \penalty\z@
- % Give a stretchy breakpoint that will always be taken in preference
- % to the \penalty 9999 used to update page parameters. The cube root
- % of 10000/100 indicates a multiplier of 0.21545, but the maximum
- % calculated badness is really 8192, not 10000, so the multiplier
- % is 0.2301.
- \advance\skip@ \z@ plus-.5\baselineskip
- \advance\skip@ \z@ plus-.231\height
- \advance\skip@ \z@ plus-.231\skip@
- \advance\skip@ \z@ plus-.231\OuterFrameSep
- \vskip-\skip@ \penalty 1800 \vskip\skip@
- \fi
- \addvspace{\OuterFrameSep}%
- \endgroup
- % clear out pending page break
- \penalty\@M \vskip 2\baselineskip \vskip\height
- \penalty9999 \vskip -2\baselineskip \vskip-\height
- \penalty9999 % updates \pagetotal
-|\message{After clearout, \pagetotal=\the\pagetotal, \pagegoal=\the\pagegoal. }%
- \fb@adjheight
- \setbox\@tempboxa\vbox\bgroup
- #1% Modifications to \hsize (can use \width and \height)
- \textwidth\hsize \columnwidth\hsize
-}
-
-\def\endMakeFramed{\par
- \kern\z@
- \hrule\@width\hsize\@height\z@ % possibly bad
- \penalty-100 % (\hrule moves depth into height)
- \egroup
-%%% {\showoutput\showbox\@tempboxa}%
- \begingroup
- \fb@put@frame\FrameCommand\FirstFrameCommand
- \endgroup
- \@minipagefalse % In case it was set and not cleared
-}
-
-% \fb@put@frame takes the contents of \@tempboxa and puts all, or a piece,
-% of it on the page with a frame (\FrameCommand, \FirstFrameCommand,
-% \MidFrameCommand, or \LastFrameCommand). It recurses until all of
-% \@tempboxa has been used up. (\@tempboxa must have zero depth.)
-% #1 = attempted framing command, if no split
-% #2 = framing command if split
-% First iteration: Try to fit with \FrameCommand. If it does not fit,
-% split for \FirstFrameCommand.
-% Later iteration: Try to fit with \LastFrameCommand. If it does not
-% fit, split for \MidFrameCommand.
-\def\fb@put@frame#1#2{\relax
- \ifdim\pagegoal=\maxdimen \pagegoal\vsize \fi
-| \message{=============== Entering putframe ====================^^J
-| \pagegoal=\the\pagegoal, \pagetotal=\the\pagetotal. }%
- \ifinner
- \fb@putboxa#1%
- \fb@afterframe
- \else
- \dimen@\pagegoal \advance\dimen@-\pagetotal % natural space left on page
- \ifdim\dimen@<2\baselineskip % Too little room on page
-| \message{Page has only \the\dimen@\space room left; eject. }%
- \eject \fb@adjheight \fb@put@frame#1#2%
- \else % there's appreciable room left on the page
- \fb@sizeofframe#1%
-| \message{\string\pagetotal=\the\pagetotal,
-| \string\pagegoal=\the\pagegoal,
-| \string\pagestretch=\the\pagestretch,
-| \string\pageshrink=\the\pageshrink,
-| \string\fb@frh=\the\fb@frh. \space}
-| \message{^^JBox of size \the\ht\@tempboxa\space}%
- \begingroup % temporarily set \dimen@ to be...
- \advance\dimen@.8\pageshrink % maximum space available on page
- \advance\dimen@-\fb@frh\relax % max space available for frame's contents
-%%% LOOKS SUBTRACTED AND ADDED, SO DOUBLE ACCOUNTING!
- \expandafter\endgroup
- % expand \ifdim, then restore \dimen@ to real room left on page
- \ifdim\dimen@>\ht\@tempboxa % whole box does fit
-| \message{fits in \the\dimen@. }%
- % ToDo: Change this to use vsplit anyway to capture the marks
- % MERGE THIS WITH THE else CLAUSE!!!
- \fb@putboxa#1%
- \fb@afterframe
- \else % box must be split
-| \message{must be split to fit in \the\dimen@. }%
- % update frame measurement to use \FirstFrameCommand or \MidFrameCommand
- \fb@sizeofframe#2%
- \setbox\@tempboxa\vbox{% simulate frame and flexiblity of the page:
- \vskip \fb@frh \@plus\pagestretch \@minus.8\pageshrink
- \kern137sp\kern-137sp\penalty-30
- \unvbox\@tempboxa}%
- \edef\fb@resto@set{\boxmaxdepth\the\boxmaxdepth
- \splittopskip\the\splittopskip}%
- \boxmaxdepth\z@ \splittopskip\z@
-| \message{^^JPadded box of size \the\ht\@tempboxa\space split to \the\dimen@}%
- % Split box here
- \setbox\tw@\vsplit\@tempboxa to\dimen@
-| \toks99\expandafter{\splitfirstmark}%
-| \toks98\expandafter{\splitbotmark}%
-| \message{Marks are: \the\toks99, \the\toks98. }%
- \setbox\tw@\vbox{\unvbox\tw@}% natural-sized
-| \message{Natural height of split box is \the\ht\tw@, leaving
-| \the\ht\@tempboxa\space remainder. }%
- % If the split-to size > (\vsize-\topskip), then set box to full size.
- \begingroup
- \advance\dimen@\topskip
- \expandafter\endgroup
- \ifdim\dimen@>\pagegoal
-| \message{Frame is big -- Use up the full column. }%
- \dimen@ii\pagegoal
- \advance\dimen@ii -\topskip
- \advance\dimen@ii \FrameHeightAdjust\relax
- \else % suspect this is implemented incorrectly:
- % If the split-to size > feasible room_on_page, rebox it smaller.
- \advance\dimen@.8\pageshrink
- \ifdim\ht\tw@>\dimen@
-| \message{Box too tall; rebox it to \the\dimen@. }%
- \dimen@ii\dimen@
- \else % use natural size
- \dimen@ii\ht\tw@
- \fi
- \fi
- % Re-box contents to desired size \dimen@ii
- \advance\dimen@ii -\fb@frh
- \setbox\tw@\vbox to\dimen@ii \bgroup
- % remove simulated frame and page flexibility:
- \vskip -\fb@frh \@plus-\pagestretch \@minus-.8\pageshrink
- \unvbox\tw@ \unpenalty\unpenalty
- \ifdim\lastkern=-137sp % whole box went to next page
-| \message{box split at beginning! }%
- % need work here???
- \egroup \fb@resto@set \eject % (\vskip for frame size was discarded)
- \fb@adjheight
- \fb@put@frame#1#2% INSERTED ???
- \else % Got material split off at the head
- \egroup \fb@resto@set
- \ifvoid\@tempboxa % it all fit after all
-| \message{box split at end! }%
- \setbox\@tempboxa\box\tw@
- \fb@putboxa#1%
- \fb@afterframe
- \else % it really did split
-| \message{box split as expected. Its reboxed height is \the\ht\tw@. }%
- \ifdim\wd\tw@>\z@
- \wd\tw@\wd\@tempboxa
- \centerline{#2{\box\tw@}}% ??? \centerline bad idea
- \else
-| \message{Zero width means likely blank. Don't frame it (guess)}%
- \box\tw@
- \fi
- \hrule \@height\z@ \@width\hsize
- \eject
- \fb@adjheight
- \fb@put@frame\LastFrameCommand\MidFrameCommand
- \fi\fi\fi\fi\fi
-}
-
-\def\fb@putboxa#1{%
- \ifvoid\@tempboxa
- \PackageWarning{framed}{Boxa is void -- discard it. }%
- \else
-| \message{Frame and place boxa. }%
-| %{\showoutput\showbox\@tempboxa}%
- \centerline{#1{\box\@tempboxa}}%
- \fi
-}
-
-\def\fb@afterframe{%
- \nointerlineskip \null %{\showoutput \showlists}
- \penalty-30 \vskip\OuterFrameSep \relax
-}
-
-% measure width and height added by frame (#1 = frame command)
-% call results \fb@frw and \fb@frh
-% todo: a mechanism to handle wide frame titles
-\newdimen\fb@frw
-\newdimen\fb@frh
-\def\fb@sizeofframe#1{\begingroup
- \setbox\z@\vbox{\vskip-5in \hbox{\hskip-5in
- #1{\hbox{\vrule \@height 4.7in \@depth.3in \@width 5in}}}%
- \vskip\z@skip}%
-| \message{Measuring frame addition for \string#1 in \@currenvir\space
-| gives ht \the\ht\z@\space and wd \the\wd\z@. }%
-| %{\showoutput\showbox\z@}%
- \global\fb@frw\wd\z@ \global\fb@frh\ht\z@
- \endgroup
-}
-
-\def\fb@adjheight{%
- \vbox to\FrameHeightAdjust{}% get proper baseline skip from above.
- \penalty\@M \nointerlineskip
- \vskip-\FrameHeightAdjust
- \penalty\@M} % useful for tops of pages
-
-\edef\zero@glue{\the\z@skip}
-
-\catcode`\|=\FrameRestore
-
-% Provide configuration commands:
-\providecommand\FrameCommand{%
- \setlength\fboxrule{\FrameRule}\setlength\fboxsep{\FrameSep}%
- \fbox}
-\@ifundefined{FrameRule}{\newdimen\FrameRule \FrameRule=\fboxrule}{}
-\@ifundefined{FrameSep} {\newdimen\FrameSep \FrameSep =3\fboxsep}{}
-\providecommand\FirstFrameCommand{\FrameCommand}
-\providecommand\MidFrameCommand{\FrameCommand}
-\providecommand\LastFrameCommand{\FrameCommand}
-
-% Height of frame above first baseline when frame starts a page:
-\providecommand\FrameHeightAdjust{6pt}
-
-% \FrameRestore has parts of \@parboxrestore, performing a similar but
-% less complete restoration of the default layout. See how it is used in
-% the "settings" argument of \MakeFrame. Though not a parameter, \hsize
-% should be set to the desired total line width available inside the
-% frame before invoking \FrameRestore.
-\def\FrameRestore{%
- \let\if@nobreak\iffalse
- \let\if@noskipsec\iffalse
- \let\-\@dischyph
- \let\'\@acci\let\`\@accii\let\=\@acciii
- % \message{FrameRestore:
- % \@totalleftmargin=\the \@totalleftmargin,
- % \rightmargin=\the\rightmargin,
- % \@listdepth=\the\@listdepth. }%
- % Test if we are in a list (or list-like paragraph)
- \ifnum \ifdim\@totalleftmargin>\z@ 1\fi
- \ifdim\rightmargin>\z@ 1\fi
- \ifnum\@listdepth>\z@ 1\fi 0>\z@
- % \message{In a list: \linewidth=\the\linewidth, \@totalleftmargin=\the\@totalleftmargin,
- % \parshape=\the\parshape, \columnwidth=\the\columnwidth, \hsize=\the\hsize,
- % \labelwidth=\the\labelwidth. }%
- \@setminipage % snug fit around the item. I would like this to be non-global.
- % Now try to propageate changes of width from \hsize to list parameters.
- % This is deficient, but a more advanced way to indicate modification to text
- % dimensions is not (yet) provided; in particular, no separate left/right
- % adjustment.
- \advance\linewidth-\columnwidth \advance\linewidth\hsize
- \parshape\@ne \@totalleftmargin \linewidth
- \else % Not in list
- \linewidth=\hsize
- %\message{No list, set \string\linewidth=\the\hsize. }%
- \fi
- \sloppy
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%