*! version 7.1.2  26Nov2012
*     add bwidth(vector) to vce(analytic, options)
*! version 7.0.0  28Jul2012
*! Version 6.0.0 includes bandwidth selection by cross validation
*! Version 7.0.0 includes bootstrapped VCE
program define poparms, eclass byable(onecall)
	version 12.1

	if _by() {
		local BY `"by `_byvars'`_byrc0':"'
	}
	if replay() {
		if ("`e(cmd)'"!="poparms") error 301

		Replay `0'
		exit
	}
	/* preserve random number seed					*/
	local seed `c(seed)'
	cap noi `BY' Estimate `0'
	local rc = c(rc)
	set seed `seed'
	exit `rc'
end

program Estimate, eclass
	syntax anything(name=eqlist id="equation list") [if][in],    ///
		[				///
		Quantiles(numlist) 		///
		ipw 				///
 		CVBand				///	UNDOCUMENTED
		vce(string)			///
		trace 				///	UNDOCUMENTED
		pszero(numlist max=1 >0 <1e-3)	///	UNDOCUMENTED
		]

	local ieif = ("`ipw'"=="")

	if "`pszero'" == "" {
		local pszero = 1e-7
	}
// syntax for vce()
// vce({ANalytic|BOOTstrap|none} , [Reps(#) bwscale(#)
// 	DENsities(matname) bwidths(matname))

	local tmp : subinstr local vce "," "," , all count(local ncommas)
	if `ncommas' > 1 {
		di in red `"{cmd:vce(`vce')} invalid"'
		exit 498
	}

	if `ncommas' == 1 {
		local vcep `"`vce' quantiles(`quantiles')"'
	}
	else {
		local vcep `"`vce' , quantiles(`quantiles')"'
	}

	PP_vceparse `vcep'

	local properties `r(properties)'
	local vcetype `r(vcetype)'
	local bwscale `r(bwscale)'
	local reps    `r(reps)'

	if "`r(usdensities)'" != "" {
		tempname usdensities
		matrix `usdensities' = r(densities)
	}

	if "`r(usbwidths)'" != "" {
		tempname usbwidths
		matrix `usbwidths' = r(bwidths)
	}

	/* undocumented options: trace - display intermediate results	*/
	local cmdline `"poparms `:list retokenize 0'"'

	_parse expand eqninfo left : eqlist
	local k_eqs = `eqninfo_n'

	if `k_eqs' != 2 {
		di in red "{p}two equations reqired: " 			 ///
		 "{bf:({it:te_equation})}, the treatment equation, and " ///
		 "{bf:({it:mean_equation})}, the mean equation{p_end}"
		exit 198
	}
	local tmp : subinstr local eqninfo_`i' "," ",",	count(local cms)

	ParseEq3 `eqninfo_1'
	local treatvar `s(depvar)'
	local gpvars `s(indvars)'

	ParseEq3 `eqninfo_2'
	local depvar `s(depvar)'
	local cvars `s(indvars)'

	marksample touse
	markout `touse' `depvar' `gpvars' `treatvar' `cvars'
	qui count if `touse'
	if (!r(N)) error(2000)

	qui cap fvexpand `gpvars' if `touse'
	local gpvars `r(varlist)'

	qui cap fvexpand `cvars' if `touse'
	local cvars `r(varlist)'

					// kq hold number of quantile estimated
					// NOTE:
					//    If quantiles bootstrap is default
					//    only means, analytic method is
					//    default
	if "`quantiles'" != "" {
		numlist "`quantiles'", sort
		local quantiles `r(numlist)'
		local kq : word count `quantiles'

		tempname tau
		matrix `tau' = J(`kq',1,0)
		forvalues i = 1/`kq' {
			local tau`i' : word `i' of `quantiles'
			/* handle quantile(50.5) */
	                local ltau`i' = string(floor(100*`tau`i''),"%2.0f")
			matrix `tau'[`i',1] = `tau`i''
		}

	}
	else {
		local kq = 0
	}


	/* find the maximum treatment level				*/
	set sortseed 12345

					// kt holds number of treatment levels
	tempname levels
	ValidateTreatvar `treatvar', touse(`touse')
	local kt = `r(kt)'
	mat `levels' = r(levels)

	if "`quantiles'" != "" {
		if "`usdensities'" != "" {
			if colsof(`usdensities') != (`kq'*`kt') {
				di in red "{cmd:densities() must specify " ///
					"a row vector with `kq' "	///
					"columns"

				di in red "{p 0 4}The number of columns " ///
					"in the "			///
					"the row vector specified by "	///
					"{cmd:densities()} must be "	///
					"the same as the (number of "	///
					"treatment leves)*(number of "	///
					"quantiles){p_end}"
				exit 498
			}
		}
		if "`usbwidths'" != "" {
			if colsof(`usbwidths') != (`kq'*`kt') {
				di in red "{cmd:bwidths() must specify " ///
					"a row vector with `kq' "	///
					"columns"

				di in red "{p 0 4}The number of columns " ///
					"in the "			///
					"the row vector specified by "	///
					"{cmd:bwidths()} must be "	///
					"the same as the (number of "	///
					"treatment leves)*(number of "	///
					"quantiles){p_end}"
				exit 498
			}
		}
	}

	/* find the number of independent variables			*/
	local k : word count `cvars'

	/* Estimate propensity scores via -mlogit-			*/
	local base = `levels'[1,1]
	qui mlogit `treatvar' `gpvars' if `touse', b(`base')
	if !e(converge) {
		di in red "{p}{bf:mlogit} did not converge{p_end}" ///
		exit 430
	}
	else if c(rc) {
		di in red "{p}{bf:mlogit} failed; estimation " ///
		 "cannot proceed without propensity scores{p_end}"
		exit 498
	}

// e(sample) differs from original touse
// only when some probs are very small and there is no identification
	qui count if `touse'
	local n1 = r(N)

	qui replace `touse' = e(sample)
	qui count if `touse'
	local n = r(N)

	if `n1' != `n' {
		di "{cmd:mlogit} sample differs from original sample"
		di "  Some propensities scores may be too close to zero or one"
		di "  The parameters may not be identified"
	}

					// propensity scores
	forvalues t=1/`kt' {
		tempvar phat`t'
		local phat `phat' `phat`t''
	}
	qui predict double ( `phat' ) if `touse', pr

	foreach v of local phat {
		qui summarize `v'
		local min  = r(min)
		local max  = r(max)
		if `min' < `pszero' | `max'>1-`pszero' {
di in red "Some propensity scores are too close to zero or one"
di in red "The parameters are not identified."
exit 498
		}
	}

