diff --git a/config/default.toml b/config/default.toml index f96d1a7d..5f8778a3 100644 --- a/config/default.toml +++ b/config/default.toml @@ -1,3 +1,3 @@ [app] name = "PageTop Essence" -language = "es-ES" +description = "A modern Content Management System for sharing the world." diff --git a/src/base/component/block.rs b/src/base/component/block.rs new file mode 100644 index 00000000..03e67e01 --- /dev/null +++ b/src/base/component/block.rs @@ -0,0 +1,105 @@ +use crate::prelude::*; + +pub struct Block { + renderable: fn() -> bool, + weight : i8, + id : Option, + title : String, + markup : Vec, + template : String, +} + +impl PageComponent for Block { + + fn prepare() -> Self { + Block { + renderable: always, + weight : 0, + id : None, + title : "".to_string(), + markup : Vec::new(), + template : "default".to_string(), + } + } + + fn is_renderable(&self) -> bool { + (self.renderable)() + } + + fn weight(&self) -> i8 { + self.weight + } + + fn default_render(&self, assets: &mut PageAssets) -> Markup { + let id = assets.required_id(self.name(), self.id()); + html! { + div id=(id) class="block" { + @if !self.title.is_empty() { + h2 class="block-title" { (self.title) } + } + div class="block-body" { + @for markup in self.markup.iter() { + (*markup) + } + } + } + } + } +} + +impl Block { + + pub fn markup(markup: Markup) -> Self { + Block::prepare().add_markup(markup) + } + + // Block BUILDER. + + pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self { + self.renderable = renderable; + self + } + + pub fn with_weight(mut self, weight: i8) -> Self { + self.weight = weight; + self + } + + pub fn with_id(mut self, id: &str) -> Self { + self.id = util::valid_id(id); + self + } + + pub fn with_title(mut self, title: &str) -> Self { + self.title = title.to_string(); + self + } + + pub fn add_markup(mut self, markup: Markup) -> Self { + self.markup.push(markup); + self + } + + pub fn using_template(mut self, template: &str) -> Self { + self.template = template.to_string(); + self + } + + // Block GETTERS. + + pub fn id(&self) -> &str { + util::assigned_value(&self.id) + } + + pub fn title(&self) -> &str { + self.title.as_str() + } + + pub fn template(&self) -> &str { + self.template.as_str() + } +} + +fn always() -> bool { + true +} diff --git a/src/base/component/container.rs b/src/base/component/container.rs index d4315ddc..61c08336 100644 --- a/src/base/component/container.rs +++ b/src/base/component/container.rs @@ -5,7 +5,7 @@ enum ContainerType { Column, Row, Wrapper } pub struct Container { renderable: fn() -> bool, weight : i8, - id : String, + id : Option, container : ContainerType, components: PageContainer, template : String, @@ -17,7 +17,7 @@ impl PageComponent for Container { Container { renderable: always, weight : 0, - id : "".to_string(), + id : None, container : ContainerType::Wrapper, components: PageContainer::new(), template : "default".to_string(), @@ -39,7 +39,7 @@ impl PageComponent for Container { ContainerType::Column => "col", }; html! { - div class=(classes) { + div id=[&self.id] class=(classes) { (self.components.render(assets)) } } @@ -73,7 +73,7 @@ impl Container { } pub fn with_id(mut self, id: &str) -> Self { - self.id = id.to_string(); + self.id = util::valid_id(id); self } @@ -87,10 +87,10 @@ impl Container { self } - // Grid GETTERS. + // Container GETTERS. pub fn id(&self) -> &str { - self.id.as_str() + util::assigned_value(&self.id) } pub fn template(&self) -> &str { diff --git a/src/base/component/form/button.rs b/src/base/component/form/button.rs index 440ccf93..c95eb3ec 100644 --- a/src/base/component/form/button.rs +++ b/src/base/component/form/button.rs @@ -23,7 +23,7 @@ impl PageComponent for Button { name : None, value : None, autofocus : None, - disabled : None, + disabled : None, template : "default".to_string(), } } @@ -96,20 +96,12 @@ impl Button { } pub fn with_name(mut self, name: &str) -> Self { - self.name = if name.is_empty() { - None - } else { - Some(name.replace(" ", "_")) - }; + self.name = util::valid_id(name); self } pub fn with_value(mut self, value: &str) -> Self { - self.value = if value.is_empty() { - None - } else { - Some(value.to_string()) - }; + self.value = util::optional_value(value); self } @@ -137,17 +129,11 @@ impl Button { // Button GETTERS. pub fn name(&self) -> &str { - match &self.name { - Some(name) => name.as_str(), - _ => "" - } + util::assigned_value(&self.name) } pub fn value(&self) -> &str { - match &self.value { - Some(value) => value.as_str(), - _ => "" - } + util::assigned_value(&self.value) } pub fn has_autofocus(&self) -> bool { diff --git a/src/base/component/form/date.rs b/src/base/component/form/date.rs index e1e33be0..b2839e8e 100644 --- a/src/base/component/form/date.rs +++ b/src/base/component/form/date.rs @@ -107,20 +107,12 @@ impl Date { } pub fn with_name(mut self, name: &str) -> Self { - self.name = if name.is_empty() { - None - } else { - Some(name.replace(" ", "_")) - }; + self.name = util::valid_id(name); self } pub fn with_value(mut self, value: &str) -> Self { - self.value = if value.is_empty() { - None - } else { - Some(value.to_string()) - }; + self.value = util::optional_value(value); self } @@ -130,11 +122,7 @@ impl Date { } pub fn with_placeholder(mut self, placeholder: &str) -> Self { - self.placeholder = if placeholder.is_empty() { - None - } else { - Some(placeholder.to_string()) - }; + self.placeholder = util::optional_value(placeholder); self } @@ -191,17 +179,11 @@ impl Date { // Date GETTERS. pub fn name(&self) -> &str { - match &self.name { - Some(name) => name.as_str(), - _ => "" - } + util::assigned_value(&self.name) } pub fn value(&self) -> &str { - match &self.value { - Some(value) => value.as_str(), - _ => "" - } + util::assigned_value(&self.value) } pub fn label(&self) -> &str { @@ -209,10 +191,7 @@ impl Date { } pub fn placeholder(&self) -> &str { - match &self.placeholder { - Some(placeholder) => placeholder.as_str(), - _ => "" - } + util::assigned_value(&self.placeholder) } pub fn has_autofocus(&self) -> bool { diff --git a/src/base/component/form/form.rs b/src/base/component/form/form.rs index 519587e0..6f73469d 100644 --- a/src/base/component/form/form.rs +++ b/src/base/component/form/form.rs @@ -71,20 +71,12 @@ impl Form { } pub fn with_id(mut self, id: &str) -> Self { - self.id = if id.is_empty() { - None - } else { - Some(id.replace(" ", "_")) - }; + self.id = util::valid_id(id); self } pub fn with_action(mut self, action: &str) -> Self { - self.action = if action.is_empty() { - None - } else { - Some(action.to_string()) - }; + self.action = util::optional_value(action); self } @@ -94,11 +86,7 @@ impl Form { } pub fn with_charset(mut self, charset: &str) -> Self { - self.charset = if charset.is_empty() { - None - } else { - Some(charset.to_string()) - }; + self.charset = util::optional_value(charset); self } @@ -115,17 +103,11 @@ impl Form { // Form GETTERS. pub fn id(&self) -> &str { - match &self.id { - Some(id) => id.as_str(), - _ => "" - } + util::assigned_value(&self.id) } pub fn action(&self) -> &str { - match &self.action { - Some(action) => action.as_str(), - _ => "" - } + util::assigned_value(&self.action) } pub fn method(&self) -> &str { @@ -136,10 +118,7 @@ impl Form { } pub fn charset(&self) -> &str { - match &self.charset { - Some(charset) => charset.as_str(), - _ => "" - } + util::assigned_value(&self.charset) } pub fn template(&self) -> &str { diff --git a/src/base/component/form/hidden.rs b/src/base/component/form/hidden.rs index a95cfc77..57b4b34f 100644 --- a/src/base/component/form/hidden.rs +++ b/src/base/component/form/hidden.rs @@ -1,29 +1,21 @@ use crate::prelude::*; pub struct Hidden { - renderable : fn() -> bool, - weight : i8, - name : Option, - value : Option, - template : String, + weight : i8, + name : Option, + value : Option, } impl PageComponent for Hidden { fn prepare() -> Self { Hidden { - renderable : always, - weight : 0, - name : None, - value : None, - template : "default".to_string(), + weight : 0, + name : None, + value : None, } } - fn is_renderable(&self) -> bool { - (self.renderable)() - } - fn weight(&self) -> i8 { self.weight } @@ -51,60 +43,28 @@ impl Hidden { // Hidden BUILDER. - pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self { - self.renderable = renderable; - self - } - pub fn with_weight(mut self, weight: i8) -> Self { self.weight = weight; self } pub fn with_name(mut self, name: &str) -> Self { - self.name = if name.is_empty() { - None - } else { - Some(name.replace(" ", "_")) - }; + self.name = util::valid_id(name); self } pub fn with_value(mut self, value: &str) -> Self { - self.value = if value.is_empty() { - None - } else { - Some(value.to_string()) - }; - self - } - - pub fn using_template(mut self, template: &str) -> Self { - self.template = template.to_string(); + self.value = util::optional_value(value); self } // Hidden GETTERS. pub fn name(&self) -> &str { - match &self.name { - Some(name) => name.as_str(), - _ => "" - } + util::assigned_value(&self.name) } pub fn value(&self) -> &str { - match &self.value { - Some(value) => value.as_str(), - _ => "" - } - } - - pub fn template(&self) -> &str { - self.template.as_str() + util::assigned_value(&self.value) } } - -fn always() -> bool { - true -} diff --git a/src/base/component/form/input.rs b/src/base/component/form/input.rs index d4ec8930..82c0bda3 100644 --- a/src/base/component/form/input.rs +++ b/src/base/component/form/input.rs @@ -162,20 +162,12 @@ impl Input { } pub fn with_name(mut self, name: &str) -> Self { - self.name = if name.is_empty() { - None - } else { - Some(name.replace(" ", "_")) - }; + self.name = util::valid_id(name); self } pub fn with_value(mut self, value: &str) -> Self { - self.value = if value.is_empty() { - None - } else { - Some(value.to_string()) - }; + self.value = util::optional_value(value); self } @@ -200,11 +192,7 @@ impl Input { } pub fn with_placeholder(mut self, placeholder: &str) -> Self { - self.placeholder = if placeholder.is_empty() { - None - } else { - Some(placeholder.to_string()) - }; + self.placeholder = util::optional_value(placeholder); self } @@ -261,17 +249,11 @@ impl Input { // Input GETTERS. pub fn name(&self) -> &str { - match &self.name { - Some(name) => name.as_str(), - _ => "" - } + util::assigned_value(&self.name) } pub fn value(&self) -> &str { - match &self.value { - Some(value) => value.as_str(), - _ => "" - } + util::assigned_value(&self.value) } pub fn label(&self) -> &str { @@ -291,10 +273,7 @@ impl Input { } pub fn placeholder(&self) -> &str { - match &self.placeholder { - Some(placeholder) => placeholder.as_str(), - _ => "" - } + util::assigned_value(&self.placeholder) } pub fn has_autofocus(&self) -> bool { diff --git a/src/base/component/menu.rs b/src/base/component/menu.rs new file mode 100644 index 00000000..34be6e33 --- /dev/null +++ b/src/base/component/menu.rs @@ -0,0 +1,252 @@ +use crate::prelude::*; + +enum MenuItemType { + Label(String), + Link(String, String), + LinkBlank(String, String), + Markup(Markup), + Separator, + Submenu(String, Menu), +} + +// ----------------------------------------------------------------------------- +// MenuItem. +// ----------------------------------------------------------------------------- + +pub struct MenuItem { + renderable: fn() -> bool, + weight : i8, + item_type : Option, +} + +impl PageComponent for MenuItem { + + fn prepare() -> Self { + MenuItem { + renderable: always, + weight : 0, + item_type : None, + } + } + + fn is_renderable(&self) -> bool { + (self.renderable)() + } + + fn weight(&self) -> i8 { + self.weight + } + + fn default_render(&self, assets: &mut PageAssets) -> Markup { + match &self.item_type { + Some(MenuItemType::Label(label)) => html! { + li class="label" { a href="#" { (label) } } + }, + Some(MenuItemType::Link(label, path)) => html! { + li class="link" { a href=(path) { (label) } } + }, + Some(MenuItemType::LinkBlank(label, path)) => html! { + li class="link_blank" { + a href=(path) target="_blank" { (label) } + } + }, + Some(MenuItemType::Markup(markup)) => html! { + li class="markup" { (*markup) } + }, + Some(MenuItemType::Submenu(label, menu)) => html! { + li class="submenu" { + a href="#" { (label) } + ul { + (menu.render_items(assets)) + } + } + }, + Some(MenuItemType::Separator) => html! { + li class="separator" { } + }, + None => html! {} + } + } +} + +impl MenuItem { + + pub fn label(label: &str) -> Self { + MenuItem { + renderable: always, + weight : 0, + item_type : Some(MenuItemType::Label(label.to_string())), + } + } + + pub fn link(label: &str, path: &str) -> Self { + MenuItem { + renderable: always, + weight : 0, + item_type : Some(MenuItemType::Link( + label.to_string(), + path.to_string(), + )), + } + } + + pub fn link_blank(label: &str, path: &str) -> Self { + MenuItem { + renderable: always, + weight : 0, + item_type : Some(MenuItemType::LinkBlank( + label.to_string(), + path.to_string(), + )), + } + } + + pub fn markup(markup: Markup) -> Self { + MenuItem { + renderable: always, + weight : 0, + item_type : Some(MenuItemType::Markup(markup)), + } + } + + pub fn separator() -> Self { + MenuItem { + renderable: always, + weight : 0, + item_type : Some(MenuItemType::Separator), + } + } + + pub fn submenu(label: &str, menu: Menu) -> Self { + MenuItem { + renderable: always, + weight : 0, + item_type : Some(MenuItemType::Submenu( + label.to_string(), + menu + )), + } + } + + // MenuItem BUILDER. + + pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self { + self.renderable = renderable; + self + } + + pub fn with_weight(mut self, weight: i8) -> Self { + self.weight = weight; + self + } +} + +// ----------------------------------------------------------------------------- +// Menu. +// ----------------------------------------------------------------------------- + +pub struct Menu { + renderable: fn() -> bool, + weight : i8, + id : Option, + items : PageContainer, + template : String, +} + +impl PageComponent for Menu { + + fn prepare() -> Self { + Menu { + renderable: always, + weight : 0, + id : None, + items : PageContainer::new(), + template : "default".to_string(), + } + } + + fn is_renderable(&self) -> bool { + (self.renderable)() + } + + fn weight(&self) -> i8 { + self.weight + } + + fn default_render(&self, assets: &mut PageAssets) -> Markup { + assets + .add_stylesheet(StyleSheet::source( + "/theme/menu/css/menu.css?ver=1.1.1" + )) + .add_stylesheet(StyleSheet::source( + "/theme/menu/css/menu-clean.css?ver=1.1.1" + )) + .add_javascript(JavaScript::source( + "/theme/menu/js/menu.min.js?ver=1.1.1" + )) + .add_jquery(); + + let id = assets.required_id(self.name(), self.id()); + html! { + ul id=(id) class="sm sm-clean" { + (self.render_items(assets)) + } + script type="text/javascript" defer { + "jQuery(function(){jQuery('#" (id) "').smartmenus({" + "hideTimeout: 0," + "showTimeout: 80," + "});});" + } + } + } +} + +impl Menu { + + // Menu BUILDER. + + pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self { + self.renderable = renderable; + self + } + + pub fn with_weight(mut self, weight: i8) -> Self { + self.weight = weight; + self + } + + pub fn with_id(mut self, id: &str) -> Self { + self.id = util::valid_id(id); + self + } + + pub fn add(mut self, item: MenuItem) -> Self { + self.items.add(item); + self + } + + pub fn using_template(mut self, template: &str) -> Self { + self.template = template.to_string(); + self + } + + // Menu GETTERS. + + pub fn id(&self) -> &str { + util::assigned_value(&self.id) + } + + pub fn template(&self) -> &str { + self.template.as_str() + } + + // Menu EXTRAS. + + pub fn render_items(&self, assets: &mut PageAssets) -> Markup { + html! { (self.items.render(assets)) } + } +} + +fn always() -> bool { + true +} diff --git a/src/base/component/mod.rs b/src/base/component/mod.rs index 07c16cf7..f9973108 100644 --- a/src/base/component/mod.rs +++ b/src/base/component/mod.rs @@ -2,6 +2,10 @@ mod container; pub use container::Container; mod chunck; pub use chunck::Chunck; +mod block; +pub use block::Block; +mod menu; +pub use menu::{Menu, MenuItem}; pub mod form; pub use form::{Form, FormMethod}; diff --git a/src/base/module/admin/configure.rs b/src/base/module/admin/configure.rs new file mode 100644 index 00000000..1859f016 --- /dev/null +++ b/src/base/module/admin/configure.rs @@ -0,0 +1,17 @@ +use crate::prelude::*; +use crate::base::module::admin::summary::summary; + +pub struct AdminModule; + +impl Module for AdminModule { + fn name(&self) -> String { + "PageTop Admin".to_string() + } + + fn configure_module(&self, cfg: &mut server::web::ServiceConfig) { + cfg.service( + server::web::scope("/admin") + .route("", server::web::get().to(summary)) + ); + } +} diff --git a/src/base/module/admin/mod.rs b/src/base/module/admin/mod.rs new file mode 100644 index 00000000..1444391b --- /dev/null +++ b/src/base/module/admin/mod.rs @@ -0,0 +1,4 @@ +mod configure; +pub use configure::AdminModule; + +mod summary; diff --git a/src/base/module/admin/summary.rs b/src/base/module/admin/summary.rs new file mode 100644 index 00000000..6f620fd0 --- /dev/null +++ b/src/base/module/admin/summary.rs @@ -0,0 +1,54 @@ +use crate::prelude::*; + +pub async fn summary() -> server::Result { + let top_menu = Menu::prepare() + .add(MenuItem::label("Opción 1")) + .add(MenuItem::link("Opción 2", "https://www.google.es")) + .add(MenuItem::link_blank("Opción 3", "https://www.google.es")) + .add(MenuItem::submenu("Submenú 1", Menu::prepare() + .add(MenuItem::label("Opción 1")) + .add(MenuItem::label("Opción 2")) + )) + .add(MenuItem::separator()) + .add(MenuItem::submenu("Submenú 2", Menu::prepare() + .add(MenuItem::label("Opción 1")) + .add(MenuItem::label("Opción 2")) + )) + .add(MenuItem::label("Opción 4")); + + let side_menu = Menu::prepare() + .add(MenuItem::label("Opción 1")) + .add(MenuItem::link("Opción 2", "https://www.google.es")) + .add(MenuItem::link_blank("Opción 3", "https://www.google.es")) + .add(MenuItem::submenu("Submenú 1", Menu::prepare() + .add(MenuItem::label("Opción 1")) + .add(MenuItem::label("Opción 2")) + )) + .add(MenuItem::separator()) + .add(MenuItem::submenu("Submenú 2", Menu::prepare() + .add(MenuItem::label("Opción 1")) + .add(MenuItem::label("Opción 2")) + )) + .add(MenuItem::label("Opción 4")); + + Page::prepare() + .with_title("Admin") + + .add_to("top-menu", top_menu) + + .add_to("content", Container::row() + .add(Container::column() + .add(side_menu) + ) + .add(Container::column() + .add(Chunck::markup(html! { + p { "Columna 2"} + })) + ) + ) + + + .using_template("admin") + + .render() +} diff --git a/src/base/module/mod.rs b/src/base/module/mod.rs index dd90a79f..3a4e2d51 100644 --- a/src/base/module/mod.rs +++ b/src/base/module/mod.rs @@ -1,2 +1,3 @@ +pub mod admin; pub mod homepage; pub mod user; diff --git a/src/base/theme/bootsier/mod.rs b/src/base/theme/bootsier/mod.rs index 92e7437a..2d37cb05 100644 --- a/src/base/theme/bootsier/mod.rs +++ b/src/base/theme/bootsier/mod.rs @@ -26,13 +26,13 @@ impl Theme for BootsierTheme { ) .add_stylesheet( StyleSheet::source( - "/bootsier/css/bootstrap.min.css?v=5.1.3" + "/bootsier/css/bootstrap.min.css?ver=5.1.3" ) .with_weight(-99) ) .add_javascript( JavaScript::source( - "/bootsier/js/bootstrap.bundle.min.js?v=5.1.3" + "/bootsier/js/bootstrap.bundle.min.js?ver=5.1.3" ) .with_weight(-99) ) diff --git a/src/core/response/page/assets.rs b/src/core/response/page/assets.rs index c01855d9..8d929f79 100644 --- a/src/core/response/page/assets.rs +++ b/src/core/response/page/assets.rs @@ -177,7 +177,7 @@ pub struct Assets { stylesheets: Vec, javascripts: Vec, with_jquery: bool, - seqid_count: u16, + id_counter : u32, } impl Assets { @@ -188,7 +188,7 @@ impl Assets { stylesheets: Vec::new(), javascripts: Vec::new(), with_jquery: false, - seqid_count: 0, + id_counter : 0, } } @@ -228,7 +228,7 @@ impl Assets { if !self.with_jquery { self.add_javascript( JavaScript::source( - "/theme/js/jquery.min.js?v=3.6.0" + "/theme/js/jquery.min.js?ver=3.6.0" ) .with_weight(i8::MIN) .with_mode(JSMode::Normal) @@ -262,13 +262,20 @@ impl Assets { } } - // Assets GETTERS. + // Assets EXTRAS. - pub fn seqid(&mut self, id: &str) -> String { + pub fn required_id(&mut self, prefix: &str, id: &str) -> String { if id.is_empty() { - self.seqid_count += 1; - return format!("seqid-{}", self.seqid_count); + let prefix = prefix.trim().replace(" ", "_").to_lowercase(); + let prefix = if prefix.is_empty() { + "prefix".to_string() + } else { + prefix + }; + self.id_counter += 1; + [prefix, self.id_counter.to_string()].join("-") + } else { + id.to_string() } - id.to_string() } } diff --git a/src/core/response/page/component.rs b/src/core/response/page/component.rs index 097d960f..aebb1f43 100644 --- a/src/core/response/page/component.rs +++ b/src/core/response/page/component.rs @@ -9,6 +9,14 @@ pub trait Component: Downcast + Send + Sync { fn prepare() -> Self where Self: Sized; + fn name(&self) -> &str { + let name = type_name::(); + match name.rfind("::") { + Some(position) => &name[(position + 2)..], + None => name + } + } + fn qualified_name(&self) -> &str { type_name::() } diff --git a/src/core/state.rs b/src/core/state.rs index 307455a1..a53d8d80 100644 --- a/src/core/state.rs +++ b/src/core/state.rs @@ -39,6 +39,7 @@ pub fn register_theme(t: &'static (dyn Theme + 'static)) { pub static MODULES: Lazy>> = Lazy::new(|| { RwLock::new(vec![ + &base::module::admin::AdminModule, &base::module::user::UserModule, ]) }); diff --git a/src/lib.rs b/src/lib.rs index 327379a9..42f51a3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,11 +7,11 @@ pub use once_cell::sync::Lazy; // APIs públicas. // ----------------------------------------------------------------------------- -pub mod macros; // Macros útiles. pub mod config; // Gestión de la configuración. pub mod trace; // Traza de ejecución. pub mod locale; // Localización. pub mod core; // Servidor web y sistemas para Temas, Módulos y Respuestas. pub mod base; // Temas, Módulos y Componentes base. +pub mod util; // Macros y funciones útiles. pub mod prelude; // Re-exporta recursos comunes. diff --git a/src/macros/mod.rs b/src/macros/mod.rs deleted file mode 100644 index 88ab3f90..00000000 --- a/src/macros/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[macro_export] -/// Macro para construir grupos de pares clave-valor. -/// -/// ``` -/// let args = args![ -/// "userName" => "Roberto", -/// "photoCount" => 3, -/// "userGender" => "male" -/// ]; -/// ``` -macro_rules! args { - ( $($key:expr => $value:expr),* ) => {{ - let mut a = std::collections::HashMap::new(); - $( - a.insert(String::from($key), $value.into()); - )* - a - }}; -} diff --git a/src/prelude.rs b/src/prelude.rs index b4b62b18..4a66e08b 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,6 +1,8 @@ //! Re-exporta recursos comunes. pub use crate::args; +pub use crate::util; + pub use crate::config::SETTINGS; pub use crate::trace; pub use crate::localize; diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 00000000..638e948f --- /dev/null +++ b/src/util.rs @@ -0,0 +1,42 @@ +#[macro_export] +/// Macro para construir grupos de pares clave-valor. +/// +/// ``` +/// let args = args![ +/// "userName" => "Roberto", +/// "photoCount" => 3, +/// "userGender" => "male" +/// ]; +/// ``` +macro_rules! args { + ( $($key:expr => $value:expr),* ) => {{ + let mut a = std::collections::HashMap::new(); + $( + a.insert(String::from($key), $value.into()); + )* + a + }}; +} + +pub fn valid_id(id: &str) -> Option { + let id = id.trim().replace(" ", "_").to_lowercase(); + match id.is_empty() { + true => None, + false => Some(id), + } +} + +pub fn optional_value(value: &str) -> Option { + let value = value.to_string(); + match value.is_empty() { + true => None, + false => Some(value), + } +} + +pub fn assigned_value(value: &Option) -> &str { + match value { + Some(value) => value.as_str(), + _ => "", + } +} diff --git a/static/theme/menu/css/menu-blue.css b/static/theme/menu/css/menu-blue.css new file mode 100644 index 00000000..4cff3bb5 --- /dev/null +++ b/static/theme/menu/css/menu-blue.css @@ -0,0 +1,333 @@ +@import url(https://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700); +.sm-blue { + background: transparent; + border-radius: 8px; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); +} +.sm-blue a, .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active { + padding: 10px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + font-family: "PT Sans Narrow", "Arial Narrow", Arial, Helvetica, sans-serif; + font-size: 18px; + font-weight: bold; + line-height: 23px; + text-decoration: none; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2); +} +.sm-blue a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; +} +.sm-blue a.disabled { + color: #a1d1e8; +} +.sm-blue a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 16px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; +} +.sm-blue a .sub-arrow::before { + content: '+'; +} +.sm-blue a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-blue > li:first-child > a, .sm-blue > li:first-child > :not(ul) a { + border-radius: 8px 8px 0 0; +} +.sm-blue > li:last-child > a, .sm-blue > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul { + border-radius: 0 0 8px 8px; +} +.sm-blue > li:last-child > a.highlighted, .sm-blue > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-blue > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted { + border-radius: 0; +} +.sm-blue ul { + background: #fff; +} +.sm-blue ul ul { + background: rgba(102, 102, 102, 0.1); +} +.sm-blue ul a, .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active { + background: transparent; + color: #2b82ac; + font-size: 16px; + text-shadow: none; + border-left: 8px solid transparent; +} +.sm-blue ul a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; +} +.sm-blue ul a.disabled { + color: #b3b3b3; +} +.sm-blue ul ul a, +.sm-blue ul ul a:hover, +.sm-blue ul ul a:focus, +.sm-blue ul ul a:active { + border-left: 16px solid transparent; +} +.sm-blue ul ul ul a, +.sm-blue ul ul ul a:hover, +.sm-blue ul ul ul a:focus, +.sm-blue ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-blue ul ul ul ul a, +.sm-blue ul ul ul ul a:hover, +.sm-blue ul ul ul ul a:focus, +.sm-blue ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-blue ul ul ul ul ul a, +.sm-blue ul ul ul ul ul a:hover, +.sm-blue ul ul ul ul ul a:focus, +.sm-blue ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} +.sm-blue ul li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-blue ul li:first-child { + border-top: 0; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-blue ul { + position: absolute; + width: 12em; + } + + .sm-blue li { + float: left; + } + + .sm-blue.sm-rtl li { + float: right; + } + + .sm-blue ul li, .sm-blue.sm-rtl ul li, .sm-blue.sm-vertical li { + float: none; + } + + .sm-blue a { + white-space: nowrap; + } + + .sm-blue ul a, .sm-blue.sm-vertical a { + white-space: normal; + } + + .sm-blue .sm-nowrap > li > a, .sm-blue .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-blue { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + border-radius: 8px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + } + .sm-blue a, .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active, .sm-blue a.highlighted { + padding: 13px 24px; + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + } + .sm-blue a:hover, .sm-blue a:focus, .sm-blue a:active, .sm-blue a.highlighted { + background: #2b82ac; + background-image: linear-gradient(to bottom, #2d89b4, #297ca3); + } + .sm-blue a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; + } + .sm-blue a.disabled { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #a1d1e8; + } + .sm-blue a .sub-arrow { + top: auto; + margin-top: 0; + bottom: 2px; + left: 50%; + margin-left: -5px; + right: auto; + width: 0; + height: 0; + border-width: 5px; + border-style: solid dashed dashed dashed; + border-color: #a1d1e8 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-blue a .sub-arrow::before { + display: none; + } + .sm-blue > li:first-child > a, .sm-blue > li:first-child > :not(ul) a { + border-radius: 8px 0 0 8px; + } + .sm-blue > li:last-child > a, .sm-blue > li:last-child > :not(ul) a { + border-radius: 0 8px 8px 0 !important; + } + .sm-blue > li { + border-left: 1px solid #2b82ac; + } + .sm-blue > li:first-child { + border-left: 0; + } + .sm-blue ul { + border: 1px solid #a8a8a8; + padding: 7px 0; + background: #fff; + border-radius: 0 0 4px 4px !important; + box-shadow: 0 5px 12px rgba(0, 0, 0, 0.2); + } + .sm-blue ul ul { + border-radius: 4px !important; + background: #fff; + } + .sm-blue ul a, .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active, .sm-blue ul a.highlighted { + border: 0 !important; + padding: 9px 23px; + background: transparent; + color: #2b82ac; + border-radius: 0 !important; + } + .sm-blue ul a:hover, .sm-blue ul a:focus, .sm-blue ul a:active, .sm-blue ul a.highlighted { + background: #3092c0; + background-image: linear-gradient(to bottom, #3298c8, #2e8cb8); + color: #fff; + } + .sm-blue ul a.current { + background: #006892; + background-image: linear-gradient(to bottom, #006188, #006f9c); + color: #fff; + } + .sm-blue ul a.disabled { + background: #fff; + color: #b3b3b3; + } + .sm-blue ul a .sub-arrow { + top: 50%; + margin-top: -5px; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #a1d1e8; + } + .sm-blue ul li { + border: 0; + } + .sm-blue .scroll-up, + .sm-blue .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-blue .scroll-up-arrow, + .sm-blue .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #2b82ac transparent; + } + .sm-blue .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: #2b82ac transparent transparent transparent; + } + .sm-blue.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent #a1d1e8 transparent transparent; + } + .sm-blue.sm-rtl > li:first-child > a, .sm-blue.sm-rtl > li:first-child > :not(ul) a { + border-radius: 0 8px 8px 0; + } + .sm-blue.sm-rtl > li:last-child > a, .sm-blue.sm-rtl > li:last-child > :not(ul) a { + border-radius: 8px 0 0 8px !important; + } + .sm-blue.sm-rtl > li:first-child { + border-left: 1px solid #2b82ac; + } + .sm-blue.sm-rtl > li:last-child { + border-left: 0; + } + .sm-blue.sm-rtl ul a .sub-arrow { + right: auto; + left: 10px; + border-style: dashed solid dashed dashed; + border-color: transparent #a1d1e8 transparent transparent; + } + .sm-blue.sm-vertical { + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); + } + .sm-blue.sm-vertical a { + padding: 9px 23px; + } + .sm-blue.sm-vertical a .sub-arrow { + top: 50%; + margin-top: -5px; + bottom: auto; + left: auto; + margin-left: 0; + right: 10px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #a1d1e8; + } + .sm-blue.sm-vertical > li:first-child > a, .sm-blue.sm-vertical > li:first-child > :not(ul) a { + border-radius: 8px 8px 0 0; + } + .sm-blue.sm-vertical > li:last-child > a, .sm-blue.sm-vertical > li:last-child > :not(ul) a { + border-radius: 0 0 8px 8px !important; + } + .sm-blue.sm-vertical > li { + border-left: 0 !important; + } + .sm-blue.sm-vertical ul { + border-radius: 4px !important; + } + .sm-blue.sm-vertical ul a { + padding: 9px 23px; + } +} + +/*# sourceMappingURL=sm-blue.css.map */ diff --git a/static/theme/menu/css/menu-clean.css b/static/theme/menu/css/menu-clean.css new file mode 100644 index 00000000..4fb39b72 --- /dev/null +++ b/static/theme/menu/css/menu-clean.css @@ -0,0 +1,327 @@ +.sm-clean { + background: #eeeeee; + border-radius: 5px; +} +.sm-clean a, .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #555555; + font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif; + font-size: 18px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-clean a.current { + color: #D23600; +} +.sm-clean a.disabled { + color: #bbbbbb; +} +.sm-clean a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 16px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(255, 255, 255, 0.5); + border-radius: 5px; +} +.sm-clean a .sub-arrow::before { + content: '+'; +} +.sm-clean a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-clean > li:first-child > a, .sm-clean > li:first-child > :not(ul) a { + border-radius: 5px 5px 0 0; +} +.sm-clean > li:last-child > a, .sm-clean > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul { + border-radius: 0 0 5px 5px; +} +.sm-clean > li:last-child > a.highlighted, .sm-clean > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > a.highlighted, .sm-clean > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > ul > li:last-child > *:not(ul) a.highlighted { + border-radius: 0; +} +.sm-clean li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-clean > li:first-child { + border-top: 0; +} +.sm-clean ul { + background: rgba(162, 162, 162, 0.1); +} +.sm-clean ul a, .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active { + font-size: 16px; + border-left: 8px solid transparent; +} +.sm-clean ul ul a, +.sm-clean ul ul a:hover, +.sm-clean ul ul a:focus, +.sm-clean ul ul a:active { + border-left: 16px solid transparent; +} +.sm-clean ul ul ul a, +.sm-clean ul ul ul a:hover, +.sm-clean ul ul ul a:focus, +.sm-clean ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-clean ul ul ul ul a, +.sm-clean ul ul ul ul a:hover, +.sm-clean ul ul ul ul a:focus, +.sm-clean ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-clean ul ul ul ul ul a, +.sm-clean ul ul ul ul ul a:hover, +.sm-clean ul ul ul ul ul a:focus, +.sm-clean ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-clean ul { + position: absolute; + width: 12em; + } + + .sm-clean li { + float: left; + } + + .sm-clean.sm-rtl li { + float: right; + } + + .sm-clean ul li, .sm-clean.sm-rtl ul li, .sm-clean.sm-vertical li { + float: none; + } + + .sm-clean a { + white-space: nowrap; + } + + .sm-clean ul a, .sm-clean.sm-vertical a { + white-space: normal; + } + + .sm-clean .sm-nowrap > li > a, .sm-clean .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-clean { + padding: 0 10px; + background: #eeeeee; + border-radius: 100px; + } + .sm-clean a, .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active, .sm-clean a.highlighted { + padding: 12px 12px; + color: #555555; + border-radius: 0 !important; + } + .sm-clean a:hover, .sm-clean a:focus, .sm-clean a:active, .sm-clean a.highlighted { + color: #D23600; + } + .sm-clean a.current { + color: #D23600; + } + .sm-clean a.disabled { + color: #bbbbbb; + } + .sm-clean a.has-submenu { + padding-right: 24px; + } + .sm-clean a .sub-arrow { + top: 50%; + margin-top: -2px; + right: 12px; + width: 0; + height: 0; + border-width: 4px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-clean a .sub-arrow::before { + display: none; + } + .sm-clean li { + border-top: 0; + } + .sm-clean > li > ul::before, + .sm-clean > li > ul::after { + content: ''; + position: absolute; + top: -18px; + left: 30px; + width: 0; + height: 0; + overflow: hidden; + border-width: 9px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #bbbbbb transparent; + } + .sm-clean > li > ul::after { + top: -16px; + left: 31px; + border-width: 8px; + border-color: transparent transparent #fff transparent; + } + .sm-clean ul { + border: 1px solid #bbbbbb; + padding: 5px 0; + background: #fff; + border-radius: 5px !important; + box-shadow: 0 5px 9px rgba(0, 0, 0, 0.2); + } + .sm-clean ul a, .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active, .sm-clean ul a.highlighted { + border: 0 !important; + padding: 10px 20px; + color: #555555; + } + .sm-clean ul a:hover, .sm-clean ul a:focus, .sm-clean ul a:active, .sm-clean ul a.highlighted { + background: #eeeeee; + color: #D23600; + } + .sm-clean ul a.current { + color: #D23600; + } + .sm-clean ul a.disabled { + background: #fff; + color: #cccccc; + } + .sm-clean ul a.has-submenu { + padding-right: 20px; + } + .sm-clean ul a .sub-arrow { + right: 8px; + top: 50%; + margin-top: -5px; + border-width: 5px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #555555; + } + .sm-clean .scroll-up, + .sm-clean .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-clean .scroll-up:hover, + .sm-clean .scroll-down:hover { + background: #eeeeee; + } + .sm-clean .scroll-up:hover .scroll-up-arrow { + border-color: transparent transparent #D23600 transparent; + } + .sm-clean .scroll-down:hover .scroll-down-arrow { + border-color: #D23600 transparent transparent transparent; + } + .sm-clean .scroll-up-arrow, + .sm-clean .scroll-down-arrow { + position: absolute; + top: 0; + left: 50%; + margin-left: -6px; + width: 0; + height: 0; + overflow: hidden; + border-width: 6px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #555555 transparent; + } + .sm-clean .scroll-down-arrow { + top: 8px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + } + .sm-clean.sm-rtl a.has-submenu { + padding-right: 12px; + padding-left: 24px; + } + .sm-clean.sm-rtl a .sub-arrow { + right: auto; + left: 12px; + } + .sm-clean.sm-rtl.sm-vertical a.has-submenu { + padding: 10px 20px; + } + .sm-clean.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent #555555 transparent transparent; + } + .sm-clean.sm-rtl > li > ul::before { + left: auto; + right: 30px; + } + .sm-clean.sm-rtl > li > ul::after { + left: auto; + right: 31px; + } + .sm-clean.sm-rtl ul a.has-submenu { + padding: 10px 20px !important; + } + .sm-clean.sm-rtl ul a .sub-arrow { + right: auto; + left: 8px; + border-style: dashed solid dashed dashed; + border-color: transparent #555555 transparent transparent; + } + .sm-clean.sm-vertical { + padding: 10px 0; + border-radius: 5px; + } + .sm-clean.sm-vertical a { + padding: 10px 20px; + } + .sm-clean.sm-vertical a:hover, .sm-clean.sm-vertical a:focus, .sm-clean.sm-vertical a:active, .sm-clean.sm-vertical a.highlighted { + background: #fff; + } + .sm-clean.sm-vertical a.disabled { + background: #eeeeee; + } + .sm-clean.sm-vertical a .sub-arrow { + right: 8px; + top: 50%; + margin-top: -5px; + border-width: 5px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #555555; + } + .sm-clean.sm-vertical > li > ul::before, + .sm-clean.sm-vertical > li > ul::after { + display: none; + } + .sm-clean.sm-vertical ul a { + padding: 10px 20px; + } + .sm-clean.sm-vertical ul a:hover, .sm-clean.sm-vertical ul a:focus, .sm-clean.sm-vertical ul a:active, .sm-clean.sm-vertical ul a.highlighted { + background: #eeeeee; + } + .sm-clean.sm-vertical ul a.disabled { + background: #fff; + } +} + +/*# sourceMappingURL=sm-clean.css.map */ diff --git a/static/theme/menu/css/menu-mint.css b/static/theme/menu/css/menu-mint.css new file mode 100644 index 00000000..1ab65555 --- /dev/null +++ b/static/theme/menu/css/menu-mint.css @@ -0,0 +1,331 @@ +.sm-mint { + border-top: 2px solid #8db863; + border-bottom: 2px solid #8db863; + background: #fff; +} +.sm-mint a, .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #333; + font-family: Arial, sans-serif; + font-size: 16px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-mint a.current { + font-weight: bold; +} +.sm-mint a.disabled { + color: #cccccc; +} +.sm-mint a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 14px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(141, 184, 99, 0.2); + border-radius: 4px; +} +.sm-mint a .sub-arrow::before { + content: '+'; +} +.sm-mint a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-mint li { + border-top: 1px solid rgba(141, 184, 99, 0.2); +} +.sm-mint > li:first-child { + border-top: 0; +} +.sm-mint ul { + background: rgba(141, 184, 99, 0.2); +} +.sm-mint ul a, .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active { + font-size: 14px; + border-left: 8px solid transparent; +} +.sm-mint ul ul a, +.sm-mint ul ul a:hover, +.sm-mint ul ul a:focus, +.sm-mint ul ul a:active { + border-left: 16px solid transparent; +} +.sm-mint ul ul ul a, +.sm-mint ul ul ul a:hover, +.sm-mint ul ul ul a:focus, +.sm-mint ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-mint ul ul ul ul a, +.sm-mint ul ul ul ul a:hover, +.sm-mint ul ul ul ul a:focus, +.sm-mint ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-mint ul ul ul ul ul a, +.sm-mint ul ul ul ul ul a:hover, +.sm-mint ul ul ul ul ul a:focus, +.sm-mint ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-mint ul { + position: absolute; + width: 12em; + } + + .sm-mint li { + float: left; + } + + .sm-mint.sm-rtl li { + float: right; + } + + .sm-mint ul li, .sm-mint.sm-rtl ul li, .sm-mint.sm-vertical li { + float: none; + } + + .sm-mint a { + white-space: nowrap; + } + + .sm-mint ul a, .sm-mint.sm-vertical a { + white-space: normal; + } + + .sm-mint .sm-nowrap > li > a, .sm-mint .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-mint { + border-top: 0; + background: transparent; + } + .sm-mint a, .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active, .sm-mint a.highlighted { + padding: 11px 20px; + color: #333; + border-radius: 4px 4px 0 0; + } + .sm-mint a:hover, .sm-mint a:focus, .sm-mint a:active { + background: #8db863; + color: #fff; + } + .sm-mint a.highlighted { + background: #F6FFED; + color: #333; + box-shadow: 0 4px 3px rgba(0, 0, 0, 0.25); + } + .sm-mint a.disabled { + background: transparent; + color: #cccccc; + box-shadow: none; + } + .sm-mint a.has-submenu { + padding-right: 34px; + } + .sm-mint a .sub-arrow { + top: 50%; + margin-top: -3px; + right: 20px; + width: 0; + height: 0; + border-width: 6px 4.02px 0 4.02px; + border-style: solid dashed dashed dashed; + border-color: #8db863 transparent transparent transparent; + background: transparent; + border-radius: 0; + } + .sm-mint a:hover .sub-arrow, .sm-mint a:focus .sub-arrow, .sm-mint a:active .sub-arrow { + border-color: #fff transparent transparent transparent; + } + .sm-mint a.highlighted .sub-arrow { + border-color: #8db863 transparent transparent transparent; + } + .sm-mint a.disabled .sub-arrow { + border-color: #8db863 transparent transparent transparent; + } + .sm-mint a .sub-arrow::before { + display: none; + } + .sm-mint li { + border-top: 0; + } + .sm-mint ul { + border: 0; + padding: 8px 0; + background: #F6FFED; + border-radius: 0 4px 4px 4px; + box-shadow: 0 4px 3px rgba(0, 0, 0, 0.25); + } + .sm-mint ul ul { + border-radius: 4px; + } + .sm-mint ul a, .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active, .sm-mint ul a.highlighted { + border: 0 !important; + padding: 10px 20px; + color: #333; + border-radius: 0; + } + .sm-mint ul a:hover, .sm-mint ul a:focus, .sm-mint ul a:active, .sm-mint ul a.highlighted { + background: #8db863; + color: #fff; + box-shadow: none; + } + .sm-mint ul a.disabled { + background: transparent; + color: #b3b3b3; + } + .sm-mint ul a.has-submenu { + padding-right: 20px; + } + .sm-mint ul a .sub-arrow { + right: 10px; + margin-top: -4.02px; + border-width: 4.02px 0 4.02px 6px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #8db863; + } + .sm-mint ul a:hover .sub-arrow, .sm-mint ul a:focus .sub-arrow, .sm-mint ul a:active .sub-arrow, .sm-mint ul a.highlighted .sub-arrow { + border-color: transparent transparent transparent #fff; + } + .sm-mint ul a.disabled .sub-arrow { + border-color: transparent transparent transparent #8db863; + } + .sm-mint .scroll-up, + .sm-mint .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #F6FFED; + height: 20px; + } + .sm-mint .scroll-up-arrow, + .sm-mint .scroll-down-arrow { + position: absolute; + top: 6px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 0 6px 8px 6px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #8db863 transparent; + } + .sm-mint .scroll-down-arrow { + border-width: 8px 6px 0 6px; + border-style: solid dashed dashed dashed; + border-color: #8db863 transparent transparent transparent; + } + .sm-mint.sm-rtl a.has-submenu { + padding-right: 20px; + padding-left: 34px; + } + .sm-mint.sm-rtl a .sub-arrow { + right: auto; + left: 20px; + } + .sm-mint.sm-rtl.sm-vertical { + border-right: 0; + border-left: 2px solid #8db863; + } + .sm-mint.sm-rtl.sm-vertical a { + border-radius: 0 4px 4px 0; + } + .sm-mint.sm-rtl.sm-vertical a.has-submenu { + padding: 10px 20px; + } + .sm-mint.sm-rtl.sm-vertical a .sub-arrow { + right: auto; + left: 10px; + border-width: 4.02px 6px 4.02px 0; + border-style: dashed solid dashed dashed; + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl.sm-vertical a:hover .sub-arrow, .sm-mint.sm-rtl.sm-vertical a:focus .sub-arrow, .sm-mint.sm-rtl.sm-vertical a:active .sub-arrow, .sm-mint.sm-rtl.sm-vertical a.highlighted .sub-arrow { + border-color: transparent #fff transparent transparent; + } + .sm-mint.sm-rtl.sm-vertical a.disabled .sub-arrow { + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl ul { + border-radius: 4px 0 4px 4px; + } + .sm-mint.sm-rtl ul a { + border-radius: 0 !important; + } + .sm-mint.sm-rtl ul a.has-submenu { + padding: 10px 20px !important; + } + .sm-mint.sm-rtl ul a .sub-arrow { + right: auto; + left: 10px; + border-width: 4.02px 6px 4.02px 0; + border-style: dashed solid dashed dashed; + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-rtl ul a:hover .sub-arrow, .sm-mint.sm-rtl ul a:focus .sub-arrow, .sm-mint.sm-rtl ul a:active .sub-arrow, .sm-mint.sm-rtl ul a.highlighted .sub-arrow { + border-color: transparent #fff transparent transparent; + } + .sm-mint.sm-rtl ul a.disabled .sub-arrow { + border-color: transparent #8db863 transparent transparent; + } + .sm-mint.sm-vertical { + border-bottom: 0; + border-right: 2px solid #8db863; + } + .sm-mint.sm-vertical a { + padding: 10px 20px; + border-radius: 4px 0 0 4px; + } + .sm-mint.sm-vertical a:hover, .sm-mint.sm-vertical a:focus, .sm-mint.sm-vertical a:active, .sm-mint.sm-vertical a.highlighted { + background: #8db863; + color: #fff; + box-shadow: none; + } + .sm-mint.sm-vertical a.disabled { + background: transparent; + color: #cccccc; + } + .sm-mint.sm-vertical a .sub-arrow { + right: 10px; + margin-top: -4.02px; + border-width: 4.02px 0 4.02px 6px; + border-style: dashed dashed dashed solid; + border-color: transparent transparent transparent #8db863; + } + .sm-mint.sm-vertical a:hover .sub-arrow, .sm-mint.sm-vertical a:focus .sub-arrow, .sm-mint.sm-vertical a:active .sub-arrow, .sm-mint.sm-vertical a.highlighted .sub-arrow { + border-color: transparent transparent transparent #fff; + } + .sm-mint.sm-vertical a.disabled .sub-arrow { + border-color: transparent transparent transparent #8db863; + } + .sm-mint.sm-vertical ul { + border-radius: 4px !important; + } + .sm-mint.sm-vertical ul a { + padding: 10px 20px; + } +} + +/*# sourceMappingURL=sm-mint.css.map */ diff --git a/static/theme/menu/css/menu-simple.css b/static/theme/menu/css/menu-simple.css new file mode 100644 index 00000000..8fcf0c15 --- /dev/null +++ b/static/theme/menu/css/menu-simple.css @@ -0,0 +1,249 @@ +.sm-simple { + border: 1px solid #bbbbbb; + background: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); +} +.sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active { + padding: 13px 20px; + /* make room for the toggle button (sub indicator) */ + padding-right: 58px; + color: #555555; + font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif; + font-size: 16px; + font-weight: normal; + line-height: 17px; + text-decoration: none; +} +.sm-simple a.current { + background: #555555; + color: #fff; +} +.sm-simple a.disabled { + color: #cccccc; +} +.sm-simple a .sub-arrow { + position: absolute; + top: 50%; + margin-top: -17px; + left: auto; + right: 4px; + width: 34px; + height: 34px; + overflow: hidden; + font: bold 14px/34px monospace !important; + text-align: center; + text-shadow: none; + background: rgba(0, 0, 0, 0.08); +} +.sm-simple a .sub-arrow::before { + content: '+'; +} +.sm-simple a.highlighted .sub-arrow::before { + content: '-'; +} +.sm-simple li { + border-top: 1px solid rgba(0, 0, 0, 0.05); +} +.sm-simple > li:first-child { + border-top: 0; +} +.sm-simple ul { + background: rgba(179, 179, 179, 0.1); +} +.sm-simple ul a, .sm-simple ul a:hover, .sm-simple ul a:focus, .sm-simple ul a:active { + font-size: 14px; + border-left: 8px solid transparent; +} +.sm-simple ul ul a, +.sm-simple ul ul a:hover, +.sm-simple ul ul a:focus, +.sm-simple ul ul a:active { + border-left: 16px solid transparent; +} +.sm-simple ul ul ul a, +.sm-simple ul ul ul a:hover, +.sm-simple ul ul ul a:focus, +.sm-simple ul ul ul a:active { + border-left: 24px solid transparent; +} +.sm-simple ul ul ul ul a, +.sm-simple ul ul ul ul a:hover, +.sm-simple ul ul ul ul a:focus, +.sm-simple ul ul ul ul a:active { + border-left: 32px solid transparent; +} +.sm-simple ul ul ul ul ul a, +.sm-simple ul ul ul ul ul a:hover, +.sm-simple ul ul ul ul ul a:focus, +.sm-simple ul ul ul ul ul a:active { + border-left: 40px solid transparent; +} + +@media (min-width: 768px) { + /* Switch to desktop layout + ----------------------------------------------- + These transform the menu tree from + collapsible to desktop (navbar + dropdowns) + -----------------------------------------------*/ + /* start... (it's not recommended editing these rules) */ + .sm-simple ul { + position: absolute; + width: 12em; + } + + .sm-simple li { + float: left; + } + + .sm-simple.sm-rtl li { + float: right; + } + + .sm-simple ul li, .sm-simple.sm-rtl ul li, .sm-simple.sm-vertical li { + float: none; + } + + .sm-simple a { + white-space: nowrap; + } + + .sm-simple ul a, .sm-simple.sm-vertical a { + white-space: normal; + } + + .sm-simple .sm-nowrap > li > a, .sm-simple .sm-nowrap > li > :not(ul) a { + white-space: nowrap; + } + + /* ...end */ + .sm-simple { + background: #fff; + } + .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted { + padding: 11px 20px; + color: #555555; + } + .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted { + background: #eeeeee; + } + .sm-simple a.current { + background: #555555; + color: #fff; + } + .sm-simple a.disabled { + background: #fff; + color: #cccccc; + } + .sm-simple a.has-submenu { + padding-right: 32px; + } + .sm-simple a .sub-arrow { + top: 50%; + margin-top: -8px; + right: 20px; + width: 8px; + height: 16px; + font: 14px/16px monospace !important; + background: transparent; + } + .sm-simple a.highlighted .sub-arrow::before { + content: '+'; + } + .sm-simple > li { + border-top: 0; + border-left: 1px solid #eeeeee; + } + .sm-simple > li:first-child { + border-left: 0; + } + .sm-simple ul { + border: 1px solid #bbbbbb; + background: #fff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + } + .sm-simple ul a { + border: 0 !important; + } + .sm-simple ul a.has-submenu { + padding-right: 20px; + } + .sm-simple ul a .sub-arrow { + left: 8px; + right: auto; + } + .sm-simple ul > li { + border-left: 0; + border-top: 1px solid #eeeeee; + } + .sm-simple ul > li:first-child { + border-top: 0; + } + .sm-simple .scroll-up, + .sm-simple .scroll-down { + position: absolute; + display: none; + visibility: hidden; + overflow: hidden; + background: #fff; + height: 20px; + } + .sm-simple .scroll-up-arrow, + .sm-simple .scroll-down-arrow { + position: absolute; + top: -2px; + left: 50%; + margin-left: -8px; + width: 0; + height: 0; + overflow: hidden; + border-width: 8px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #555555 transparent; + } + .sm-simple .scroll-down-arrow { + top: 6px; + border-style: solid dashed dashed dashed; + border-color: #555555 transparent transparent transparent; + } + .sm-simple.sm-rtl a.has-submenu { + padding-right: 20px; + padding-left: 32px; + } + .sm-simple.sm-rtl a .sub-arrow { + left: 20px; + right: auto; + } + .sm-simple.sm-rtl.sm-vertical a.has-submenu { + padding: 11px 20px; + } + .sm-simple.sm-rtl.sm-vertical a .sub-arrow { + left: auto; + right: 8px; + } + .sm-simple.sm-rtl > li:first-child { + border-left: 1px solid #eeeeee; + } + .sm-simple.sm-rtl > li:last-child { + border-left: 0; + } + .sm-simple.sm-rtl ul a.has-submenu { + padding: 11px 20px; + } + .sm-simple.sm-rtl ul a .sub-arrow { + left: auto; + right: 8px; + } + .sm-simple.sm-vertical a .sub-arrow { + left: 8px; + right: auto; + } + .sm-simple.sm-vertical li { + border-left: 0; + border-top: 1px solid #eeeeee; + } + .sm-simple.sm-vertical > li:first-child { + border-top: 0; + } +} + +/*# sourceMappingURL=sm-simple.css.map */ diff --git a/static/theme/menu/css/menu.css b/static/theme/menu/css/menu.css new file mode 100644 index 00000000..95cdf757 --- /dev/null +++ b/static/theme/menu/css/menu.css @@ -0,0 +1,58 @@ +.sm { + box-sizing: border-box; + position: relative; + z-index: 9999; + -webkit-tap-highlight-color: rgba(0,0,0,0); +} +.sm, +.sm ul, +.sm li { + display: block; + list-style: none; + margin: 0; + padding: 0; + line-height: normal; + direction: ltr; + text-align: left; +} +.sm-rtl, +.sm-rtl ul, +.sm-rtl li { + direction: rtl; + text-align: right; +} +.sm > li > h1, +.sm > li > h2, +.sm > li > h3, +.sm > li > h4, +.sm > li > h5, +.sm > li > h6 { + margin: 0; + padding: 0; +} +.sm ul { + display: none; +} +.sm li, +.sm a { + position: relative; +} +.sm a { + display: block; +} +.sm a.disabled { + cursor: default; +} +.sm::after { + content: ""; + display: block; + height: 0; + font: 0px/0 serif; + clear: both; + overflow: hidden; +} +.sm *, +.sm *::before, +.sm *::after { + box-sizing: inherit; +} diff --git a/static/theme/menu/js/menu.min.js b/static/theme/menu/js/menu.min.js new file mode 100644 index 00000000..d60d33c5 --- /dev/null +++ b/static/theme/menu/js/menu.min.js @@ -0,0 +1,3 @@ +/*! SmartMenus jQuery Plugin - v1.1.1 - July 23, 2020 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&4>=o&&4>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a:not(.mega-menu a)").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=e.dataSM("sub"),s=i?2==i.dataSM("level"):!1;if(i){var o=$(t.target).is(".sub-arrow"),a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(i.is(":visible")){if(!a&&this.opts.showOnClick&&s)return this.menuHide(i),this.clickActivated=!1,this.focusActivated=!1,!1;if(a&&(n||o))return this.itemActivate(e,h),this.menuHide(i),!1}else if((!r||!a||o)&&(!a&&this.opts.showOnClick&&s&&(this.clickActivated=!0),this.itemActivate(e,h),i.is(":visible")))return this.focusActivated=!0,!1}return!a&&this.opts.showOnClick&&s||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),w=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),M=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=w?d-r-M:M,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=w?M-r:d-M,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(w&&f>y?e=g?f-y+e:d-M:!w&&y+r>f+b&&(e=g?f+b-r-y+e:M-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts&&"object"!=typeof dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file