diff --git a/.hgignore b/.hgignore index 4453837..2e155dd 100644 --- a/.hgignore +++ b/.hgignore @@ -1,4 +1,11 @@ syntax: glob -Build/ *.orig -.git \ No newline at end of file +*.suo +.git +Build/ +Documentation/Documentation/* +Documentation/Artifacts/* +Documentation/Manual/_build/* +Configuration/Configuration/bin/** +Configuration/Configuration/obj/** + diff --git a/Configuration/Configuration.sln b/Configuration/Configuration.sln new file mode 100644 index 0000000..8011aba --- /dev/null +++ b/Configuration/Configuration.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2013 for Windows Desktop +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Configuration", "Configuration\Configuration.csproj", "{90F163C8-2147-46C9-8BF5-C51116856F62}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {90F163C8-2147-46C9-8BF5-C51116856F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90F163C8-2147-46C9-8BF5-C51116856F62}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90F163C8-2147-46C9-8BF5-C51116856F62}.Debug|x86.ActiveCfg = Debug|x86 + {90F163C8-2147-46C9-8BF5-C51116856F62}.Debug|x86.Build.0 = Debug|x86 + {90F163C8-2147-46C9-8BF5-C51116856F62}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90F163C8-2147-46C9-8BF5-C51116856F62}.Release|Any CPU.Build.0 = Release|Any CPU + {90F163C8-2147-46C9-8BF5-C51116856F62}.Release|x86.ActiveCfg = Release|x86 + {90F163C8-2147-46C9-8BF5-C51116856F62}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Configuration/Configuration/App.config b/Configuration/Configuration/App.config new file mode 100644 index 0000000..fad249e --- /dev/null +++ b/Configuration/Configuration/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Configuration/Configuration/App.xaml b/Configuration/Configuration/App.xaml new file mode 100644 index 0000000..a07c142 --- /dev/null +++ b/Configuration/Configuration/App.xaml @@ -0,0 +1,42 @@ + + + + + + + + + diff --git a/Configuration/Configuration/App.xaml.cs b/Configuration/Configuration/App.xaml.cs new file mode 100644 index 0000000..ce657d8 --- /dev/null +++ b/Configuration/Configuration/App.xaml.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace Configuration +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + + } +} diff --git a/Configuration/Configuration/Assets/Icons/Add.png b/Configuration/Configuration/Assets/Icons/Add.png new file mode 100644 index 0000000..cf2e43e Binary files /dev/null and b/Configuration/Configuration/Assets/Icons/Add.png differ diff --git a/Configuration/Configuration/Assets/Icons/Delete.png b/Configuration/Configuration/Assets/Icons/Delete.png new file mode 100644 index 0000000..27a3623 Binary files /dev/null and b/Configuration/Configuration/Assets/Icons/Delete.png differ diff --git a/Configuration/Configuration/Builder.cs b/Configuration/Configuration/Builder.cs new file mode 100644 index 0000000..0684668 --- /dev/null +++ b/Configuration/Configuration/Builder.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Configuration.ViewModel; +using System.IO; +namespace Configuration +{ + public class Builder + { + public void LoadMain(ref MainVM main, ObservableCollectionlayouts, ObservableCollection collections) + { + //todo :make paths relative + ConfFileParser ini = new ConfFileParser(RetroFE.GetAbsolutePath() + "/Settings.conf"); + + main.IsFullscreen = ToBool(ini.GetSetting("fullscreen")); + main.IsHorizontalStretch = ToBool(ini.GetSetting("horizontal")); + main.IsVerticalStretch = ToBool(ini.GetSetting("vertical")); + if (!main.IsHorizontalStretch) + { + main.HorizontalResolution = Convert.ToInt32(ini.GetSetting("horizontal")); + } + if (!main.IsVerticalStretch) + { + main.VerticalResolution = Convert.ToInt32(ini.GetSetting("vertical")); + } + + main.Layout = layouts.FirstOrDefault(row => row == ini.GetSetting("layout")); + + main.IsMouseHidden = ToBool(ini.GetSetting("hideMouse")); + main.IsParenthesisVisible = !ToBool(ini.GetSetting("showParenthesis")); + main.IsBracesVisible = !ToBool(ini.GetSetting("showSquareBrackets")); + string firstCollection = ini.GetSetting("firstCollection"); + if(firstCollection == "") + { + firstCollection = "Main"; + } + main.FirstCollection = collections.FirstOrDefault(row => row.Name == firstCollection); + main.IsVideoEnabled = ToBool(ini.GetSetting("videoEnable")); + main.VideoLoop = Convert.ToInt32(ini.GetSetting("videoLoop")); + main.IsInfiniteLoop = (main.VideoLoop == 0); + main.IsExitOnFirstBack = ToBool(ini.GetSetting("exitOnFirstPageBack")); + main.AttractModeTime = Convert.ToInt32(ini.GetSetting("attractModeTime")); + main.IsAttractModeEnabled = (main.AttractModeTime != 0); + } + + public void LoadController(ref ControllerVM vm) + { + //todo :make paths relative + ConfFileParser ini = new ConfFileParser(RetroFE.GetAbsolutePath() + "/Controls.conf"); + vm.ScrollNext = ini.GetSetting("nextItem"); + vm.ScrollPrevious = ini.GetSetting("previousItem"); + vm.PageUp = ini.GetSetting("pageUp"); + vm.PageDown = ini.GetSetting("pageDown"); + vm.SelectItem = ini.GetSetting("select"); + vm.Back = ini.GetSetting("back"); + vm.Quit = ini.GetSetting("quit"); + } + + public ObservableCollection LoadLaunchers() + { + //todo :make paths relative + ObservableCollection launchers = new ObservableCollection(); + + string[] files = Directory.GetFiles(RetroFE.GetAbsolutePath() + "/Launchers", "*.conf"); + + foreach (string file in files) + { + LauncherVM vm = new LauncherVM(); + ConfFileParser ini = new ConfFileParser(file); + + vm.Name = System.IO.Path.GetFileNameWithoutExtension(file); + vm.ExecutablePath = ini.GetSetting("executable"); + vm.Arguments = ini.GetSetting("arguments"); + launchers.Add(vm); + } + + return launchers; + } + + public ObservableCollection LoadCollections(ObservableCollection launchers) + { + //todo :make paths relative + ObservableCollection collections = new ObservableCollection(); + + string[] dirs = Directory.GetDirectories(RetroFE.GetAbsolutePath() + "/Collections"); + + foreach (string dir in dirs) + { + string settingsFile = Path.Combine(dir, "Settings.conf"); + string menuFile = Path.Combine(dir, "Menu.xml"); + CollectionVM vm = new CollectionVM(); + ConfFileParser ini = new ConfFileParser(settingsFile); + MenuParser mp = new MenuParser(); + string launcher = ini.GetSetting("launcher"); + vm.Name = System.IO.Path.GetFileNameWithoutExtension(dir); + vm.Launcher = launchers.FirstOrDefault(row => row.Name == launcher); + vm.ListPath = ini.GetSetting("list.path"); + vm.Layout = ini.GetSetting("layout"); + + if (vm.Layout == "") + { + vm.IsDefaultLayout = true; + } + vm.FileExtensions = ini.GetSetting("list.extensions"); + vm.MediaPathVideo = ini.GetSetting("media.video"); + vm.MediaPathTitle = ini.GetSetting("media.title"); + vm.MediaPathLogo = ini.GetSetting("media.logo"); + vm.MediaPathTitle = ini.GetSetting("media.title"); + vm.MediaPathSnap = ini.GetSetting("media.snap"); + vm.MediaPathBox = ini.GetSetting("media.box"); + vm.MediaPathCart = ini.GetSetting("media.cart"); + + //todo: read submenus + + vm.Submenus = mp.ReadCollections(menuFile); + collections.Add(vm); + } + + return collections; + } + public ObservableCollection LoadLayouts() + { + //todo :make paths relative + ObservableCollection layouts = new ObservableCollection(); + + string[] dirs = Directory.GetDirectories(RetroFE.GetAbsolutePath() + "/Layouts"); + + foreach (string dir in dirs) + { + string layout = System.IO.Path.GetFileNameWithoutExtension(dir); + layouts.Add(layout); + } + + return layouts; + } + + private bool ToBool(string value) + { + value = value.Trim().ToLower(); + + return (value == "yes" || value == "true" || value == "stretch"); + } + } +} diff --git a/Configuration/Configuration/ConfFileParser.cs b/Configuration/Configuration/ConfFileParser.cs new file mode 100644 index 0000000..2f7e90d --- /dev/null +++ b/Configuration/Configuration/ConfFileParser.cs @@ -0,0 +1,146 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; + +public class ConfFileParser +{ + private Dictionary keyPairs = new Dictionary(); + private String FilePath; + + /// + /// Opens the INI file at the given path and enumerates the values in the IniParser. + /// + /// Full path to INI file. + public ConfFileParser(String filePath) + { + TextReader iniFile = null; + String strLine = null; + + FilePath = filePath; + + if (File.Exists(filePath)) + { + try + { + iniFile = new StreamReader(filePath); + + strLine = iniFile.ReadLine(); + + while (strLine != null) + { + strLine = strLine.Trim(); + + if (strLine != "") + { + int commentStart = strLine.IndexOf("#"); + if(commentStart > 0) + { + strLine = strLine.Substring(0, commentStart-1); + } + + string[] propertyPair = strLine.Split(new char[] { '=' }, 2); + + if (propertyPair.Length > 1) + { + string key = propertyPair[0].Trim(); + string value = propertyPair[1].Trim(); + keyPairs.Add(key, value); + } + } + + strLine = iniFile.ReadLine(); + } + + } + catch (Exception ex) + { + throw ex; + } + finally + { + if (iniFile != null) + iniFile.Close(); + } + } + else + throw new FileNotFoundException("Unable to locate " + filePath); + + } + + /// + /// Returns the value for the given section, key pair. + /// + /// Section name. + /// Key name. + public String GetSetting(String settingName) + { + if(keyPairs.ContainsKey(settingName)) + return (String)keyPairs[settingName]; + + return ""; + } + + /// + /// Adds or replaces a setting to the table to be saved. + /// + /// Section to add under. + /// Key name to add. + /// Value of key. + public void AddSetting(String settingName, String settingValue) + { + keyPairs[settingName] = settingValue; + } + + /// + /// Remove a setting. + /// + /// Section to add under. + /// Key name to add. + public void DeleteSetting(String settingName) + { + if (keyPairs.ContainsKey(settingName)) + keyPairs.Remove(settingName); + } + + /// + /// Save settings to new file. + /// + /// New file path. + public void SaveSettings(String newFilePath) + { + String tmpValue = ""; + String strToSave = ""; + + foreach (string property in keyPairs.Keys) + { + tmpValue = (String)keyPairs[property]; + + if (tmpValue != null) + tmpValue = "=" + tmpValue; + + strToSave += (property + tmpValue + "\r\n"); + } + + strToSave += "\r\n"; + + try + { + TextWriter tw = new StreamWriter(newFilePath); + tw.Write(strToSave); + tw.Close(); + } + catch (Exception ex) + { + throw ex; + } + } + + /// + /// Save settings back to ini file. + /// + public void SaveSettings() + { + SaveSettings(FilePath); + } +} \ No newline at end of file diff --git a/Configuration/Configuration/ConfFileSaver.cs b/Configuration/Configuration/ConfFileSaver.cs new file mode 100644 index 0000000..bf9fbbd --- /dev/null +++ b/Configuration/Configuration/ConfFileSaver.cs @@ -0,0 +1,58 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Configuration +{ + class ConfFileSaver + { + public void AddOption(string key, string value) + { + Options.Add(key, value); + } + + public void AddOption(string key, bool value) + { + string strValue = (value) ? "yes" : "no"; + Options.Add(key, strValue); + } + + + public void AddOption(string key, int value) + { + string strValue = Convert.ToString(value); + + Options.Add(key, strValue); + } + + public void Save(string filePath) + { + TextWriter iniFile = null; + + try + { + iniFile = new StreamWriter(filePath); + + foreach (KeyValuePair option in Options) + { + iniFile.Write(option.Key + " = " + option.Value + Environment.NewLine); + } + + } + catch (Exception ex) + { + throw ex; + } + finally + { + if (iniFile != null) + iniFile.Close(); + } + } + + private Dictionary Options = new Dictionary(); + } +} diff --git a/Configuration/Configuration/Configuration.csproj b/Configuration/Configuration/Configuration.csproj new file mode 100644 index 0000000..537d00a --- /dev/null +++ b/Configuration/Configuration/Configuration.csproj @@ -0,0 +1,182 @@ + + + + + Debug + AnyCPU + {90F163C8-2147-46C9-8BF5-C51116856F62} + WinExe + Properties + Configuration + Configuration + v4.5 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + ManagedMinimumRules.ruleset + true + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + ManagedMinimumRules.ruleset + true + + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + + + + + + + + + + + + + + + + + AddRemoveList.xaml + + + Collection.xaml + + + ControlInput.xaml + + + Launcher.xaml + + + MainSettings.xaml + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + MainWindow.xaml + Code + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Configuration/Configuration/Converter/CollectionExistsConverter.cs b/Configuration/Configuration/Converter/CollectionExistsConverter.cs new file mode 100644 index 0000000..a24f94f --- /dev/null +++ b/Configuration/Configuration/Converter/CollectionExistsConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Windows.Data; + +namespace Configuration.Converter +{ + public class CollectionExistsConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { +// if (targetType != typeof(bool)) +// throw new InvalidOperationException("The target is not a bool"); + return true; + // return !(bool)value; + } + + public object ConvertBack(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/Configuration/Configuration/Converter/InverseBooleanConverter.cs b/Configuration/Configuration/Converter/InverseBooleanConverter.cs new file mode 100644 index 0000000..67f6c23 --- /dev/null +++ b/Configuration/Configuration/Converter/InverseBooleanConverter.cs @@ -0,0 +1,24 @@ +using System; +using System.Windows.Data; + +namespace Configuration.Converter +{ + [ValueConversion(typeof(bool), typeof(bool))] + public class InverseBooleanConverter: IValueConverter + { + public object Convert(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { + if (targetType != typeof(bool)) + throw new InvalidOperationException("The target is not a bool"); + + return !(bool)value; + } + + public object ConvertBack(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/Configuration/Configuration/Converter/InverseBooleanToVisibilityConverter.cs b/Configuration/Configuration/Converter/InverseBooleanToVisibilityConverter.cs new file mode 100644 index 0000000..595cd59 --- /dev/null +++ b/Configuration/Configuration/Converter/InverseBooleanToVisibilityConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.Windows; +using System.Windows.Data; + +namespace Configuration.Converter +{ + public class InverseBooleanToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { + if (targetType != typeof(Visibility)) + throw new InvalidOperationException("The target is not a visibility type"); + + return (!(bool)value) ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { + throw new NotSupportedException(); + } + + } +} diff --git a/Configuration/Configuration/Converter/NullToVisibilityConverter.cs b/Configuration/Configuration/Converter/NullToVisibilityConverter.cs new file mode 100644 index 0000000..d255838 --- /dev/null +++ b/Configuration/Configuration/Converter/NullToVisibilityConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.Windows; +using System.Windows.Data; + +namespace Configuration.Converter +{ + public class NullToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { + if (targetType != typeof(Visibility)) + throw new InvalidOperationException("The target is not of type bool"); + + return ((object)value != null) ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, + System.Globalization.CultureInfo culture) + { + throw new NotSupportedException(); + } + + } +} diff --git a/Configuration/Configuration/MainWindow.xaml b/Configuration/Configuration/MainWindow.xaml new file mode 100644 index 0000000..8c04d08 --- /dev/null +++ b/Configuration/Configuration/MainWindow.xaml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Configuration/Configuration/MainWindow.xaml.cs b/Configuration/Configuration/MainWindow.xaml.cs new file mode 100644 index 0000000..4ed668c --- /dev/null +++ b/Configuration/Configuration/MainWindow.xaml.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Configuration.ViewModel; +namespace Configuration +{ + /// + /// Interaction logic for MainWindow.xaml + /// + /// + + public partial class MainWindow : Window + { + private TabItem LastSelectedTabItem; + public MainWindow() + { + + InitializeComponent(); + if (!File.Exists(RetroFE.GetAbsolutePath() + "/Core/RetroFE.exe")) + { + MessageBox.Show("Could not find RetroFE executable. Exiting."); + Close(); + } + else + { + MessageBox.Show("This tool has not had a lot of testing. " + Environment.NewLine + Environment.NewLine + "Back up your files and use at your own risk before using this tool."); + ObservableCollection layouts = new ObservableCollection(); + LauncherListVM launcher = this.TryFindResource("LauncherConfig") as LauncherListVM; + CollectionListVM collection = this.TryFindResource("CollectionConfig") as CollectionListVM; + ControllerVM controller = this.TryFindResource("ControllerConfig") as ControllerVM; + MainVM main = this.TryFindResource("MainConfig") as MainVM; + Builder b = new Builder(); + + launcher.LauncherCollection = b.LoadLaunchers(); + collection.CollectionList = b.LoadCollections(launcher.LauncherCollection); + main.Layouts = b.LoadLayouts(); + b.LoadMain(ref main, main.Layouts, collection.CollectionList); + b.LoadController(ref controller); + } + } + + private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + TabControl control = sender as TabControl; + + if (LastSelectedTabItem != null) + { + LastSelectedTabItem.Focus(); + Save((string)LastSelectedTabItem.Header); + } + + if (control != null && control.SelectedValue != null) + { + LastSelectedTabItem = control.SelectedItem as TabItem; + } + } + + private void TabControl_FocusableChanged(object sender, DependencyPropertyChangedEventArgs e) + { + TabControl control = sender as TabControl; + + if(control.SelectedItem != null) + { + TabItem item = control.SelectedItem as TabItem; + item.Focus(); + Save((string)item.Header); + } + } + + private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + if (ConfigurationTabControl.SelectedItem != null) + { + TabItem item = ConfigurationTabControl.SelectedItem as TabItem; + item.Focus(); + Save((string)item.Header); + } + + } + + private void Save(string tabItem) + { + if (tabItem == "General") + { + MainVM main = this.TryFindResource("MainConfig") as MainVM; + main.Save(); + } + else if (tabItem == "Controller") + { + ControllerVM vm = this.TryFindResource("ControllerConfig") as ControllerVM; + vm.Save(); + } + else if (tabItem == "Launchers") + { + LauncherListVM vm = this.TryFindResource("LauncherConfig") as LauncherListVM; + vm.Save(vm.SelectedLauncher); + } + else if (tabItem == "Collections") + { + CollectionListVM vm = this.TryFindResource("CollectionConfig") as CollectionListVM; + vm.Save(vm.SelectedCollection); + } + } + + } +} diff --git a/Configuration/Configuration/MenuParser.cs b/Configuration/Configuration/MenuParser.cs new file mode 100644 index 0000000..140608e --- /dev/null +++ b/Configuration/Configuration/MenuParser.cs @@ -0,0 +1,74 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.ObjectModel; +using System.Collections.Generic; +using System.Xml; + +public class MenuParser +{ + public ObservableCollection ReadCollections(string filePath) + { + + ObservableCollection list = new ObservableCollection(); + if (File.Exists(filePath)) + { + try + { + XmlReader reader = XmlReader.Create(filePath); + XmlDocument doc = new XmlDocument(); + reader.Read(); + doc.Load(reader); + + XmlNodeList items = doc.GetElementsByTagName("item"); + foreach (XmlNode item in items) + { + XmlAttribute name = item.Attributes["collection"]; + + if(name != null) + { + list.Add(name.Value); + } + } + } + catch (Exception ex) + { + throw ex; + } + } + + return list; + } + + /// + /// Save settings back to ini file. + /// + public void Save(ObservableCollection list, string filePath) + { + try + { + XmlDocument doc = new XmlDocument(); + XmlElement menu = doc.CreateElement("menu"); + + doc.AppendChild(menu); + + foreach (string item in list) + { + XmlElement node = doc.CreateElement("item"); + XmlAttribute attrib = doc.CreateAttribute("collection"); + attrib.Value = item; + menu.AppendChild(node); + node.AppendChild(attrib); + } + + doc.Save(filePath); + } + catch (Exception ex) + { + throw ex; + } + + +// SaveSettings(_FilePath); + } +} \ No newline at end of file diff --git a/Configuration/Configuration/Properties/AssemblyInfo.cs b/Configuration/Configuration/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c893c5f --- /dev/null +++ b/Configuration/Configuration/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Configuration")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Deere & Company")] +[assembly: AssemblyProduct("Configuration")] +[assembly: AssemblyCopyright("Copyright © Deere & Company 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Configuration/Configuration/Properties/Resources.Designer.cs b/Configuration/Configuration/Properties/Resources.Designer.cs new file mode 100644 index 0000000..744b8ff --- /dev/null +++ b/Configuration/Configuration/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Configuration.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Configuration.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Configuration/Configuration/Properties/Resources.resx b/Configuration/Configuration/Properties/Resources.resx new file mode 100644 index 0000000..ffecec8 --- /dev/null +++ b/Configuration/Configuration/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Configuration/Configuration/Properties/Settings.Designer.cs b/Configuration/Configuration/Properties/Settings.Designer.cs new file mode 100644 index 0000000..c17d0c2 --- /dev/null +++ b/Configuration/Configuration/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Configuration.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Configuration/Configuration/Properties/Settings.settings b/Configuration/Configuration/Properties/Settings.settings new file mode 100644 index 0000000..8f2fd95 --- /dev/null +++ b/Configuration/Configuration/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Configuration/Configuration/RelayCommand.cs b/Configuration/Configuration/RelayCommand.cs new file mode 100644 index 0000000..b85758b --- /dev/null +++ b/Configuration/Configuration/RelayCommand.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +namespace Configuration +{ + public class RelayCommand : ICommand + { + #region Fields + + readonly Action _execute; + readonly Predicate _canExecute; + + #endregion // Fields + + #region Constructors + + /// + /// Creates a new command that can always execute. + /// + /// The execution logic. + public RelayCommand(Action execute) + : this(execute, null) + { + } + + /// + /// Creates a new command. + /// + /// The execution logic. + /// The execution status logic. + public RelayCommand(Action execute, Predicate canExecute) + { + if (execute == null) + throw new ArgumentNullException("execute"); + + _execute = execute; + _canExecute = canExecute; + } + + #endregion // Constructors + + #region ICommand Members + + public bool CanExecute(object parameters) + { + return _canExecute == null ? true : _canExecute(parameters); + } + + public event EventHandler CanExecuteChanged + { + add { CommandManager.RequerySuggested += value; } + remove { CommandManager.RequerySuggested -= value; } + } + + public void Execute(object parameters) + { + _execute(parameters); + } + + #endregion // ICommand Members + } +} diff --git a/Configuration/Configuration/RetroFE.cs b/Configuration/Configuration/RetroFE.cs new file mode 100644 index 0000000..c84b041 --- /dev/null +++ b/Configuration/Configuration/RetroFE.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; + +namespace Configuration +{ + class RetroFE + { + public static string GetAbsolutePath() + { + string path = Environment.GetEnvironmentVariable("RETROFE_PATH"); + + if (path == null) + { + path = new FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location).Directory.FullName; + } + + return path; + } + } +} diff --git a/Configuration/Configuration/View/AddRemoveList.xaml b/Configuration/Configuration/View/AddRemoveList.xaml new file mode 100644 index 0000000..0dd0f88 --- /dev/null +++ b/Configuration/Configuration/View/AddRemoveList.xaml @@ -0,0 +1,75 @@ + + + /Assets/Icons/Add.png + /Assets/Icons/Delete.png + + + + + + + + + + + + + + + + + + + + + Name + + + + + + + + + + + + + + diff --git a/Configuration/Configuration/View/AddRemoveList.xaml.cs b/Configuration/Configuration/View/AddRemoveList.xaml.cs new file mode 100644 index 0000000..ddf2c89 --- /dev/null +++ b/Configuration/Configuration/View/AddRemoveList.xaml.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Configuration.ViewModel; + +namespace Configuration.View +{ + /// + /// Interaction logic for AddRemoveList.xaml + /// + public partial class AddRemoveList : UserControl + { + + public ICommand AddListItemCommand + { + get { return (ICommand)GetValue(AddListItemCommandProperty); } + set { SetValue(ListItemsSourceProperty, value); } + } + + public static DependencyProperty AddListItemCommandProperty = DependencyProperty.Register("AddListItemCommand", typeof(ICommand), typeof(AddRemoveList)); + + public ICommand RemoveListItemCommand + { + get { return (ICommand)GetValue(RemoveListItemCommandProperty); } + set { SetValue(ListItemsSourceProperty, value); } + } + + public static DependencyProperty RemoveListItemCommandProperty = DependencyProperty.Register("RemoveListItemCommand", typeof(ICommand), typeof(AddRemoveList)); + + public System.Collections.IEnumerable ListItemsSource + { + get { return (ObservableCollection)GetValue(ListItemsSourceProperty); } + set { SetValue(ListItemsSourceProperty, value); } + } + + public static DependencyProperty ListItemsSourceProperty = DependencyProperty.Register("ListItemsSource", typeof(System.Collections.IEnumerable), typeof(AddRemoveList)); + + + public object SelectedItem + { + get { return (object)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + + public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(AddRemoveList)); + + + public String ListDisplayMemberPath + { + get { return (String)GetValue(ListDisplayMemberPathProperty); } + set { SetValue(ListDisplayMemberPathProperty, value); } + } + + public static DependencyProperty ListDisplayMemberPathProperty = DependencyProperty.Register("ListDisplayMemberPath", typeof(String), typeof(AddRemoveList)); + + + public AddRemoveList() + { + InitializeComponent(); + } + + private void HideAddPopup(object sender, RoutedEventArgs e) + { + AddPopup.IsOpen = false; + // AddName.Text = ""; + } + } +} diff --git a/Configuration/Configuration/View/Collection.xaml b/Configuration/Configuration/View/Collection.xaml new file mode 100644 index 0000000..b38e71b --- /dev/null +++ b/Configuration/Configuration/View/Collection.xaml @@ -0,0 +1,161 @@ + + + + + + + /Assets/Icons/Add.png + /Assets/Icons/Delete.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Configuration/Configuration/View/Collection.xaml.cs b/Configuration/Configuration/View/Collection.xaml.cs new file mode 100644 index 0000000..e413fee --- /dev/null +++ b/Configuration/Configuration/View/Collection.xaml.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Configuration.ViewModel; + +namespace Configuration.View +{ + /// + /// Interaction logic for Collection.xaml + /// + public partial class Collection : UserControl + { + + public CollectionVM Data + { + get { return (CollectionVM)GetValue(DataProperty); } + set { SetValue(DataProperty, value); } + } + + public static DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(CollectionVM), typeof(Collection)); + + public System.Collections.IEnumerable LauncherCollection + { + get { return (System.Collections.IEnumerable)GetValue(LauncherCollectionProperty); } + set { SetValue(LauncherCollectionProperty, value); } + } + + public static DependencyProperty LauncherCollectionProperty = DependencyProperty.Register("LauncherCollection", typeof(System.Collections.IEnumerable), typeof(Collection)); + + public System.Collections.IEnumerable Layouts + { + get { return (System.Collections.IEnumerable)GetValue(LayoutsProperty); } + set { SetValue(LayoutsProperty, value); } + } + + public static DependencyProperty LayoutsProperty = DependencyProperty.Register("Layouts", typeof(System.Collections.IEnumerable), typeof(Collection)); + + + public System.Collections.IEnumerable Collections + { + get { return (System.Collections.IEnumerable)GetValue(CollectionsProperty); } + set { SetValue(CollectionsProperty, value); } + } + + public static DependencyProperty CollectionsProperty = DependencyProperty.Register("Collections", typeof(System.Collections.IEnumerable), typeof(Collection)); + + public Collection() + { + InitializeComponent(); + } + + } +} diff --git a/Configuration/Configuration/View/ControlInput.xaml b/Configuration/Configuration/View/ControlInput.xaml new file mode 100644 index 0000000..2b8f02a --- /dev/null +++ b/Configuration/Configuration/View/ControlInput.xaml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Configuration/Configuration/View/ControlInput.xaml.cs b/Configuration/Configuration/View/ControlInput.xaml.cs new file mode 100644 index 0000000..77057f3 --- /dev/null +++ b/Configuration/Configuration/View/ControlInput.xaml.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Configuration.ViewModel; + +namespace Configuration.View +{ + /// + /// Interaction logic for ControlInput.xaml + /// + public partial class ControlInput : UserControl + { + Dictionary SDLAsciiDescMap = new Dictionary(); + public ControlInput() + { + InitializeComponent(); + SDLAsciiDescMap[0x8] = "Backspace"; + SDLAsciiDescMap[0x9] = "Tab"; + SDLAsciiDescMap[0x0C] = "Clear"; + SDLAsciiDescMap[0x0D] = "Return"; + SDLAsciiDescMap[0x13] = "Pause"; + SDLAsciiDescMap[0x14] = "CapsLock"; + SDLAsciiDescMap[0x1B] = "Escape"; + SDLAsciiDescMap[0x20] = "Space"; + SDLAsciiDescMap[0x21] = "PageUp"; + SDLAsciiDescMap[0x22] = "PageDown"; + SDLAsciiDescMap[0x23] = "End"; + SDLAsciiDescMap[0x24] = "Home"; + SDLAsciiDescMap[0x25] = "Left"; + SDLAsciiDescMap[0x26] = "Up"; + SDLAsciiDescMap[0x27] = "Right"; + SDLAsciiDescMap[0x28] = "Down"; + SDLAsciiDescMap[0x29] = "Select"; + SDLAsciiDescMap[0x2B] = "Execute"; + SDLAsciiDescMap[0x2C] = "PrintScreen"; + SDLAsciiDescMap[0x2D] = "Insert"; + SDLAsciiDescMap[0x2E] = "Delete"; + SDLAsciiDescMap[0x2F] = "Help"; + SDLAsciiDescMap[0x30] = "0"; + SDLAsciiDescMap[0x31] = "1"; + SDLAsciiDescMap[0x32] = "2"; + SDLAsciiDescMap[0x33] = "3"; + SDLAsciiDescMap[0x34] = "4"; + SDLAsciiDescMap[0x35] = "5"; + SDLAsciiDescMap[0x36] = "6"; + SDLAsciiDescMap[0x37] = "7"; + SDLAsciiDescMap[0x38] = "8"; + SDLAsciiDescMap[0x39] = "9"; + SDLAsciiDescMap[0x41] = "A"; + SDLAsciiDescMap[0x42] = "B"; + SDLAsciiDescMap[0x43] = "C"; + SDLAsciiDescMap[0x44] = "D"; + SDLAsciiDescMap[0x45] = "E"; + SDLAsciiDescMap[0x46] = "F"; + SDLAsciiDescMap[0x47] = "G"; + SDLAsciiDescMap[0x48] = "H"; + SDLAsciiDescMap[0x49] = "I"; + SDLAsciiDescMap[0x4A] = "J"; + SDLAsciiDescMap[0x4B] = "K"; + SDLAsciiDescMap[0x4C] = "L"; + SDLAsciiDescMap[0x4D] = "M"; + SDLAsciiDescMap[0x4E] = "N"; + SDLAsciiDescMap[0x4F] = "O"; + SDLAsciiDescMap[0x50] = "P"; + SDLAsciiDescMap[0x51] = "Q"; + SDLAsciiDescMap[0x52] = "R"; + SDLAsciiDescMap[0x53] = "S"; + SDLAsciiDescMap[0x54] = "T"; + SDLAsciiDescMap[0x55] = "U"; + SDLAsciiDescMap[0x56] = "V"; + SDLAsciiDescMap[0x57] = "W"; + SDLAsciiDescMap[0x58] = "X"; + SDLAsciiDescMap[0x59] = "Y"; + SDLAsciiDescMap[0x5A] = "Z"; + SDLAsciiDescMap[0x5B] = "Left GUI"; + SDLAsciiDescMap[0x5C] = "Right GUI"; + SDLAsciiDescMap[0x5D] = "Application"; + SDLAsciiDescMap[0x5F] = "Sleep"; + SDLAsciiDescMap[0x60] = "Keypad 0"; + SDLAsciiDescMap[0x61] = "Keypad 1"; + SDLAsciiDescMap[0x62] = "Keypad 2"; + SDLAsciiDescMap[0x63] = "Keypad 3"; + SDLAsciiDescMap[0x64] = "Keypad 4"; + SDLAsciiDescMap[0x65] = "Keypad 5"; + SDLAsciiDescMap[0x66] = "Keypad 6"; + SDLAsciiDescMap[0x67] = "Keypad 7"; + SDLAsciiDescMap[0x68] = "Keypad 8"; + SDLAsciiDescMap[0x69] = "Keypad 9"; + SDLAsciiDescMap[0x6A] = "*"; + SDLAsciiDescMap[0x6B] = "+"; + SDLAsciiDescMap[0x6C] = "Separator"; + SDLAsciiDescMap[0x6D] = "-"; + SDLAsciiDescMap[0x6E] = "."; + SDLAsciiDescMap[0x6F] = "/"; + SDLAsciiDescMap[0x70] = "F1"; + SDLAsciiDescMap[0x71] = "F2"; + SDLAsciiDescMap[0x72] = "F3"; + SDLAsciiDescMap[0x73] = "F4"; + SDLAsciiDescMap[0x74] = "F5"; + SDLAsciiDescMap[0x75] = "F6"; + SDLAsciiDescMap[0x76] = "F7"; + SDLAsciiDescMap[0x77] = "F8"; + SDLAsciiDescMap[0x78] = "F9"; + SDLAsciiDescMap[0x79] = "F10"; + SDLAsciiDescMap[0x7A] = "F11"; + SDLAsciiDescMap[0x7B] = "F12"; + SDLAsciiDescMap[0x7C] = "F13"; + SDLAsciiDescMap[0x7D] = "F14"; + SDLAsciiDescMap[0x7E] = "F15"; + SDLAsciiDescMap[0x7F] = "F16"; + SDLAsciiDescMap[0x80] = "F17"; + SDLAsciiDescMap[0x81] = "F18"; + SDLAsciiDescMap[0x82] = "F19"; + SDLAsciiDescMap[0x83] = "F20"; + SDLAsciiDescMap[0x84] = "F21"; + SDLAsciiDescMap[0x85] = "F22"; + SDLAsciiDescMap[0x86] = "F23"; + SDLAsciiDescMap[0x87] = "F24"; + SDLAsciiDescMap[0x90] = "Numlock"; + SDLAsciiDescMap[0x91] = "ScrollLock"; + SDLAsciiDescMap[0xA0] = "Left Shift"; + SDLAsciiDescMap[0xA1] = "Right Shift"; + SDLAsciiDescMap[0xA2] = "Left Ctrl"; + SDLAsciiDescMap[0xA3] = "Right Ctrl"; + SDLAsciiDescMap[0xA4] = "Left Menu"; + SDLAsciiDescMap[0xA5] = "Right Menu"; + SDLAsciiDescMap[0xC0] = "`"; + + } + + public ControllerVM Data + { + get { return (ControllerVM)GetValue(DataProperty); } + set { SetValue(DataProperty, value); } + } + + public static DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(ControllerVM), typeof(ControlInput)); + + + private void TextBlock_PreviewKeyDown(object sender, KeyEventArgs e) + { + TextBox tb = sender as TextBox; + System.Windows.Forms.KeysConverter kc = new System.Windows.Forms.KeysConverter(); + int key = System.Windows.Input.KeyInterop.VirtualKeyFromKey(e.Key); + int systemKey = System.Windows.Input.KeyInterop.VirtualKeyFromKey(e.SystemKey); + + if (SDLAsciiDescMap.ContainsKey(key)) + { + tb.Text = SDLAsciiDescMap[key]; + } + else + if (SDLAsciiDescMap.ContainsKey(systemKey)) + { + tb.Text = SDLAsciiDescMap[systemKey]; + } + else + { + tb.Text = key + " " + e.SystemKey + " (none)"; + } + //todo, implement a map + + e.Handled = true; + } + } + +} diff --git a/Configuration/Configuration/View/Launcher.xaml b/Configuration/Configuration/View/Launcher.xaml new file mode 100644 index 0000000..3e51184 --- /dev/null +++ b/Configuration/Configuration/View/Launcher.xaml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/Configuration/Configuration/View/Launcher.xaml.cs b/Configuration/Configuration/View/Launcher.xaml.cs new file mode 100644 index 0000000..668771c --- /dev/null +++ b/Configuration/Configuration/View/Launcher.xaml.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Configuration.ViewModel; + +namespace Configuration.View +{ + /// + /// Interaction logic for Launcher.xaml + /// + public partial class Launcher : UserControl + { + public Launcher() + { + InitializeComponent(); + } + + + public LauncherVM Data + { + get { return (LauncherVM)GetValue(DataProperty); } + set { SetValue(DataProperty, value); } + } + + public static DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(LauncherVM), typeof(Launcher)); + + } +} diff --git a/Configuration/Configuration/View/MainSettings.xaml b/Configuration/Configuration/View/MainSettings.xaml new file mode 100644 index 0000000..2ccd2cb --- /dev/null +++ b/Configuration/Configuration/View/MainSettings.xaml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Configuration/Configuration/View/MainSettings.xaml.cs b/Configuration/Configuration/View/MainSettings.xaml.cs new file mode 100644 index 0000000..3ce7e4b --- /dev/null +++ b/Configuration/Configuration/View/MainSettings.xaml.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Configuration.ViewModel; + +namespace Configuration.View +{ + /// + /// Interaction logic for MainSettings.xaml + /// + public partial class MainSettings : UserControl + { + public MainVM Data + { + get { return (MainVM)GetValue(DataProperty); } + set { SetValue(DataProperty, value); } + } + + public static DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(MainVM), typeof(MainSettings)); + + public System.Collections.IEnumerable Launchers + { + get { return (System.Collections.IEnumerable)GetValue(LaunchersProperty); } + set { SetValue(LaunchersProperty, value); } + } + public static DependencyProperty LaunchersProperty = DependencyProperty.Register("Launchers", typeof(System.Collections.IEnumerable), typeof(MainSettings)); + + public System.Collections.IEnumerable Collections + { + get { return (System.Collections.IEnumerable)GetValue(CollectionsProperty); } + set { SetValue(CollectionsProperty, value); } + } + public static DependencyProperty CollectionsProperty = DependencyProperty.Register("Collections", typeof(System.Collections.IEnumerable), typeof(MainSettings)); + + + public MainSettings() + { + InitializeComponent(); + } + } +} diff --git a/Configuration/Configuration/ViewModel/CollectionListVM.cs b/Configuration/Configuration/ViewModel/CollectionListVM.cs new file mode 100644 index 0000000..41aabe1 --- /dev/null +++ b/Configuration/Configuration/ViewModel/CollectionListVM.cs @@ -0,0 +1,160 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using Configuration; + +namespace Configuration.ViewModel +{ + class CollectionListVM : INotifyPropertyChanged + { + ObservableCollection _CollectionList = new ObservableCollection(); + public ObservableCollection CollectionList + { + get { return _CollectionList; } + set { _CollectionList = value; NotifyPropertyChanged("CollectionList"); } + } + + CollectionVM _SelectedCollection = null; + public CollectionVM SelectedCollection + { + get { return _SelectedCollection; } + set { + if (_SelectedCollection != null) + { + Save(_SelectedCollection); + } + _SelectedCollection = value; + NotifyPropertyChanged("SelectedCollection"); + } + } + + ICommand _AddListItemCommand; + public ICommand AddListItemCommand + { + get + { + if (_AddListItemCommand == null) + { + _AddListItemCommand = new RelayCommand(param => this.AddCollection(param), param => this.CanAdd()); + } + + return _AddListItemCommand; + } + } + ICommand _RemoveListItemCommand; + public ICommand RemoveListItemCommand + { + get + { + if (_RemoveListItemCommand == null) + { + _RemoveListItemCommand = new RelayCommand(param => this.RemoveCollection(), param => this.CanDelete()); + } + + return _RemoveListItemCommand; + } + } + + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + + private bool CanAdd() + { + return true; + } + + private bool CanDelete() + { + return (SelectedCollection != null); + } + + private void AddCollection(object param) + { + + CollectionVM cvm = new CollectionVM(); + cvm.Name = param as String; + NotifyPropertyChanged("CollectionList"); + + ConfFileSaver settings = new ConfFileSaver(); + ConfFileSaver include = new ConfFileSaver(); + ConfFileSaver exclude = new ConfFileSaver(); + MenuParser menu = new MenuParser(); + + //todo change path + string path = RetroFE.GetAbsolutePath() + "/Collections/" + cvm.Name; + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + if (!File.Exists(path + "/Settings.conf")) + { + CollectionList.Add(cvm); + settings.Save(path + "/Settings.conf"); + + if (!File.Exists(path + "/Include.txt")) + { + include.Save(path + "/Include.txt"); + } + if (!File.Exists(path + "/Exclude.txt")) + { + exclude.Save(path + "/Exclude.txt"); + } + + //menu.Save(path + "/Menu.xml"); + } + } + + public void Save(CollectionVM cvm) + { + if (cvm == null) return; + + ConfFileSaver s = new ConfFileSaver(); + + if (!cvm.IsDefaultLayout) + { + s.AddOption("layout", cvm.Layout); + } + s.AddOption("launcher", (cvm.Launcher == null) ? "" : cvm.Launcher.Name); + s.AddOption("list.path", cvm.ListPath); + s.AddOption("list.extensions", cvm.FileExtensions); + s.AddOption("media.box", cvm.MediaPathBox); + s.AddOption("media.cart", cvm.MediaPathCart); + s.AddOption("media.logo", cvm.MediaPathLogo); + s.AddOption("media.snap", cvm.MediaPathSnap); + s.AddOption("media.title", cvm.MediaPathTitle); + s.AddOption("media.video", cvm.MediaPathVideo); + + //todo: change serverPath + string path = RetroFE.GetAbsolutePath() + "/Collections/" + cvm.Name + "/Settings.conf"; + s.Save(path); + } + + private bool RemoveCollection() + { + //todo: change location + string path = RetroFE.GetAbsolutePath() + "/Launchers/" + SelectedCollection.Name + ".conf"; + if (File.Exists(path)) + { + File.Delete(path); + } + + CollectionList.Remove(SelectedCollection); + + return true; + } + } +} diff --git a/Configuration/Configuration/ViewModel/CollectionVM.cs b/Configuration/Configuration/ViewModel/CollectionVM.cs new file mode 100644 index 0000000..fcbdd14 --- /dev/null +++ b/Configuration/Configuration/ViewModel/CollectionVM.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using System.Windows.Forms; +using Configuration; + +namespace Configuration.ViewModel +{ + public class CollectionVM : INotifyPropertyChanged + { + String _Name; + public String Name + { + get { return _Name; } + set { _Name = value; NotifyPropertyChanged("Name"); } + } + + String _ListPath; + public String ListPath + { + get { return _ListPath; } + set { _ListPath = value; NotifyPropertyChanged("ListPath"); } + } + + String _FileExtensions = null; + public String FileExtensions + { + get { return _FileExtensions; } + set { _FileExtensions = value; NotifyPropertyChanged("FileExtensions"); } + } + + LauncherVM _Launcher = null; + public LauncherVM Launcher + { + get { return _Launcher; } + set { _Launcher = value; NotifyPropertyChanged("Launcher"); } + } + + String _Layout = null; + public String Layout + { + get { return _Layout; } + set { _Layout = value; NotifyPropertyChanged("Layout"); } + } + + bool _IsDefaultLayout; + public bool IsDefaultLayout + { + get { return _IsDefaultLayout; } + set { _IsDefaultLayout = value; NotifyPropertyChanged("IsDefaultLayout"); } + } + + + String _MediaPathVideo; + public String MediaPathVideo + { + get { return _MediaPathVideo; } + set { _MediaPathVideo = value; NotifyPropertyChanged("MediaPathVideo"); } + } + + String _MediaPathTitle; + public String MediaPathTitle + { + get { return _MediaPathTitle; } + set { _MediaPathTitle = value; NotifyPropertyChanged("MediaPathTitle"); } + } + String _MediaPathLogo; + public String MediaPathLogo + { + get { return _MediaPathLogo; } + set { _MediaPathLogo = value; NotifyPropertyChanged("MediaPathLogo"); } + } + String _MediaPathBox; + public String MediaPathBox + { + get { return _MediaPathBox; } + set { _MediaPathBox = value; NotifyPropertyChanged("MediaPathBox"); } + } + String _MediaPathCart; + public String MediaPathCart + { + get { return _MediaPathCart; } + set { _MediaPathCart = value; NotifyPropertyChanged("MediaPathCart"); } + } + String _MediaPathSnap; + public String MediaPathSnap + { + get { return _MediaPathSnap; } + set { _MediaPathSnap = value; NotifyPropertyChanged("MediaPathSnap"); } + } + + ObservableCollection _Submenus; + public ObservableCollection Submenus + { + get { return _Submenus; } + set { _Submenus = value; NotifyPropertyChanged("Submenus"); } + } + + ICommand _DeleteSubmenuCommand; + public ICommand DeleteSubmenuCommand + { + get + { + if (_DeleteSubmenuCommand == null) + { + _DeleteSubmenuCommand = new RelayCommand(param => this.DeleteSubmenu((string)param), param => true); + } + + return _DeleteSubmenuCommand; + } + } + + + + ICommand _BrowseFolderCommand; + public ICommand BrowseFolderCommand + { + get + { + if (_BrowseFolderCommand == null) + { + _BrowseFolderCommand = new RelayCommand(param => this.BrowseFolder((string)param), param => true); + } + + return _BrowseFolderCommand; + } + } + + public void DeleteSubmenu(string reserved) + { + } + + public void BrowseFolder(string type) + { + FolderBrowserDialog dialog = new FolderBrowserDialog(); + + if(dialog.ShowDialog() == DialogResult.OK) + { + string selectedPath = dialog.SelectedPath; + + if (type == "Video") + { + MediaPathVideo = selectedPath; + } + else if (type == "Title") + { + MediaPathTitle = selectedPath; + } + else if (type == "Snap") + { + MediaPathSnap = selectedPath; + } + else if (type == "Logo") + { + MediaPathLogo = selectedPath; + } + else if (type == "Cart") + { + MediaPathCart = selectedPath; + } + else if (type == "Box") + { + MediaPathBox = selectedPath; + } + else if (type == "Item") + { + ListPath = selectedPath; + } + } + } + + + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + } +} diff --git a/Configuration/Configuration/ViewModel/ControllerVM.cs b/Configuration/Configuration/ViewModel/ControllerVM.cs new file mode 100644 index 0000000..5782612 --- /dev/null +++ b/Configuration/Configuration/ViewModel/ControllerVM.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using System.Windows.Forms; +using Configuration; + +namespace Configuration.ViewModel +{ + public class ControllerVM : INotifyPropertyChanged + { + String _ScrollPrevious; + public String ScrollPrevious + { + get { return _ScrollPrevious; } + set { _ScrollPrevious = value; NotifyPropertyChanged("ScrollPrevious"); } + } + + String _ScrollNext; + public String ScrollNext + { + get { return _ScrollNext; } + set { _ScrollNext = value; NotifyPropertyChanged("ScrollNext"); } + } + + String _PageUp; + public String PageUp + { + get { return _PageUp; } + set { _PageUp = value; NotifyPropertyChanged("PageUp"); } + } + + String _PageDown; + public String PageDown + { + get { return _PageDown; } + set { _PageDown = value; NotifyPropertyChanged("PageDown"); } + } + + String _SelectItem; + public String SelectItem + { + get { return _SelectItem; } + set { _SelectItem = value; NotifyPropertyChanged("SelectItem"); } + } + + String _Back; + public String Back + { + get { return _Back; } + set { _Back = value; NotifyPropertyChanged("Back"); } + } + + String _Quit; + public String Quit + { + get { return _Quit; } + set { _Quit = value; NotifyPropertyChanged("Quit"); } + } + + public void Save() + { + ConfFileSaver s = new ConfFileSaver(); + + s.AddOption("previousItem", ScrollPrevious); + s.AddOption("nextItem", ScrollNext); + s.AddOption("pageUp", PageUp); + s.AddOption("pageDown", PageDown); + + s.AddOption("select", SelectItem); + s.AddOption("back", Back); + s.AddOption("quit", Quit); + + //todo: change location + string path = RetroFE.GetAbsolutePath() + "/Controls.conf"; + s.Save(path); + } + + + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + } +} diff --git a/Configuration/Configuration/ViewModel/LauncherListVM.cs b/Configuration/Configuration/ViewModel/LauncherListVM.cs new file mode 100644 index 0000000..a6f2bb2 --- /dev/null +++ b/Configuration/Configuration/ViewModel/LauncherListVM.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using System.IO; +using Configuration; + +namespace Configuration.ViewModel +{ + class LauncherListVM : INotifyPropertyChanged + { + ObservableCollection _LauncherCollection = new ObservableCollection(); + public ObservableCollection LauncherCollection + { + get { return _LauncherCollection; } + set { _LauncherCollection = value; NotifyPropertyChanged("LauncherCollection"); } + } + + LauncherVM _SelectedLauncher = null; + public LauncherVM SelectedLauncher + { + get { return _SelectedLauncher; } + set + { + if (_SelectedLauncher != null) + { + Save(_SelectedLauncher); + } + _SelectedLauncher = value; + NotifyPropertyChanged("SelectedLauncher"); + } + } + + ICommand _AddListItemCommand; + public ICommand AddListItemCommand + { + get + { + if (_AddListItemCommand == null) + { + _AddListItemCommand = new RelayCommand(param => this.AddLauncher(param), param => this.CanAdd()); + } + + return _AddListItemCommand; + } + } + ICommand _RemoveListItemCommand; + public ICommand RemoveListItemCommand + { + get + { + if (_RemoveListItemCommand == null) + { + _RemoveListItemCommand = new RelayCommand(param => this.RemoveLauncher(), param => this.CanDelete()); + } + + return _RemoveListItemCommand; + } + } + + + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + + private bool CanAdd() + { + return true; + } + + private bool CanDelete() + { + return (SelectedLauncher != null); + } + + private void AddLauncher(object param) + { + + LauncherVM l = new LauncherVM(); + l.Name = param as String; + NotifyPropertyChanged("LauncherCollection"); + ConfFileSaver saver = new ConfFileSaver(); + + //todo change path + if (!File.Exists(RetroFE.GetAbsolutePath() + "/Launchers/" + l.Name + ".conf")) + { + LauncherCollection.Add(l); + saver.Save(RetroFE.GetAbsolutePath() + "/Launchers/" + l.Name + ".conf"); + } + } + + public void Save(LauncherVM launcher) + { + if (launcher == null) return; + + ConfFileSaver s = new ConfFileSaver(); + s.AddOption("executable", launcher.ExecutablePath); + s.AddOption("arguments", launcher.Arguments); + + //todo: change location + string path = RetroFE.GetAbsolutePath() + "/Launchers/" + SelectedLauncher.Name + ".conf"; + s.Save(path); + } + + private bool RemoveLauncher() + { + //todo: change location + string path = RetroFE.GetAbsolutePath() + "/Launchers/" + SelectedLauncher.Name + ".conf"; + if (File.Exists(path)) + { + File.Delete(path); + } + + LauncherCollection.Remove(SelectedLauncher); + + return true; + } + } +} diff --git a/Configuration/Configuration/ViewModel/LauncherVM.cs b/Configuration/Configuration/ViewModel/LauncherVM.cs new file mode 100644 index 0000000..1e85f44 --- /dev/null +++ b/Configuration/Configuration/ViewModel/LauncherVM.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using System.Windows.Forms; +using Configuration; + +namespace Configuration.ViewModel +{ + public class LauncherVM : INotifyPropertyChanged + { + String _Name; + public String Name + { + get { return _Name; } + set { _Name = value; NotifyPropertyChanged("Name"); } + } + + String _ExecutablePath; + public String ExecutablePath + { + get { return _ExecutablePath; } + set { _ExecutablePath = value; NotifyPropertyChanged("ExecutablePath"); } + } + + String _Arguments; + public String Arguments + { + get { return _Arguments; } + set { _Arguments = value; NotifyPropertyChanged("Arguments"); } + } + + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + ICommand _BrowseFileCommand; + public ICommand BrowseFileCommand + { + get + { + if (_BrowseFileCommand == null) + { + _BrowseFileCommand = new RelayCommand(param => this.BrowseFile(), param => true); + } + + return _BrowseFileCommand; + } + } + + + public void BrowseFile() + { + OpenFileDialog dialog = new OpenFileDialog(); + dialog.Multiselect = false; + + if (dialog.ShowDialog() == DialogResult.OK) + { + ExecutablePath = dialog.FileName; + } + } + + } +} diff --git a/Configuration/Configuration/ViewModel/MainVM.cs b/Configuration/Configuration/ViewModel/MainVM.cs new file mode 100644 index 0000000..a6f77b7 --- /dev/null +++ b/Configuration/Configuration/ViewModel/MainVM.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using Configuration; + +namespace Configuration.ViewModel +{ + public class MainVM : INotifyPropertyChanged + { + bool _IsFullscreen; + public bool IsFullscreen + { + get { return _IsFullscreen; } + set { _IsFullscreen = value; NotifyPropertyChanged("IsFullscreen"); } + } + + int _HorizontalResolution; + public int HorizontalResolution + { + get { return _HorizontalResolution; } + set { _HorizontalResolution = value; NotifyPropertyChanged("HorizontalResolution"); } + } + + bool _IsHorizontalStretch; + public bool IsHorizontalStretch + { + get { return _IsHorizontalStretch; } + set { _IsHorizontalStretch = value; NotifyPropertyChanged("IsHorizontalStretch"); } + } + + bool _IsVerticalStretch; + public bool IsVerticalStretch + { + get { return _IsVerticalStretch; } + set { _IsVerticalStretch = value; NotifyPropertyChanged("IsVerticalStretch"); } + } + + int _VerticalResolution; + public int VerticalResolution + { + get { return _VerticalResolution; } + set { _VerticalResolution = value; NotifyPropertyChanged("VerticalResolution"); } + } + + String _Layout; + public String Layout + { + get { return _Layout; } + set { _Layout = value; NotifyPropertyChanged("Layout"); } + } + + ObservableCollection _Layouts; + public ObservableCollection Layouts + { + get { return _Layouts; } + set { _Layouts = value; NotifyPropertyChanged("Layouts"); } + } + + + bool _IsMouseHidden; + public bool IsMouseHidden + { + get { return _IsMouseHidden; } + set { _IsMouseHidden = value; NotifyPropertyChanged("IsMouseHidden"); } + } + + bool _IsParenthesisVisible; + public bool IsParenthesisVisible + { + get { return _IsParenthesisVisible; } + set { _IsParenthesisVisible = value; NotifyPropertyChanged("IsParenthesisVisible"); } + } + + bool _IsBracesVisible; + public bool IsBracesVisible + { + get { return _IsBracesVisible; } + set { _IsBracesVisible = value; NotifyPropertyChanged("IsBracesVisible"); } + } + + CollectionVM _FirstCollection; + public CollectionVM FirstCollection + { + get { return _FirstCollection; } + set { _FirstCollection = value; NotifyPropertyChanged("FirstCollection"); } + } + + bool _IsVideoEnabled; + public bool IsVideoEnabled + { + get { return _IsVideoEnabled; } + set { _IsVideoEnabled = value; NotifyPropertyChanged("IsVideoEnabled"); } + } + + int _VideoLoop; + public int VideoLoop + { + get { return _VideoLoop; } + set { _VideoLoop = value; NotifyPropertyChanged("VideoLoop"); } + } + + bool _IsInfiniteLoop; + public bool IsInfiniteLoop + { + get { return _IsInfiniteLoop; } + set { _IsInfiniteLoop = value; NotifyPropertyChanged("IsInfiniteLoop"); } + } + + bool _IsExitOnFirstBack; + public bool IsExitOnFirstBack + { + get { return _IsExitOnFirstBack; } + set { _IsExitOnFirstBack = value; NotifyPropertyChanged("IsExitOnFirstBack"); } + } + + int _AttractModeTime; + public int AttractModeTime + { + get { return _AttractModeTime; } + set { _AttractModeTime = value; NotifyPropertyChanged("AttractModeTime"); } + } + + bool _IsAttractModeEnabled; + public bool IsAttractModeEnabled + { + get { return _IsAttractModeEnabled; } + set { _IsAttractModeEnabled = value; NotifyPropertyChanged("IsAttractModeEnabled"); } + } + + + public event PropertyChangedEventHandler PropertyChanged; + private void NotifyPropertyChanged(String propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public void Save() + { + ConfFileSaver s = new ConfFileSaver(); + + if(IsVerticalStretch) + { + s.AddOption("vertical", "stretch"); + } + else + { + s.AddOption("vertical", VerticalResolution); + } + + if(IsHorizontalStretch) + { + s.AddOption("horizontal", "stretch"); + } + else + { + s.AddOption("horizontal", HorizontalResolution); + } + + s.AddOption("fullscreen", IsFullscreen); + s.AddOption("layout", (Layout == null) ? "Default" : Layout); + s.AddOption("hideMouse", IsMouseHidden); + s.AddOption("showParenthesis", IsParenthesisVisible); + s.AddOption("showSquareBrackets", IsBracesVisible); + s.AddOption("firstCollection", (FirstCollection == null) ? "Main" : FirstCollection.Name); + + s.AddOption("videoEnable", IsVideoEnabled); + s.AddOption("videoLoop", VideoLoop); + s.AddOption("exitOnFirstPageBack", IsExitOnFirstBack); + s.AddOption("attractModeTime", (IsAttractModeEnabled) ? AttractModeTime : 0); + + + //todo: change location + string path = RetroFE.GetAbsolutePath() + "/Settings.conf"; + s.Save(path); + } + + } +} diff --git a/Documentation/Manual/Configuration.rst b/Documentation/Manual/Configuration.rst new file mode 100644 index 0000000..351805c --- /dev/null +++ b/Documentation/Manual/Configuration.rst @@ -0,0 +1,478 @@ +.. _Configuration: + +================================== +Configuration +================================== + +RetroFE splits up configuration files to optimize flexability and portability. The configuration is broken up into the following categories: + +=========================== ================================================================================================================================================================== +Configuration Role +=========================== ================================================================================================================================================================== +Main Settings Defines screen resolution, controls, etc. +Launchers Defines what executables to use for launching menu items (emulators, apps, etc.) +Collections Defines directories to scan for populating lists, media (image and video) paths, and additional information for an item (i.e controls, instructions, histrory) +Main Menu Defines the list of collections to pick from on the main page. +=========================== ================================================================================================================================================================== + +Main Configuration +################################################ + +**/Settings.conf** + +See below for a list of supported properties. + +================================== ======================================================================================================== +Property Description +================================== ======================================================================================================== +horizontal Horizontal screen width (in pixels) +vertical Vertical screen width (in pixels) +fullscreen Display in fullscreen or windowed mode (yes/no) +layout Name of the default layout to use (unless overridden in the themes) +exitOnFirstPageBack Exit the frontend when the back button is pressed on the first page +attractModeTime Number of seconds while idleing to wait before entering attract mode (0 to disable) +showParenthesis Set to no if you want to hide parenthesis (and anything inside) for menu lists +showSquareBrackets Set to no if you want to hide braces (and anything inside) for menu lists +showVideo Set to no if you want to not load video (for slower systems) +videoLoop Number of times to loop video playback (enter 0 to continuously loop) +firstCollection Defines the first collection to load. If not specified, the "Main" collection will be used. +controls.previousItem The key to press to scroll to the previous item in a list +controls.nextItem The key to press to scroll to the next item in a list +controls.pageUp The key to press to scroll page up in a list +controls.pageDown The key to press to scroll page down in a list +controls.select The key to press to select (or launch) the selected list item +controls.back The key to press to return to the previous menu +controls.quit The key to press to quit the frontend +================================== ======================================================================================================== + +Basic example (640x480 fullscreen with controls configured): + +.. code-block:: javascript + + horizontal = 640 + vertical = 480 + fullscreen = yes + + controls.previousItem = Up + controls.nextItem = Down + controls.pageUp = Left + controls.pageDown = Right + controls.select = Space + controls.back = Escape + controls.quit = q + +See :ref:`ControlKeycodes` for a list of valid key codes + +.. _ConfigurationLaunchers: + + +Launchers +################################################ + +**/Launchers/.conf** + +*(where is the name of the launcher)* + +A launcher is a program (i.e. emulator, application, or game) which gets executed when a menu item is selected. Parameters can also be passed +into a launcher. + +See below for a list of supported properties. + +=========================== ================================================================== +Property Description +=========================== ================================================================== +executable Path of where the executable exists +arguments Arguments to pass when executing the launcher (i.e. ROM name) +=========================== ================================================================== + +See below for a basic launcher for the Nestopia emulator (/Launchers/nestopia.conf) + +.. code-block:: javascript + + executable = D:/Emulators/Nestopia/nestopia.exe + arguments = "%ITEM_FILEPATH%" + +%ITEM_FILEPATH% is a reserved variable name. See the variables table below for other variables that may be used. +Also note the quotes around "%ITEM_FILEPATH%" to help not confuse the executable from thinking that an item with spaces as multiple arguments. + +Assuming that "Super Mario Bros" was the selected item, the frontend will attempt to execute: + +.. code-block:: javascript + + "D:/Emulators/Nestopia/nestopia.exe" "D:/ROMs/Nintendo/Super Mario Bros.nes". + + You can also use relative paths (relative to the root folder of RetroFE) +.. code-block:: javascript + + executable = ../Emulators/Nestopia/nestopia.exe + arguments = "%ITEM_FILEPATH%" + + + +Variables +----------- +=========================== =========================== =============================================== +Variable Description Translated Example +=========================== =========================== =============================================== +%ITEM_FILEPATH% Full item path D:/ROMs/Nintendo/Super Mario Bros.nes +%ITEM_NAME% The item name Super Mario Bros +%ITEM_FILENAME% Filename without path Super Mario Bros.nes +%ITEM_DIRECTORY% Folder where file exists D:/ROMs/Nintendo +%ITEM_COLLECTION_NAME% Name of collection for item Nintendo Entertainment System +%RETROFE_PATH% Folder location of Frontend D:/Frontends/RetroFE +%RETROFE_EXEC_PATH% Location of RetroFE D:/Frontends/RetroFE/RetroFE.exe +=========================== =========================== =============================================== + +More elaborate example: + +.. code-block:: javascript + + # Have fceux load a save state automatically for the ROM when started + executable = D:/Emulators/fceux/fceux.exe + arguments = "%ITEM_FILEPATH%" -loadstate "%ITEM_DIRECTORY%/%ITEM_NAME%.fcs" + +.. _ConfigurationCollections: + +Collections +################################################ + +**/Collections//** + +A collection is a list of items to display on a menu. A collection can be built by scanning a list of files in a folder. Each collection configuration is broken up into three separate +configuration files (for portability). + + +================================== ================================================================================================================== +Configuration File Description +================================== ================================================================================================================== +Settings.conf Defines which launcher to use, item (ROM) folders, extensions, media paths, layout/theme, etc... +Mamelist.xml If this is a mame collection, place your mamelist.xml file in this folder. +Include.txt List the filenames (without the extension) to show up in your list. If empty, all files will be shown in the list. +Include.xml HyperSpin HyperList XML file to show up in your list. Ignored if Include.txt exists. +Exclude.txt List the filenames (without the extension) to hide from being shown up in your list +================================== ================================================================================================================== + +General Settings +---------------------- +**/Collections//Settings.conf** + +================================== ================================================================================================================================ +Property Description +================================== ================================================================================================================================ +launcher Launcher to use when item is selected (will look up /Launchers/.conf +layout The name of the layout to load for the collection (will read layout from Layouts/ +path Location of where files to launch exist +extensions Adds only files with the given extension to a list (comma separated) +snap Snapshot image folder +title Title screen image folder +video Video folder +box Box artwork folder +================================== ================================================================================================================================ + +The following example will use the launcher configuration from "/Launchers/nestopia.conf" and will use the layout in "Layouts/Nintendo Entertainment System" + +.. code-block:: javascript + + launcher = nestopia + layout = Nintendo Entertainment System + path = D:/ROMs/Nintendo Entertainment System + extensions = nes,zip + snap = D:/Media/Nintendo Entertainment System/Snaps + title = D:/Media/Nintendo Entertainment System/Titles + video = D:/Media/Nintendo Entertainment System/Videos + box = D:/Media/Nintendo Entertainment System/Box + + +Showing and Hiding Collection Items +------------------------------------------ +**/Collections//Include.txt** and **/Collections//Exclude.txt** + + +By default, RetroFE will show all items scanned in your folder path (assuming the extension matches). If an Include.txt file exists (and Include.txt is not empty), only the +items in that file will show up in the menu (assuming the file exists). + +If an Exclude.xml file exists, the file will always be hidden from the list, regardless if the file item is specified in Include.txt. + +All items listed in Include.txt and Exclude.txt are the name of the file (without the file extension). + +Example Include.txt file: + +.. code-block:: javascript + + Super Mario Bros (USA) + Contra (USA) + +Example Exclude.txt file: + +.. code-block:: javascript + + E.T. (USA) + Bayou Billy (USA) + + +.. _ConfigurationMenu: + +Main Menu +################################################ +**/Collections/Main/Menu.xml** + +This file defines what menu items are displayed on the first page. See below for a basic example: + +.. code-block:: xml + + + + + + +Note that for each item specified, one with an identical name (case sensitive) must exist in your collections folder. For the example above, the collection configuration in +/Collections/Nintendo Entertainment System/ and /Collections/Arcade/ must exist. + +.. _ControlKeycodes: + +Valid Key Codes +################ + +These codes were taken from https://wiki.libsdl.org/SDL_Keycode + +See below for a list of key codes that can be used for configuring the controls: + +===================== ================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================ +Code Notes +===================== ================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================ +"0" +"1" +"2" +"3" +"4" +"5" +"6" +"7" +"8" +"9" +"A" +"AC Back" the Back key (application control keypad) +"AC Bookmarks" the Bookmarks key (application control keypad) +"AC Forward" the Forward key (application control keypad) +"AC Home" the Home key (application control keypad) +"AC Refresh" the Refresh key (application control keypad) +"AC Search" the Search key (application control keypad) +"AC Stop" the Stop key (application control keypad) +"Again" the Again key (Redo) +"AltErase" Erase-Eaze +"'" +"Application" the Application / Compose / Context Menu (Windows) key +"AudioMute" the Mute volume key +"AudioNext" the Next Track media key +"AudioPlay" the Play media key +"AudioPrev" the Previous Track media key +"AudioStop" the Stop media key) +"B" +"\" Located at the lower left of the return key on ISO keyboards and at the right end of the QWERTY row on ANSI keyboards. Produces REVERSE SOLIDUS (backslash) and VERTICAL LINE in a US layout, REVERSE SOLIDUS and VERTICAL LINE in a UK Mac layout, NUMBER SIGN and TILDE in a UK Windows layout, DOLLAR SIGN and POUND SIGN in a Swiss German layout, NUMBER SIGN and APOSTROPHE in a German layout, GRAVE ACCENT and POUND SIGN in a French Mac layout, and ASTERISK and MICRO SIGN in a French Windows layout. +"Backspace" +"BrightnessDown" the Brightness Down key +"BrightnessUp" the Brightness Up key +"C" +"Calculator" the Calculator key +"Cancel" +"CapsLock" +"Clear" +"Clear / Again" +"," +"Computer" the My Computer key +"Copy" +"CrSel" +"CurrencySubUnit" the Currency Subunit key +"CurrencyUnit" the Currency Unit key +"Cut" +"D" +"DecimalSeparator" the Decimal Separator key +"Delete" +"DisplaySwitch" display mirroring/dual display switch, video mode switch +"Down" the Down arrow key (navigation keypad) +"E" +"Eject" the Eject key) +"End" +"=" +"Escape" the Esc key) +"Execute" +"ExSel" +"F" +"F1" +"F10" +"F11" +"F12" +"F13" +"F14" +"F15" +"F16" +"F17" +"F18" +"F19" +"F2" +"F20" +"F21" +"F22" +"F23" +"F24" +"F3" +"F4" +"F5" +"F6" +"F7" +"F8" +"F9" +"Find" +"G" +"`" Located in the top left corner (on both ANSI and ISO keyboards). Produces GRAVE ACCENT and TILDE in a US Windows layout and in US and UK Mac layouts on ANSI keyboards, GRAVE ACCENT and NOT SIGN in a UK Windows layout, SECTION SIGN and PLUS-MINUS SIGN in US and UK Mac layouts on ISO keyboards, SECTION SIGN and DEGREE SIGN in a Swiss German layout (Mac: only on ISO keyboards), CIRCUMFLEX ACCENT and DEGREE SIGN in a German layout (Mac: only on ISO keyboards), SUPERSCRIPT TWO and TILDE in a French Windows layout, COMMERCIAL AT and NUMBER SIGN in a French Mac layout on ISO keyboards, and LESS-THAN SIGN and GREATER-THAN SIGN in a Swiss German, German, or French Mac layout on ANSI keyboards. +"H" +"Help" +"Home" +"I" +"Insert" insert on PC, help on some Mac keyboards (but does send code 73, not 117) +"J" +"K" +"KBDIllumDown" the Keyboard Illumination Down key +"KBDIllumToggle" the Keyboard Illumination Toggle key +"KBDIllumUp" the Keyboard Illumination Up key +"Keypad 0" the 0 key (numeric keypad) +"Keypad 00" the 00 key (numeric keypad) +"Keypad 000" the 000 key (numeric keypad) +"Keypad 1" the 1 key (numeric keypad) +"Keypad 2" the 2 key (numeric keypad) +"Keypad 3" the 3 key (numeric keypad) +"Keypad 4" the 4 key (numeric keypad) +"Keypad 5" the 5 key (numeric keypad) +"Keypad 6" the 6 key (numeric keypad) +"Keypad 7" the 7 key (numeric keypad) +"Keypad 8" the 8 key (numeric keypad) +"Keypad 9" the 9 key (numeric keypad) +"Keypad A" the A key (numeric keypad) +"Keypad &" the & key (numeric keypad) +"Keypad @" the @ key (numeric keypad) +"Keypad B" the B key (numeric keypad) +"Keypad Backspace" the Backspace key (numeric keypad) +"Keypad Binary" the Binary key (numeric keypad) +"Keypad C" the C key (numeric keypad) +"Keypad Clear" the Clear key (numeric keypad) +"Keypad ClearEntry" the Clear Entry key (numeric keypad) +"Keypad :" the : key (numeric keypad) +"Keypad ," the Comma key (numeric keypad) +"Keypad D" the D key (numeric keypad) +"Keypad &&" the && key (numeric keypad) +"Keypad ||" the || key (numeric keypad) +"Keypad Decimal" the Decimal key (numeric keypad) +"Keypad /" the / key (numeric keypad) +"Keypad E" the E key (numeric keypad) +"Keypad Enter" the Enter key (numeric keypad) +"Keypad =" the = key (numeric keypad) +"Keypad = (AS400)" the Equals AS400 key (numeric keypad) +"Keypad !" the ! key (numeric keypad) +"Keypad F" the F key (numeric keypad) +"Keypad >" the Greater key (numeric keypad) +"Keypad #" the # key (numeric keypad) +"Keypad Hexadecimal" the Hexadecimal key (numeric keypad) +"Keypad {" the Left Brace key (numeric keypad) +"Keypad (" the Left Parenthesis key (numeric keypad) +"Keypad <" the Less key (numeric keypad) +"Keypad MemAdd" the Mem Add key (numeric keypad) +"Keypad MemClear" the Mem Clear key (numeric keypad) +"Keypad MemDivide" the Mem Divide key (numeric keypad) +"Keypad MemMultiply" the Mem Multiply key (numeric keypad) +"Keypad MemRecall" the Mem Recall key (numeric keypad) +"Keypad MemStore" the Mem Store key (numeric keypad) +"Keypad MemSubtract" the Mem Subtract key (numeric keypad) +"Keypad -" the - key (numeric keypad) +"Keypad \*" the \* key (numeric keypad) +"Keypad Octal" the Octal key (numeric keypad) +"Keypad %" the Percent key (numeric keypad) +"Keypad ." the . key (numeric keypad) +"Keypad +" the + key (numeric keypad) +"Keypad +/-" the +/- key (numeric keypad) +"Keypad ^" the Power key (numeric keypad) +"Keypad }" the Right Brace key (numeric keypad) +"Keypad )" the Right Parenthesis key (numeric keypad) +"Keypad Space" the Space key (numeric keypad) +"Keypad Tab" the Tab key (numeric keypad) +"Keypad \|" the \| key (numeric keypad) +"Keypad XOR" the XOR key (numeric keypad) +"L" +"Left Alt" alt, option +"Left Ctrl" +"Left" the Left arrow key (navigation keypad) +"[" +"Left GUI" windows, command (apple), meta +"Left Shift" +"M" +"Mail" the Mail/eMail key +"MediaSelect" the Media Select key +"Menu" +"-" +"ModeSwitch" I'm not sure if this is really not covered by any of the above, but since there's a special KMOD_MODE for it I'm adding it here +"Mute" +"N" +"Numlock" the Num Lock key (PC) / the Clear key (Mac) +"O" +"Oper" +"Out" +"P" +"PageDown" +"PageUp" +"Paste" +"Pause" the Pause / Break key +"." +"Power" The USB document says this is a status flag, not a physical key - but some Mac keyboards do have a power key. +"PrintScreen" +"Prior" +"Q" +"R" +"Right Alt" alt gr, option +"Right Ctrl" +"Return" the Enter key (main keyboard) +"Return" +"Right GUI" windows, command (apple), meta +"Right" the Right arrow key (navigation keypad) +"]" +"Right Shift" +"S" +"ScrollLock" +"Select" +";" +"Separator" +"/" +"Sleep" the Sleep key +"Space" the Space Bar key(s) +"Stop" +"SysReq" the SysReq key +"T" +"Tab" the Tab key +"ThousandsSeparator" the Thousands Separator key +"U" +"Undo" +"Up" the Up arrow key (navigation keypad) +"V" +"VolumeDown" +"VolumeUp" +"W" +"WWW" the WWW/World Wide Web key +"X" +"Y" +"Z" +"#" ISO USB keyboards actually use this code instead of 49 for the same key, but all OSes I've seen treat the two codes identically. So, as an implementor, unless your keyboard generates both of those codes and your OS treats them differently, you should generate SDL_SCANCODE_BACKSLASH instead of this code. As a user, you should not rely on this code because SDL will never generate it with most (all?) keyboards. +"&" +"*" +"@" +"^" +":" +"$" +"!" +">" +"#" +"(" +"<" +"%" +"+" +"?" +")" +"_" +===================== ================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================ diff --git a/Documentation/Manual/Installation.rst b/Documentation/Manual/Installation.rst new file mode 100644 index 0000000..23a2128 --- /dev/null +++ b/Documentation/Manual/Installation.rst @@ -0,0 +1,26 @@ + +Installation +#################### + +Setting up a base installation can be done by performing the following steps: + +Overview +------------------------------------------ +#. Unzip RetroFE +#. Edit your Settings.conf +#. Setup your launchers (emulators) +#. Setup your collections (game lists) +#. Edit your Collections/Main/Menu.xml +#. Run RetroFE.exe + + +Details +------------------------------------------ +#. Extract the contents of the frontend to a folder of your choosing. +#. Edit your :ref:`Configuration` file (/Settings.conf) +#. Setup your launchers (emulators) (/Launchers/\*.conf) +#. Setup your collections (game lists) for your games. (/Collections//\*.conf) +#. Edit your main menu (Collections/Main/Menu.xml) to show what collections show up on the front page. +#. Run RetroFE.exe + +It is recommended that you organize your assets (games, artwork, videos, etc...) prior to configuring. After getting your system up and running you can download additional layouts or create your own layout (see :ref:`Layouts` for instructions on how to create your own layout). diff --git a/Documentation/Manual/Layouts.rst b/Documentation/Manual/Layouts.rst new file mode 100644 index 0000000..3379048 --- /dev/null +++ b/Documentation/Manual/Layouts.rst @@ -0,0 +1,561 @@ +.. _Layouts: + +********** +Layouts +********** +A layout defines your user experience for displaying a collection. The layout XML file defines where graphical components are displayed, what audio is played, and how to animate components when certain events occur. + +Each collection can have its own layout. Edit your :ref:`ConfigurationCollections` files to pick your layout. + +File format +#################### + +All XML tags must be inside the root layout tag. + +.. code-block:: xml + + + ... + + + + attributes +=================== + +=========================== ===================================================================================================================================== +Attribute Description +=========================== ===================================================================================================================================== +width The virtual width to use for this layout. This will be scaled automatically by the frontend if the screen resolution is different. +height The virtual height to use for this layout. This will be scaled automatically by the frontend if the screen resolution is different. +font Location of the font (relative to the layout folder) +fontColor RGB color of the font (in hex) +=========================== ===================================================================================================================================== + +The following example uses a layout that is setup for 1024x768 pixels (4:3 aspect ratio). The frontend will handle layout scaling if your monitor runs at a larger resolution +and is of the same aspect ratio (i.e 1600x1200). The frontend will still handle layout scaling if the aspect ratio is different, however, your image will look stretched +(i.e 1920x1080 resolution, 16:9 aspect ratio). + +.. code-block:: xml + + + ... + + +The following example sets the menu font to Age.otf with a color of Royal Blue Red=41(65) Green=69(105) Blue=E1(225) + +.. code-block:: xml + + + + + +Components +########## + +A component is a graphical item to be displayed on your screen (i.e. a menu, image, video, text). + +=========================== =========================================================================== +Top Level Components Description +=========================== =========================================================================== + Menu for layout (can only contain one menu per layout) + Display a single image (i.e. a background image) + An image that is reloaded with one for a particular selected item + Display a video for the selected item +=========================== =========================================================================== + +Component attributes +==================== + +Each component (listed above) supports the following attributes: + +=========================== ================================================================================ +Attribute Description +=========================== ================================================================================ +x X coordinate of where to place the component +y Y coordinate of where to place the component +xOffset Relative X offset of how many pixels to shift the object from x (x + xOffset) +yOffset Relative Y offset of how many pixels to shift the object from y (y + yOffset) +xOrigin X offset on image to use as the pin point for placement +yOrigin Y offset on image to use as the pin point for placement +transparency 0 = 0% visible, 0.5=50% visible, 1=100% visible +angle Angle to rotate image, in degrees +width Width of the component. Image will be scaled appropriately if not specified. +height Height of the component. Image will be scaled appropriately if not specified. +minWidth Minimum width to allow the image to be (if scaling is needed) +minHeight Minimum height to allow the image to be (if scaling is needed) +maxWidth Maximum width to allow the image to be (if scaling is needed) +maxHeight Maximum height to allow the image to be (if scaling is needed) +fontSize Size of font to display component is rendering text +=========================== ================================================================================ + +(As a reminder, all examples shown below must be inside a tag) + +Relative Positioning Diagram +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. image:: coordinates.png + :width: 400pt + +Attribute values (alignment) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Keywords can be passed into the values of some attributes for alignment. + +All horizontal based attributes (i.e. x, xOffset, xOrigin, width, minWidth, maxWidth) can support the following values: "left", "center", "right", "stretch" + +All vertical based attributes (i.e. x, yOffset, yOrigin, height, minHeight, maxHeight) can support the following values: "top", "center", "bottom", "stretch" + +Display an image stretched across the the screen +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: xml + + + +Display an image centered on the screen +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: xml + + + +Display an image aligned at the bottom right of the screen +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Use the bottom rightmost pixel as the reference point when displaying on the screen and display at the bottom rightmost position. + +.. code-block:: xml + + + + +Display an image being offset 100 pixels from the right of the page (vertically centered) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Use the rightmost (vertical center) pixel as a reference point when displaying on the screen. +Display at the right-center area of the page. +Offset the image to the left by 100 pixels. + +.. code-block:: xml + + + + + +Animations +########### + +The animation engine is very flexible. You can move, rotate, scale, and make images transparent. See the basic example XML for performing an animation. The sections below explain what each tag is responsible for. + +.. code-block:: xml + + + + + + + + + + + + + + + +===================================== ================================================================================================= +Tag (in example above) Description +===================================== ================================================================================================= + The component to animate. In this case it is an image. + When to trigger the event. In this case it will be triggered when the page is first loaded. + Groups component properties to animate. In this case the first group animates the x and y coordinates + together for one second and then later animates the y axis for half a second. + Defines the start, end, and algorithm to use for animating a property (in this case the X and Y position). + Event that is continuously looped when there is no active input (when the menu is idling) +===================================== ================================================================================================= + + +Events +=================== + +The following animations are supported by all component tags. + +===================================== ================================================================================================= +Tag Description +===================================== ================================================================================================= + Events that are triggered when the layout first starts + Events that are triggered when the layout exits + Events that are triggered when the currently highlighted item is no longer highlighted + Events that are triggered when the item is highlighted + Event that is continuously looped when there is no active input (when the menu is idling) +===================================== ================================================================================================= + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + animation tag +=================== +An animation is a collection of animation properties to change at the same time. You can "daisy chain" multiple animations. + +.. code-block:: xml + + + + + + + + + + + + + tag +=============== +An animation tag defines what property to animate. + +=========================== ================================================================================================================================== +Attribute Description +=========================== ================================================================================================================================== +type Component property to animate. Supported types are: x, y, width, height, transparency, angle, xOrigin, yOrigin, xOffset, yOffset +from Starting value +to Ending value +algorithm Motion (tweening) algorithm. Defaults to linear if not specified. See Animation algorithms for more information. +=========================== ================================================================================================================================== + +The following example animates an image on the x axis to move from the left to the right of the screen in 1 second. + +.. code-block:: xml + + + + + + + + + +The following example animates an image on the x axis to move from the top left to the bottom right of the screen in 1 second. + +.. code-block:: xml + + + + + + + + + + +Animation algorithms +^^^^^^^^^^^^^^^^^^^^^ +See http://gizma.com/easing/ for examples on how each animation operates. + +===================================== ================================================================================================= +Algorithm Description +===================================== ================================================================================================= +linear no easing, no acceleration (default if none is specified) +easeinquadratic accelerating from zero velocity +easeoutquadratic deaccelerating from zero velocity +easeinoutquadratic acceleration until halfway, then deceleration +easeincubic accelerating from zero velocity +easeoutcubic deaccelerating from zero velocity +easeinoutcubic acceleration until halfway, then deceleration +easeinquartic accelerating from zero velocity +easeoutquartic deaccelerating from zero velocity +easeinoutquartic acceleration until halfway, then deceleration +easeinquintic accelerating from zero velocity +easeoutquintic deaccelerating from zero velocity +easeinoutquintic acceleration until halfway, then deceleration +easeinsinusoidal accelerating from zero velocity +easeoutsinusoidal deaccelerating from zero velocity +easeinoutsinusoidal acceleration until halfway, then deceleration +easeinexponential accelerating from zero velocity +easeoutexponential deaccelerating from zero velocity +easeinoutexponential acceleration until halfway, then deceleration +easeincircular accelerating from zero velocity +easeoutcircular deaccelerating from zero velocity +easeinoutcircular acceleration until halfway, then deceleration +===================================== ================================================================================================= + +Daisy chained animation example +================================ + +Take an image and move it from the top left of the screen to the center in 1 second. After the animation completes move the image +from the center of the screen to the bottom center of the screen in 0.5 seconds. + +.. code-block:: xml + + + + + + + + + + + + + +Fully animating +================================ + +While this example may not be practical; it showcases all the properties that can be animated. + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Images +#################### + +Component attributes +==================== + +See below for a list of supported attributes (in addition to the standard component attributes listed above) + +=========================== ================================================================================ +Attribute Description +=========================== ================================================================================ +src location of the source image (relative to the layout folder) +=========================== ================================================================================ + +For example, if you want to display picture of an Nintendo console (named "NES Console.png" in your layout folder), you would do the following: + +.. code-block:: xml + + + + +Reloadable Images +############################## + +Displays image for the currently highlighted menu item. + +Component attributes +==================== + +See below for a list of supported attributes (in addition to the standard component attributes listed above). + +=========================== ===================================================================================================================================================================== +Attribute Description +=========================== ===================================================================================================================================================================== +type Type of image to display (using the selected item). +=========================== ===================================================================================================================================================================== + +For example, if you want to display a snap shot of the selected menu item, you would do the following in your Layout.xml file: + +.. code-block:: xml + + + +Your Settings.conf file will have the following line + +.. code-block:: xml + + media.snap = D:/Video Game Artwork/Nintendo/Snaps + +If an item titled "Tetris (USA)" was selected, the reloadable image component will try to load "D:/Video Game Artwork/Nintendo/Snaps/Tetris (USA).png". If no image could be found than nothing +will be displayed. + +Reloadable Videos +############################## + +Displays video for the currently highlighted menu item. + +Component attributes +==================== + +See below for a list of supported attributes (in addition to the standard component attributes listed above). + +=========================== ===================================================================================================================================================================== +Attribute Description +=========================== ===================================================================================================================================================================== +imageType Type of image to display if the video could not be found (using the selected item). +=========================== ===================================================================================================================================================================== + +For example, if you want to display a video of the selected menu item, you would do the following in your Layout.xml file: + +.. code-block:: xml + + + +Your Settings.conf file will have the following line + +.. code-block:: xml + + media.video = D:/Video Game Artwork/Nintendo/Videos + +If an item titled "Tetris (USA)" was selected, the reloadable image component will try to load "D:/Video Game Artwork/Nintendo/Videos/Tetris (USA).png". If no image could be found than nothing +will be displayed. + +If you do not want to display an image component if the video does not exist, simply do not specify an imageType attribute: + +.. code-block:: xml + + + +Rendering Text +############################## + +Displays static text on the screen + +Component attributes +==================== + +See below for a list of supported attributes (in addition to the standard component attributes listed above). + +=========================== ===================================================================================================================================================================== +Attribute Description +=========================== ===================================================================================================================================================================== +value Contents of the text to display +=========================== ===================================================================================================================================================================== + +For example, if you want to display a video of the selected menu item, you would do the following in your Layout.xml file: + +.. code-block:: xml + + + +Menu +########### + +The menu supports animations just like every other component. There can be only one menu per layout. + +See below for a list of supported attributes (in addition to the standard component attributes listed above). + + + +menu tag +==================== + +Each menu tag represents a point on where to display a scrolling list item in the menu. When scrolling, the items themselves will scroll/move from one item point to another. +If an attribute in is not specified, it will use the attribute specified in the . + +.. code-block:: xml + + + + + + + + + + + +Animating the menu and list items +================================== +Not only can the entire menu have an animation performed, the menu item at a particular point can also be animated. See below: + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Sounds +####### +In addition to displaying graphical components, the frontend supports sound effects that are triggered when certain events occur. + +=============================== ================================================================================================= +Tag Description +=============================== ================================================================================================= + Sound triggered when the layout is started + Sound triggered when the layout is exited + Sound triggered when a new item is highlighted. This will not loop while actively scrolling. + Sound triggered when an item is selected2 +=============================== ================================================================================================= + +Each sound effect supports the following parameters: + +=========================== ===================================================================================================================================================================== +Attribute Description +=========================== ===================================================================================================================================================================== +src Location of the sound file (relative to the layout folder). +=========================== ===================================================================================================================================================================== + +.. code-block:: xml + + + + + + + diff --git a/Documentation/Manual/Makefile b/Documentation/Manual/Makefile new file mode 100644 index 0000000..db17d5a --- /dev/null +++ b/Documentation/Manual/Makefile @@ -0,0 +1,89 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Puddle.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Puddle.qhc" + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/Documentation/Manual/Overview.rst b/Documentation/Manual/Overview.rst new file mode 100644 index 0000000..d653938 --- /dev/null +++ b/Documentation/Manual/Overview.rst @@ -0,0 +1,69 @@ +.. _Overview: + +================================== +Overview +================================== + +About +#################### +RetroFE is a menu system frontend to use for navigating through your game collections. It is intended to be loaded on arcade cabinets or media PCs to hide the operating system. + +Operating Systems +#################### + +Currently RetroFE runs in both Windows and Linux on x86 architectures. +Future releases will include support for OSX, and the Raspberry Pi. + +Folder Structure +#################### + +Main +------------ + +The frontend contains several folders to help manage your experience. + +============================================= ======================================================================================================================================== +File or Folder Description +============================================= ======================================================================================================================================== +/Documentation Documentation for using the frontend (what you are currently reading) +/RetroFE.lnk Shortcut to RetroFE Executable (points to Core/RetroFE.exe) +/Layouts Folder containing all of your layouts/themes +/Launchers Folder containing all the launchers (emulators) +/Core Core libraries for RetroFE +/Core/RetroFE.exe Main Executable +/Collections Contains all your list information +/Collections/Main/Menu.xml List for the main menu +/Cache.db Used to help make the frontend run more quickly. This should not need to be touched or editied (unless you know what you are doing). +/Log.txt Log file from the last time you ran RetroFE. Used for troubleshooting issues. +/Settings.conf Main configuration. Set your screen resolution, controls, how to launch games, etc. +============================================= ======================================================================================================================================== + + +Terminology +#################### + +Collections +------------------- + +A collection is essentially a game list. Think of it as a "collection of games". + +See :ref:`ConfigurationCollections` for more information on how to setup and customize your collections. + + +Launchers +------------------- + +A launcher is an executable (i.e. an emulator) that is ran when a menu item is selected. + +See :ref:`ConfigurationLaunchers` for more information. + + +Menu +------------------- + +A menu defines how you navigate through the menu system. + +See :ref:`ConfigurationMenu` for more information. + + + diff --git a/Documentation/Manual/Troubleshooting.rst b/Documentation/Manual/Troubleshooting.rst new file mode 100644 index 0000000..62c2bb0 --- /dev/null +++ b/Documentation/Manual/Troubleshooting.rst @@ -0,0 +1,5 @@ +Troubleshooting +#################### + +Having troubles launching items? Lists not showing up correctly? Graphics not showing up properly? Is the frontend crashing? Open up Log.txt to help diagnose your problems. Also visit www.retrofe.com for any questions. + diff --git a/Documentation/Manual/conf.py b/Documentation/Manual/conf.py new file mode 100644 index 0000000..c2ada88 --- /dev/null +++ b/Documentation/Manual/conf.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# +# Puddle documentation build configuration file, created by +# sphinx-quickstart on Thu Apr 17 14:08:27 2014. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.append(os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'RetroFE' +copyright = u'2014, Don Honerbrink' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1.0.12 beta' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directory, that shouldn't be searched +# for source files. +exclude_trees = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. Major themes that come with +# Sphinx are currently 'default' and 'sphinxdoc'. +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = [ "." ] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_use_modindex = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Puddledoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'RetroFE.tex', u'RetroFE Documentation', + u'Don Honerbrink', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_use_modindex = True diff --git a/Documentation/Manual/coordinates.png b/Documentation/Manual/coordinates.png new file mode 100644 index 0000000..d07242b Binary files /dev/null and b/Documentation/Manual/coordinates.png differ diff --git a/Documentation/Manual/easing.swf b/Documentation/Manual/easing.swf new file mode 100644 index 0000000..06cd9bb Binary files /dev/null and b/Documentation/Manual/easing.swf differ diff --git a/Documentation/Manual/index.rst b/Documentation/Manual/index.rst new file mode 100644 index 0000000..0a21f7c --- /dev/null +++ b/Documentation/Manual/index.rst @@ -0,0 +1,17 @@ +RetroFE +====================================================== + +:Release: |release| +:Date: |today| + +User Documentation +------------------ + +.. toctree:: + :maxdepth: 2 + + Overview + Installation + Configuration + Layouts + Troubleshooting diff --git a/Documentation/Manual/make.bat b/Documentation/Manual/make.bat new file mode 100644 index 0000000..4754964 --- /dev/null +++ b/Documentation/Manual/make.bat @@ -0,0 +1,113 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +set SPHINXBUILD=sphinx-build +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Puddle.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Puddle.ghc + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/Documentation/Manual/sphinx_rtd_theme/__init__.py b/Documentation/Manual/sphinx_rtd_theme/__init__.py new file mode 100644 index 0000000..1440863 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/__init__.py @@ -0,0 +1,17 @@ +"""Sphinx ReadTheDocs theme. + +From https://github.com/ryan-roemer/sphinx-bootstrap-theme. + +""" +import os + +VERSION = (0, 1, 5) + +__version__ = ".".join(str(v) for v in VERSION) +__version_full__ = __version__ + + +def get_html_theme_path(): + """Return list of HTML theme paths.""" + cur_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + return cur_dir diff --git a/Documentation/Manual/sphinx_rtd_theme/breadcrumbs.html b/Documentation/Manual/sphinx_rtd_theme/breadcrumbs.html new file mode 100644 index 0000000..ff0938e --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/breadcrumbs.html @@ -0,0 +1,19 @@ + + + Docs » + {% for doc in parents %} + {{ doc.title }} » + {% endfor %} + {{ title }} + + {% if display_github %} + Edit on GitHub + {% elif display_bitbucket %} + Edit on Bitbucket + {% elif show_source and has_source and sourcename %} + View page source + {% endif %} + + + + diff --git a/Documentation/Manual/sphinx_rtd_theme/footer.html b/Documentation/Manual/sphinx_rtd_theme/footer.html new file mode 100644 index 0000000..3c7afed --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/footer.html @@ -0,0 +1,32 @@ + diff --git a/Documentation/Manual/sphinx_rtd_theme/layout.html b/Documentation/Manual/sphinx_rtd_theme/layout.html new file mode 100644 index 0000000..48b64f5 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/layout.html @@ -0,0 +1,160 @@ +{# TEMPLATE VAR SETTINGS #} +{%- set url_root = pathto('', 1) %} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} +{%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} +{%- else %} + {%- set titlesuffix = "" %} +{%- endif %} + + + + + + + + {% block htmltitle %} + {{ title|striptags|e }}{{ titlesuffix }} + {% endblock %} + + {# FAVICON #} + {% if favicon %} + + {% endif %} + + {# CSS #} + + + {# OPENSEARCH #} + {% if not embedded %} + {% if use_opensearch %} + + {% endif %} + + {% endif %} + + {# RTD hosts this file, so just load on non RTD builds #} + {% if not READTHEDOCS %} + + {% endif %} + + {% for cssfile in css_files %} + + {% endfor %} + + {%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + + {%- if parents %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} + {%- endblock %} + {%- block extrahead %} {% endblock %} + + {# Keep modernizr in head - http://modernizr.com/docs/#installing #} + + + + + + + + + {# SIDE NAV, TOGGLES ON MOBILE #} + + + {{ project }} + {% include "searchbox.html" %} + + + + {% set toctree = toctree(maxdepth=2, collapse=False, includehidden=True) %} + {% if toctree %} + {{ toctree }} + {% else %} + + {{ toc }} + {% endif %} + + + + + + + {# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #} + + + {{ project }} + + + + {# PAGE CONTENT #} + + + {% include "breadcrumbs.html" %} + + {% block body %}{% endblock %} + + {% include "footer.html" %} + + + + + + + {% include "versions.html" %} + + {% if not embedded %} + + + {%- for scriptfile in script_files %} + + {%- endfor %} + + {% endif %} + + {# RTD hosts this file, so just load on non RTD builds #} + {% if not READTHEDOCS %} + + {% endif %} + + {# STICKY NAVIGATION #} + {% if theme_sticky_navigation %} + + {% endif %} + + {%- block footer %} {% endblock %} + + + diff --git a/Documentation/Manual/sphinx_rtd_theme/layout_old.html b/Documentation/Manual/sphinx_rtd_theme/layout_old.html new file mode 100644 index 0000000..deb8df2 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/layout_old.html @@ -0,0 +1,205 @@ +{# + basic/layout.html + ~~~~~~~~~~~~~~~~~ + + Master layout template for Sphinx themes. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- block doctype -%} + +{%- endblock %} +{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %} +{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %} +{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and + (sidebars != []) %} +{%- set url_root = pathto('', 1) %} +{# XXX necessary? #} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} +{%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} +{%- else %} + {%- set titlesuffix = "" %} +{%- endif %} + +{%- macro relbar() %} + + {{ _('Navigation') }} + + {%- for rellink in rellinks %} + + {{ rellink[3] }} + {%- if not loop.first %}{{ reldelim2 }}{% endif %} + {%- endfor %} + {%- block rootrellink %} + {{ shorttitle|e }}{{ reldelim1 }} + {%- endblock %} + {%- for parent in parents %} + {{ parent.title }}{{ reldelim1 }} + {%- endfor %} + {%- block relbaritems %} {% endblock %} + + +{%- endmacro %} + +{%- macro sidebar() %} + {%- if render_sidebar %} + + + {%- block sidebarlogo %} + {%- if logo %} + + + + {%- endif %} + {%- endblock %} + {%- if sidebars != None %} + {#- new style sidebar: explicitly include/exclude templates #} + {%- for sidebartemplate in sidebars %} + {%- include sidebartemplate %} + {%- endfor %} + {%- else %} + {#- old style sidebars: using blocks -- should be deprecated #} + {%- block sidebartoc %} + {%- include "localtoc.html" %} + {%- endblock %} + {%- block sidebarrel %} + {%- include "relations.html" %} + {%- endblock %} + {%- block sidebarsourcelink %} + {%- include "sourcelink.html" %} + {%- endblock %} + {%- if customsidebar %} + {%- include customsidebar %} + {%- endif %} + {%- block sidebarsearch %} + {%- include "searchbox.html" %} + {%- endblock %} + {%- endif %} + + + {%- endif %} +{%- endmacro %} + +{%- macro script() %} + + {%- for scriptfile in script_files %} + + {%- endfor %} +{%- endmacro %} + +{%- macro css() %} + + + {%- for cssfile in css_files %} + + {%- endfor %} +{%- endmacro %} + + + + + {{ metatags }} + {%- block htmltitle %} + {{ title|striptags|e }}{{ titlesuffix }} + {%- endblock %} + {{ css() }} + {%- if not embedded %} + {{ script() }} + {%- if use_opensearch %} + + {%- endif %} + {%- if favicon %} + + {%- endif %} + {%- endif %} +{%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + + {%- if parents %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} +{%- endblock %} +{%- block extrahead %} {% endblock %} + + +{%- block header %}{% endblock %} + +{%- block relbar1 %}{{ relbar() }}{% endblock %} + +{%- block content %} + {%- block sidebar1 %} {# possible location for sidebar #} {% endblock %} + + + {%- block document %} + + {%- if render_sidebar %} + + {%- endif %} + + {% block body %} {% endblock %} + + {%- if render_sidebar %} + + {%- endif %} + + {%- endblock %} + + {%- block sidebar2 %}{{ sidebar() }}{% endblock %} + + +{%- endblock %} + +{%- block relbar2 %}{{ relbar() }}{% endblock %} + +{%- block footer %} + + asdf asdf asdf asdf 22 +{%- endblock %} + + + diff --git a/Documentation/Manual/sphinx_rtd_theme/search.html b/Documentation/Manual/sphinx_rtd_theme/search.html new file mode 100644 index 0000000..e3aa9b5 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/search.html @@ -0,0 +1,50 @@ +{# + basic/search.html + ~~~~~~~~~~~~~~~~~ + + Template for the search page. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- extends "layout.html" %} +{% set title = _('Search') %} +{% set script_files = script_files + ['_static/searchtools.js'] %} +{% block footer %} + + {# this is used when loading the search index using $.ajax fails, + such as on Chrome for documents on localhost #} + + {{ super() }} +{% endblock %} +{% block body %} + + + + {% trans %}Please activate JavaScript to enable the search + functionality.{% endtrans %} + + + + + {% if search_performed %} + {{ _('Search Results') }} + {% if not search_results %} + {{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }} + {% endif %} + {% endif %} + + {% if search_results %} + + {% for href, caption, context in search_results %} + + {{ caption }} + {{ context|e }} + + {% endfor %} + + {% endif %} + +{% endblock %} diff --git a/Documentation/Manual/sphinx_rtd_theme/searchbox.html b/Documentation/Manual/sphinx_rtd_theme/searchbox.html new file mode 100644 index 0000000..24418d3 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/searchbox.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Documentation/Manual/sphinx_rtd_theme/static/css/badge_only.css b/Documentation/Manual/sphinx_rtd_theme/static/css/badge_only.css new file mode 100644 index 0000000..4868a00 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/static/css/badge_only.css @@ -0,0 +1 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:"\f02d"}.icon-book:before{content:"\f02d"}.fa-caret-down:before{content:"\f0d7"}.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} diff --git a/Documentation/Manual/sphinx_rtd_theme/static/css/theme.css b/Documentation/Manual/sphinx_rtd_theme/static/css/theme.css new file mode 100644 index 0000000..5a5a481 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/static/css/theme.css @@ -0,0 +1,4 @@ +*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:20px 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.0.3");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.0.3") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.0.3") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.pull-left.icon{margin-right:.3em}.fa.pull-right,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before,.icon-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before,.icon-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:"\f057"}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before,.icon-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before,.icon-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:"\f0a8"}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before,.icon-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-asc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-desc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-reply-all:before{content:"\f122"}.fa-mail-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before,.icon-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .icon,.nav .fa,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .icon{display:inline}.btn .fa.fa-large,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a{color:#2980b9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:60px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:60px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27ae60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27ae60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#e74c3c !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#e67e22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980b9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#999;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{display:block;float:left;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{display:block;float:left;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{display:block;float:left;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#f3f6f6;color:#cad2d3}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e74c3c}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fff;color:#cad2d3;border-color:transparent}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{padding:6px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #e74c3c}.wy-control-group.wy-control-group-error textarea{border:solid 1px #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px;margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980b9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27ae60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#e74c3c !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}code,.rst-content tt{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:"Consolas","Monaco",monospace;color:#e74c3c;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9b59b6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:"Consolas","Monaco",monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:"Consolas","Monaco",monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#eaf2f5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#2980b9;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-side-nav-search{z-index:200;background-color:#2980b9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:absolute;top:0;left:0;width:300px;overflow:hidden;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}nav.stickynav{position:fixed;top:0}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after{visibility:visible;content:"\f0c1";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt{color:#000}.rst-content tt big,.rst-content tt em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt{font-weight:bold}.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040} diff --git a/Documentation/Manual/sphinx_rtd_theme/static/fonts/FontAwesome.otf b/Documentation/Manual/sphinx_rtd_theme/static/fonts/FontAwesome.otf new file mode 100644 index 0000000..8b0f54e Binary files /dev/null and b/Documentation/Manual/sphinx_rtd_theme/static/fonts/FontAwesome.otf differ diff --git a/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..7c79c6a Binary files /dev/null and b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot differ diff --git a/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..45fdf33 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..e89738d Binary files /dev/null and b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf differ diff --git a/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..8c1748a Binary files /dev/null and b/Documentation/Manual/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff differ diff --git a/Documentation/Manual/sphinx_rtd_theme/static/js/theme.js b/Documentation/Manual/sphinx_rtd_theme/static/js/theme.js new file mode 100644 index 0000000..60520cc --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/static/js/theme.js @@ -0,0 +1,47 @@ +$( document ).ready(function() { + // Shift nav in mobile when clicking the menu. + $(document).on('click', "[data-toggle='wy-nav-top']", function() { + $("[data-toggle='wy-nav-shift']").toggleClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + }); + // Close menu when you click a link. + $(document).on('click', ".wy-menu-vertical .current ul li a", function() { + $("[data-toggle='wy-nav-shift']").removeClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + }); + $(document).on('click', "[data-toggle='rst-current-version']", function() { + $("[data-toggle='rst-versions']").toggleClass("shift-up"); + }); + // Make tables responsive + $("table.docutils:not(.field-list)").wrap(""); +}); + +window.SphinxRtdTheme = (function (jquery) { + var stickyNav = (function () { + var navBar, + win, + stickyNavCssClass = 'stickynav', + applyStickNav = function () { + if (navBar.height() <= win.height()) { + navBar.addClass(stickyNavCssClass); + } else { + navBar.removeClass(stickyNavCssClass); + } + }, + enable = function () { + applyStickNav(); + win.on('resize', applyStickNav); + }, + init = function () { + navBar = jquery('nav.wy-nav-side:first'); + win = jquery(window); + }; + jquery(init); + return { + enable : enable + }; + }()); + return { + StickyNav : stickyNav + }; +}($)); diff --git a/Documentation/Manual/sphinx_rtd_theme/theme.conf b/Documentation/Manual/sphinx_rtd_theme/theme.conf new file mode 100644 index 0000000..dcfbf8c --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/theme.conf @@ -0,0 +1,8 @@ +[theme] +inherit = basic +stylesheet = css/theme.css + +[options] +typekit_id = hiw1hhg +analytics_id = +sticky_navigation = False diff --git a/Documentation/Manual/sphinx_rtd_theme/versions.html b/Documentation/Manual/sphinx_rtd_theme/versions.html new file mode 100644 index 0000000..8b3eb79 --- /dev/null +++ b/Documentation/Manual/sphinx_rtd_theme/versions.html @@ -0,0 +1,37 @@ +{% if READTHEDOCS %} +{# Add rst-badge after rst-versions for small badge style. #} + + + Read the Docs + v: {{ current_version }} + + + + + Versions + {% for slug, url in versions %} + {{ slug }} + {% endfor %} + + + Downloads + {% for type, url in downloads %} + {{ type }} + {% endfor %} + + + On Read the Docs + + Project Home + + + Builds + + + + Free document hosting provided by Read the Docs. + + + +{% endif %} +
+ +
asdf asdf asdf asdf 22
+ {% trans %}Please activate JavaScript to enable the search + functionality.{% endtrans %} +
{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}
{{ context|e }}