// Make weight variables wt*, wtm1*, and treatment indicators ti*
// 	treament indicators are adjusted for touse

	local j = 0
	forvalues t = 1/`kt' {
		tempvar wt`t' wtm1`t' ti`t'
		local s = `levels'[`t',1]
		qui gen double `wt`t'' = 			///
			cond(`treatvar'==`s', 1/`phat`t'', 0) if `touse'
		local wlist `wlist' `wt`t''
		qui gen byte `ti`t'' = (`treatvar'==`s' & `touse')
		local tilist `tilist' `ti`t''

		qui gen double `wtm1`t'' = `wt`t''-1 if `touse'
	}

// make names

	forvalues t=1/`kt' {
		local s    = `levels'[`t',1]
		local names "`names' mean:`s'.`treatvar'"
	}

	forvalues i=1/`kq' {
		forvalues t=1/`kt' {
			local s    = `levels'[`t',1]
			local names "`names' q`ltau`i'':`s'.`treatvar'"

			local dnames "`dnames' q`ltau`i'':`s'.`treatvar'"
		}
	}

	tempname b
	local kpar = `kt'*(1+`kq')
	matrix `b' = J(1,`kpar',0)

// Get point estimates
	if `ieif' {
					// EIF means estimated here
		tempvar  xb_meif eif_tmp
		tempname eif_a eif_c
		forvalues t = 1/`kt' {
			local s = `levels'[`t',1]
			qui regress `depvar' `cvars'  if `ti`t''
			qui capture drop `xb_meif'
			qui predict double `xb_meif'

			qui capture drop `eif_tmp'
			qui generate double `eif_tmp' = 	///
				`wt`t''*`depvar' if `touse'
			qui sum `eif_tmp'   if `touse'
			scalar `eif_a' = r(sum)

			qui replace `eif_tmp' = `wtm1`t''*`xb_meif' if `touse'
			qui sum `eif_tmp'  if `touse'
			scalar `eif_c' = r(sum)

			matrix `b'[1,`t'] = (`eif_a'-`eif_c')/(`n')
		}
					// GET EIF quantile estimates here
		if `kq'>0 {
			mata: _poparms_qEIF2("`depvar'", "`cvars'",	///
				"`touse'", 		///
				"`levels'", "`tilist'", "`wlist'",  	///
				"`tau'", "`b'", "", "`trace'", 		///
				"`dhat'")
		}
	}
	else {
				// This loop puts IPW mean estimates in b
		local j = 0
		forvalues t = 1/`kt' {
			local s = `levels'[`t',1]
			qui regress `depvar' [iw=`wt`t''] if `ti`t''
			matrix `b'[1,`++j'] = _b[_cons]
		}
					// Get IPW quantile estimates
		if `kq'>0 {
			mata: _poparms_qIPW2("`depvar'", "`touse'", 	///
				"`levels'", "`tilist'", "`wlist'", 	///
				"`tau'", "`b'", "", "`trace'")
		}
	}

	if (`ieif') local title2 (efficient influence function)
	else local title2 (inverse probability weighting)

// Now deal with VCE
	if "`vcetype'" == "analytic" {
		tempname V
					// Make Psi_mean variables
		tempvar xbe yam
		qui gen double `yam' = .

		forvalues t=1/`kt' {
			qui replace `yam' = `depvar' - `b'[1, `t']
			qui regress `yam' `cvars' if `ti`t''
			capture drop `xbe'
			qui predict double `xbe' if `touse'

			tempvar psim_`t'
			local psimlist `psimlist' `psim_`t''
			qui gen double `psim_`t'' = `wt`t''*`yam' - 	///
				`wtm1`t''*`xbe'
		}

		if `kq'>0 {
// This section computes psi variables and Gamma matrix when
//	quantiles are estimated

// consolidate psi computations into one loop
			forvalues i=1/`kq' {
				forvalues t=1/`kt' {
					tempvar psiq_`i'_`t'
					qui gen double `psiq_`i'_`t'' = .
					local psilistq `psilistq' `psiq_`i'_`t''
				}
			}

			tempvar ylt xb
			tempname bq
			qui gen double `ylt' = .
			forvalues i = 1/`kq' {
				forvalues t = 1/`kt' {
					local s = `levels'[`t',1]

					local el = (`i'-1)*`kt' + `t'
					local psi_it : word `el' of `psilistq'

					scalar `bq' = `b'[1, `kt' + `el']

					capture drop `xb'
					qui replace `ylt' = 		///
						(`depvar' <= `bq') - `tau`i''
					qui regress `ylt' `cvars' 	///
						if `treatvar'==`s' & `touse'
					qui predict double `xb'
					qui replace `psi_it' = 		///
						`wt`t''*`ylt' -		///
						`xb'*`wtm1`t'' if `touse'
				}
			}

			// Put this mess into a function
			// now adjust for Gamma

			tempname Gamma dhat
			if "`usdensities'" == "" {
				tempvar zb kv tousej tousecv
				tempname bw_cv bw_cv_v bw_pi_v bw_v

				if "`cvband'" != "" {
					matrix `bw_cv_v' = J(1, `kq'*`kt',.)
					matrix colnames `bw_cv_v' = `dnames'
					matrix rownames `bw_cv_v' = "CVbwidths"
				}

				matrix `bw_pi_v' = J(1, `kq'*`kt',.)
				matrix colnames `bw_pi_v' = `dnames'
				matrix rownames `bw_pi_v' = "PIbwidths"

				matrix `bw_v' = J(1, `kq'*`kt',.)
				matrix colnames `bw_v' = `dnames'
				matrix rownames `bw_v' = "Bwidths"

				qui generate double `zb'    = .
				qui generate double `kv'    = .
				qui generate byte `tousej'  = .
				qui generate byte `tousecv' = .
				matrix `dhat' = J(1, `kt' + `kq'*`kt', 1)
				matrix `Gamma' = I(`kt'*(1+`kq'))
				forvalues i = 1/`kq' {
forvalues t = 1/`kt' {
	local pn  = `kt' + (`i'-1)*`kt' + `t'
	local pnb = (`i'-1)*`kt' + `t'
	local qn = `b'[1, `pn']
	local treatval = `levels'[`t',1]

	if "`usbwidths'" == "" {
		qui summarize `depvar' [aw=`wt`t'']	///
			if `treatvar'==`treatval' & `touse' , detail
		local miny = r(min)
		local maxy = r(max)
		local m1   = r(sd)
		local m2   = (r(p75) - r(p25))/1.349
		local m    = min(`m1', `m2')
		local nj   = r(N)
		local bw_pi = 2.3449*`m'/((`nj')^(.2))
		matrix `bw_pi_v'[1,`pnb'] = `bw_pi'
		local bw0 = `bwscale'*`bw_pi'
		if "`cvband'" != "" {
			qui replace `tousej' = 		///
				cond(`treatvar'==`treatval' & `touse' , 1, 0)
			local sL = `qn'-`miny'
			local sH = `maxy' - `qn'
			local cut = min(.5*`s', `sL', `sH')
			qui replace `tousecv' = 	///
			cond((abs(y - `qn') < `cut') & `tousej', 1, 0)
			mata: _poparms_PPSI_BCVGrid("`depvar'", "`wt`t''", ///
				"`tousej'", "`tousecv'", `bw0',	///
				`cut', `qn', 150, "", "", "`bw_cv'")
			local mh = scalar(`bw_cv')
			matrix `bw_cv_v'[1,`pnb'] = scalar(`bw_cv')
			matrix `bw_v'[1,`pnb']    = scalar(`bw_cv')
		}
		else {
			local mh    = `bw0'
			matrix `bw_v'[1,`pnb']    = `mh'
		}
	}
	else {
		local mh                  = `usbwidths'[1,`pnb']
		matrix `bw_v'[1,`pnb']    = `usbwidths'[1,`pnb']
	}

	qui replace `zb' = (((`qn')-`depvar')/`mh')
	qui replace `kv' = cond(abs(`zb')<=1, 	///
		.75*(1-(`zb')^2), 0)
	qui regress `kv' [aw=`wt`t''] 	///
	  if `treatvar'==`treatval' & `touse'
	local fj = _b[_cons] /(`mh')

	matrix `dhat'[1, `pn'] = `fj'
}
				}
			}
			else {
				matrix `dhat' = J(1, `kt' , 1), `usdensities'
			}

			mata: `dhat' = st_matrix("`dhat'")'
			mata: st_matrix("`Gamma'", diag(1:/`dhat'))


			matrix colnames `dhat' = `dnames'
			matrix rownames `dhat' = densities

		}

//  Always compute V
		qui matrix accum `V' = `psimlist' `psilistq', noconstant
		local n_tmp = r(N)
		matrix `V' = (1/`n_tmp')*`V'


		if `kq'>0 {
// Only adjust for Gamma when Quantiles are estimated
			tempname V1
			matrix `V1' = `V'

			matrix colnames `V1' = `names'
			matrix rownames `V1' = `names'

			matrix `V' = `Gamma'*`V'*`Gamma'/`n_tmp'

		}
		else {
			matrix `V' = (1/`n_tmp')*`V'
		}

		matrix colnames `V' = `names'
		matrix rownames `V' = `names'


	}
	else if "`vcetype'" == "bootstrap" {
		tempname B bj V
		local nparms = colsof(`b')
		mata: `B' = J(`reps', `nparms', .)
		local sr = 0
		forvalues s=1/`reps' {
			preserve
			qui keep if `touse'
			qui bsample
			capture poparms (`treatvar' `gpvars') 	///
				(`depvar'   `cvars'),		///
				quantiles(`quantiles')		///
				vce(none)
			local rc = _rc
			restore
			if `rc' {
di in red "Bad bootstrap sample: cannot compute poparms estimates"
			}
			else {
				// increment sr but post in s
				//    missing value structure identifies
				//    bad samples
				local ++sr
				mata: `B'[`s',.] = st_matrix("e(b)")
			}
		}
		mata: st_matrix("`V'", quadvariance(`B'))

		local bsreps = `sr'

		matrix colnames `V' = `names'
		matrix rownames `V' = `names'
	}
	else {			// vcetype must be none
	}


	matrix colnames `b' = `names'

	ereturn post `b' `V', obs(`n') esample(`touse') 	///
		properties(`properties')

	ereturn local k = `k'
	ereturn local quantiles `quantiles'
	ereturn local marginsok default
	ereturn local depvar `depvar'
	ereturn local vcetype `vcetype'

	if "`vcetype'" == "analytic" & `kq'>0 {

		matrix `dhat' = `dhat'[1, `kt'+1 ...]
		ereturn matrix densities = `dhat'

		capture mata: mata drop `dhat'

		// bandwidth only
		if "`usdensities'" == "" {
			if "`bwidths'" == "" {
				ereturn scalar bwscale = `bwscale'
				ereturn matrix bw_pi     = `bw_pi_v'

				if "`cvband'" != "" {
					ereturn matrix bw_cv     = `bw_cv_v'
				}
				ereturn matrix bw        = `bw_v'
			}
			else {
				ereturn matrix bw        = `bw_v'
			}
		}
		ereturn matrix V1        = `V1'
	}

	if "`vcetype'" == "bootstrap" {
		capture mata: mata drop `B'
		ereturn scalar reps   = `reps'
		ereturn scalar bsreps = `bsreps'
	}

	ereturn matrix levels    = `levels'

	ereturn local predict  "poparms_p"
	ereturn local title2 `title2'
	ereturn local title Treatment Mean and Quantiles Estimation
	ereturn local cmdline `cmdline'
	ereturn local cmd poparms

	Replay, `diopts'
end

program Replay
	syntax, [ * ]

	_get_diopts diopts rest, `options'

	if "`rest'" != "" {
		if `:word count `rest'' > 1 {
			di in red "{p}options {bf:`rest'} are not " ///
			 "allowed{p_end}"
		}
		else  di in red "{p}option {bf:`rest'} is not allowed{p_end}"

		exit 198
	}
	if (e(df_m)==0) _coef_table_header, nomodeltest
	else _coef_table_header

	_coef_table, `diopts'
	if "`e(vcetype)'"=="bootstrap" & e(reps)!=e(bsreps) {
		local bsreps = e(bsreps)
		local reps   = e(reps)
		di "Only `bsreps' of the requested `reps' bootstrap " 	///
			"repetitions could be performed"
	}
end

program ParseEq3, sclass
	cap syntax varlist(numeric fv)

	local rc = c(rc)
	if `rc' {
		di in red "invalid equation; "
		cap noi syntax varlist(numeric fv)
		exit `rc'
	}

	gettoken depvar varlist : varlist
	_fv_check_depvar `depvar'

	sreturn local depvar `depvar'
	sreturn local indvars `varlist'
end


program ValidateTreatvar, rclass
	syntax varname(numeric), [ touse(varname numeric) ]

	preserve
	/*  check that the treatment variable is categorical		*/
	tempvar check del
	qui gen int `check' = round(`varlist') if `touse'
	cap assert `check' == `varlist' if `touse'
	if c(rc) {
		di in red "{it:treatvar}, {bf:`varlist'}, must be categorical"
		exit 459
	}
	qui count if `touse'
	local n = r(N)

	sort `check'
	local max = `varlist'[`n']
	local min = `varlist'[1]

	qui gen int `del' = (`check'[_n]-`check'[_n-1]>0) if _n>1 & `touse'
	qui replace `del' = 1 in 1
	qui count if `del' & `touse'
	local kt = r(N)
	if `kt' > 30 {
		di in red "{p}there are `kt' unique values in " ///
		 "{it:treatvar} {bf:`varlist'}; the maximum is 30{p_end}"
		exit 459
	}
	if `kt' < 2 {
		di in red "{p}at least two treatment groups are required{p_end}"
		exit 459
	}
	tempname levels
	mat `levels' = J(`kt',1,.)
	gsort - `del' + `check'

	forvalues i=1/`kt' {
		mat `levels'[`i',1] = `check'[`i']
	}
	return local max = `max'		// not used
	return local kt = `kt'
	return mat levels = `levels'
end

program define PP_vceparse, rclass
	syntax [anything(name=vcetype)] 	///
		[, 				///
		Reps(string) 			///
		BWScale(string) 		///
		CVBand 				///
		Quantiles(numlist)		///
		DENSities(string)		///
		bwidths(string)			///
		]

	if "`vcetype'" == "" {
		if "`quantiles'" != "" {
			local vcetype "bootstrap"
			local properties "b V"
		}
		else {
			local vcetype "analytic"
			local properties "b V"
		}
	}
	else {
		PP_getvcetype , `vcetype'
		if "`vcetype'" == "none" {
			local properties "b"
		}

		local vcetype `r(vcetype)'
	}

	if `"`reps'"' != "" {
		if "`vcetype'" != "bootstrap" {
			di in red "{cmd:reps()} cannot be specified "   ///
				"with vcetype `vcetype'"
			exit 498
		}

		capture confirm integer number `reps'
		if _rc {
			di in red "{cmd:reps() must specify an integer number"
			exit 498
		}

		if `reps' <50 {
			di in red "{cmd:reps() must specify an integer " ///
				"number at least as large as 50"
			exit 498
		}
	}
	else {
		local reps 2000
	}

	if "`vcetype'" == "analytic" {
		if "`bwscale'" != "" & "`bwidths'" != "" {
			di in red "{cmd:bwscale()} and "	///
				"{cmd:bwidths()} cannot both be specified"
			exit 498
		}

		if "`bwidths'" != "" & "`cvband'" != "" {
			di in red  "{cmd:bwidths()} and "	///
				"{cmd:cvband} cannot both be specified"
			exit 498
		}

		if "`bwidths'" != "" & "`densities'" != "" {
			di in red "{cmd:bwidths()} and "	///
				"{cmd:densities()} cannot both be specified"
			exit 498
		}

		if "`bwscale'" != "" & "`cvband'" != "" {
			di in red "{cmd:bwscale()} and "	///
				"{cmd:cvband} cannot both be specified"
			exit 498
		}

		if "`bwscale'" != "" & "`densities'" != "" {
			di in red "{cmd:bwscale()} and "	///
				"{cmd:densities()} cannot both be specified"
			exit 498
		}

		if "`cvband'" != "" & "`densities'" != "" {
			di in red "{cmd:cvband} and "	///
				"{cmd:densities()} cannot both be specified"
			exit 498
		}

		if `"`bwscale'"' != "" {
			capture confirm number `bwscale'
			if _rc {
				di in red "{cmd:bwscale() must specify a number"
				exit 498
			}

			if `bwscale' < .1 | `bwscale' > 10 {
				di in red "{cmd:bwscale()} must "	///
					"specify a number between .5 and 2"
				exit 498
			}

			if `bwscale' != 1 & "`cvband'" != "" {
				di in red "{cmd:bwscale()} and "	///
					"{cmd:cvband} cannot both be specified"
				exit 498
			}
		}
		else {
			local bwscale 1
		}

		if `"`densities'"' != "" {
			capture confirm matrix `densities'
			if _rc {
				di in red "{cmd:densities() must "	///
					"specify a matrix"
				exit 498
			}

		}

		if `"`bwidths'"' != "" {
			capture confirm matrix `bwidths'
			if _rc {
				di in red "{cmd:bwidths() must "	///
					"specify a matrix"
				exit 498
			}

		}
	}
	else {
		if `"`bwscale'"' != "" {
			di in red "{cmd:bwscale()} cannot be specified " ///
				"when vcetype is {cmd:`vcetype'}"
			exit 498
		}

		if `"`cvband'"' != "" {
			di in red "{cmd:cvband} cannot be specified "	///
				"when vcetype is {cmd:`vcetype'}"
			exit 498
		}

		if `"`densities'"' != "" {
			di in red "{cmd:densities()} cannot be "		///
				"specified when vcetype is {cmd:`vcetype'}"
			exit 498
		}

	}

	return local properties `properties'
	return local bwscale `bwscale'
	return local vcetype `vcetype'
	return local reps `reps'
	if "`densities'" != "" {
		return local usdensities usdensities
		return matrix densities = `densities' , copy
	}

	if "`bwidths'" != "" {
		return local usbwidths usbwidths
		return matrix bwidths = `bwidths' , copy
	}

end

program define PP_getvcetype, rclass
	syntax , [ ANalytic BOOTstrap NONE *]

	if "`options'" != "" {
		di in red `"`options' invalid vcetype"'
		exit 498
	}

	local w : word count `analytic' `bootstrap' `none'
	if `w' > 1 {
		di in red "vcetype invalid"
		di in red "Only one of `analytic' `bootstrap' `none' "	///
			"can be specified"
	}

	return local vcetype "`analytic'`bootstrap'`none'"
end