diff --git a/Launcher DL/Core/Configuration/Config.cs b/Launcher DL/Core/Configuration/Config.cs index 9e93681..6ebc5c9 100644 --- a/Launcher DL/Core/Configuration/Config.cs +++ b/Launcher DL/Core/Configuration/Config.cs @@ -1,22 +1,23 @@ using DLLanguages.Pick; +using static Launcher_DL.Core.Configuration.CONFIG_STR; namespace Launcher_DL.Core.Configuration; public class DefaultConfig { - public string background = "background.png"; - public string DefaultOutput = "output"; - public string BrowserCookie = "chrome"; + public string background = CONFIG_DEFAULT_BACKGROUND; + public string DefaultOutput = CONFIG_DEFAULT_OUTPUT; + public string BrowserCookie = CONFIG_DEFAULT_COOKIE; - public Color backgroundColor = ClrConv("#FF161438"); - public Color backgroundGlow = ClrConv("#FF7DB5FF"); + public Color backgroundColor = ClrConv(CONFIG_DEFAULT_BACKGROUND_COLOR); + public Color backgroundGlow = ClrConv(CONFIG_DEFAULT_BACKGROUND_GLOW); - public bool ShowSystemOutput = true; - public bool EnablePlaylist = true; - public bool EpicAnimations = true; - public bool AllowCookies = false; + public bool ShowSystemOutput = CONFIG_DEFAULT_SYSTEM_OUTPUT; + public bool EnablePlaylist = CONFIG_DEFAULT_PLAYLIST; + public bool EpicAnimations = CONFIG_DEFAULT_ANIMATIONS; + public bool AllowCookies = CONFIG_DEFAULT_COOKIES; - public int DefaultFileTypeOnStartUp = 0; + public int DefaultFileTypeOnStartUp = CONFIG_DEFAULT_FILE_TYPE; public LanguageName Language = 0; } @@ -24,13 +25,14 @@ public class Config { static bool error = false; static DefaultConfig DefaultConfiguration; - public static DefaultConfig ReadConfigINI(string Name = "Config.ini") + public static DefaultConfig ReadConfigINI() { - FileIniDataParser parser = new(); + string ConfigString = File.ReadAllText(CONFIG_NAME); + IniDataParser parser = new(); DefaultConfiguration = new(); - IniData Data = parser.ReadFile(Name); + IniData Data = parser.Parse(ConfigString); - string LanguageCheck = Data["App"]["Language"]; + string LanguageCheck = Data[CONFIG_SECTION_APP][CONFIG_LANGUAGE]; switch(LanguageCheck.ToLower()) { @@ -41,20 +43,17 @@ public static DefaultConfig ReadConfigINI(string Name = "Config.ini") case "bruh": DefaultConfiguration.Language = LanguageName.bruh; break; } - // HOLY FUCKING SHIT I JUST NEEDED TO ADD THE "REF" BECAUSE ITS JUST PASSING ITS VALUE - // SO IF I TRIED TO CHANGE THE VALUE FROM THAT METHOD IT WONT CHANGE UNLESS I REFERENCE IT - // THANKS TO THIS SAVIOR: - // https://codeeasy.io/lesson/passing_parameters_to_functions - CheckError(ref DefaultConfiguration.background, Data["Background"]["backgroundName"],"backgroundName"); - CheckError(ref DefaultConfiguration.backgroundColor, Data["Background"]["backgroundColor"],"backgroundColor"); - CheckError(ref DefaultConfiguration.backgroundGlow, Data["Background"]["backgroundGlowColor"],"backgroundGlowColor"); - CheckError(ref DefaultConfiguration.DefaultOutput, Data["File"]["DefaultOutput"],"DefaultOutput"); - CheckError(ref DefaultConfiguration.ShowSystemOutput, Data["Console"]["ShowSystemOutput"],"ShowSystemOutput"); - CheckError(ref DefaultConfiguration.DefaultFileTypeOnStartUp, Data["DropDown"]["DefaultFileTypeOnStartUp"],"DefaultFileTypeOnStartUp"); - CheckError(ref DefaultConfiguration.EnablePlaylist, Data["Playlist"]["EnablePlaylist"],"EnablePlaylist"); - CheckError(ref DefaultConfiguration.EpicAnimations, Data["graphics"]["EpicAnimations"],"EpicAnimations"); - CheckError(ref DefaultConfiguration.AllowCookies, Data["Cookies"]["AllowCookies"],"AllowCookies"); - CheckError(ref DefaultConfiguration.BrowserCookie, Data["Cookies"]["BrowserCookie"],"BrowserCookie"); + // I am pleased on this + CheckError(ref DefaultConfiguration.background, Data[CONFIG_SECTION_BACKROUND][0], CONFIG_BACKGROUND_NAME); + CheckError(ref DefaultConfiguration.backgroundColor, Data[CONFIG_SECTION_BACKROUND][1], CONFIG_BACKGROUND_COLOR); + CheckError(ref DefaultConfiguration.backgroundGlow, Data[CONFIG_SECTION_BACKROUND][2], CONFIG_BACKGROUND_GLOW); + CheckError(ref DefaultConfiguration.AllowCookies, Data[CONFIG_SECTION_COOKIES][0], CONFIG_ALLOW_COOKIES); + CheckError(ref DefaultConfiguration.BrowserCookie, Data[CONFIG_SECTION_COOKIES][1], CONFIG_BROWSER_COOKIES); + CheckError(ref DefaultConfiguration.DefaultOutput, Data[CONFIG_SECTION_FILE][0], CONFIG_OUTPUT); + CheckError(ref DefaultConfiguration.ShowSystemOutput, Data[CONFIG_SECTION_CONSOLE][0], CONFIG_SYSTEM_OUTPUT); + CheckError(ref DefaultConfiguration.DefaultFileTypeOnStartUp, Data[CONFIG_SECTION_DROPDOWN][0], CONFIG_FILE_TYPE); + CheckError(ref DefaultConfiguration.EnablePlaylist, Data[CONFIG_SECTION_PLAYLIST][0], CONFIG_ENABLE_PLAYLIST); + CheckError(ref DefaultConfiguration.EpicAnimations, Data[CONFIG_SECTION_GRAPHICS][0], CONFIG_ANIMATIONS); if(!error) { @@ -73,7 +72,7 @@ public static DefaultConfig ReadConfigINI(string Name = "Config.ini") return DefaultConfiguration; } - private static void CheckError(ref T a,dynamic b,string c) + private static void CheckError(ref T a, dynamic b, string c) { #if DEBUG ConsoleDebug.LoadingConfig(a,b,c); @@ -81,14 +80,8 @@ private static void CheckError(ref T a,dynamic b,string c) try { - switch(a.GetType().ToString()) - { - case "System.String": a = b; break; - case "System.Int32": a = int.Parse(b); break; - case "System.Windows.Media.Color": a = ClrConv(b); break; - case "System.Boolean": a = bool.Parse(b); break; - } - + if(a.GetType().ToString().Contains(CONFIG_COLOR_CONTAINS)) a = ClrConv(b); + else a = b; } catch(Exception e) { error = true; diff --git a/Launcher DL/Core/Debug/ConsoleDebug.cs b/Launcher DL/Core/Debug/ConsoleDebug.cs index 5152bd1..04d370e 100644 --- a/Launcher DL/Core/Debug/ConsoleDebug.cs +++ b/Launcher DL/Core/Debug/ConsoleDebug.cs @@ -33,18 +33,13 @@ public static void LoadConfigDone(bool isFailed) } // goddamn it I got lazy naming these parameters - public static void LoadingConfig(dynamic a, dynamic b, string c) + public static void LoadingConfig(T a, dynamic b, string c) { Console.Write($"Loading {c}"); try { - switch(a.GetType().ToString()) - { - case "System.String": a = b; break; - case "System.Int32": a = int.Parse(b); break; - case "System.Windows.Media.Color": a = ClrConv(b); break; - case "System.Boolean": a = bool.Parse(b); break; - } + if(a.GetType().ToString().Contains("System.Windows.Media.Color")) a = ClrConv(b); + else a = b; Console.SetCursorPosition(34,4 + count); Console.Write($"\x1b[32mLOADED! = {b}\x1b[0m\n"); } catch diff --git a/Launcher DL/Core/Windows/WindowsComponents.cs b/Launcher DL/Core/Windows/WindowsComponents.cs index 98620a0..f7963ba 100644 --- a/Launcher DL/Core/Windows/WindowsComponents.cs +++ b/Launcher DL/Core/Windows/WindowsComponents.cs @@ -72,29 +72,25 @@ await Task.Run(()=>{ } } - // why does the Format combobox doesnt turn to bright red its just a dim - // unlike the others. public static void FreezeComponents(bool Freeze) { - buttonFileFormat.IsEnabled = true; - buttonDownload.IsEnabled = true; - buttonUpdate.IsEnabled = true; - buttonOpenFile.IsEnabled = true; - textBoxLink.IsEnabled = true; - textBoxName.IsEnabled = true; - comboBoxType.IsEnabled = true; - comboBoxFormat.IsEnabled = true; + UIElement[] ControlLists = + { + buttonFileFormat, + buttonDownload, + buttonUpdate, + buttonOpenFile, + textBoxLink, + textBoxName, + comboBoxType, + comboBoxFormat + }; + foreach(UIElement CL in ControlLists) + CL.IsEnabled = true; + if(Freeze) - { - buttonFileFormat.IsEnabled = false; - buttonDownload.IsEnabled = false; - buttonUpdate.IsEnabled = false; - buttonOpenFile.IsEnabled = false; - textBoxLink.IsEnabled = false; - textBoxName.IsEnabled = false; - comboBoxType.IsEnabled = false; - comboBoxFormat.IsEnabled = false; - } + foreach(UIElement CL in ControlLists) + CL.IsEnabled = false; } } \ No newline at end of file diff --git a/Launcher DL/FodyWeavers.xml b/Launcher DL/FodyWeavers.xml index c28ca0a..fbb6ac9 100644 --- a/Launcher DL/FodyWeavers.xml +++ b/Launcher DL/FodyWeavers.xml @@ -1,7 +1,7 @@  - INIFileParser + IniParser \ No newline at end of file diff --git a/Launcher DL/Launcher DL.csproj b/Launcher DL/Launcher DL.csproj index e1e59d5..c2ff796 100644 --- a/Launcher DL/Launcher DL.csproj +++ b/Launcher DL/Launcher DL.csproj @@ -18,6 +18,7 @@ uVad False NU1701,CS8981,NU1503 + none @@ -57,7 +58,10 @@ all compile; runtime; build; native; contentfiles; analyzers; buildtransitive - + + + ./ini-parser [modified]/IniParser.dll + diff --git a/Launcher DL/MainWindow.xaml.cs b/Launcher DL/MainWindow.xaml.cs index 8429da1..9020382 100644 --- a/Launcher DL/MainWindow.xaml.cs +++ b/Launcher DL/MainWindow.xaml.cs @@ -56,7 +56,8 @@ public MainWindow() buttonOpenFile.Click += delegate { - console.AddFormattedText("<%20>Test"); + WindowsComponents.FreezeComponents(false); + console.AddFormattedText("<%20>UNFREEZE!"); }; } } \ No newline at end of file diff --git a/Launcher DL/ini-parser [modified]/IniParser.dll b/Launcher DL/ini-parser [modified]/IniParser.dll new file mode 100644 index 0000000..9d2296e Binary files /dev/null and b/Launcher DL/ini-parser [modified]/IniParser.dll differ diff --git a/Launcher DL/ini-parser [modified]/IniParser.xml b/Launcher DL/ini-parser [modified]/IniParser.xml new file mode 100644 index 0000000..5f06066 --- /dev/null +++ b/Launcher DL/ini-parser [modified]/IniParser.xml @@ -0,0 +1,959 @@ + + + + IniParser + + + + + Gets or sets the string to use as new line string when formating an IniData structure using a + IIniDataFormatter. Parsing an ini-file accepts any new line character (Unix/windows) + + + This allows to write a file with unix new line characters on windows (and vice versa) + + Defaults to value Environment.NewLine + + + + In a property sets the number of spaces between the end of the key + and the beginning of the assignment string. + 0 is a valid value. + + + Defaults to 1 space + + + + + In a property sets the number of spaces between the end of + the assignment string and the beginning of the value. + 0 is a valid value. + + + Defaults to 1 space + + + + + Defines data for a Parser configuration object. + + With a configuration object you can redefine how the parser + will detect special items in the ini file by defining new regex + (e.g. you can redefine the comment regex so it just treat text as + a comment iff the comment caracter is the first in the line) + or changing the set of characters used to define elements in + the ini file (e.g. change the 'comment' caracter from ';' to '#') + You can also define how the parser should treat errors, or how liberal + or conservative should it be when parsing files with "strange" formats. + + + + Default values used if an instance of + is created without specifying a configuration. + + + + + Copy ctor. + + + Original instance to be copied. + + + + + Retrieving section / keys by name is done with a case-insensitive + search. + + + Defaults to false (case sensitive search) + + + + + Allows having keys at the begining of the file, before any section + is defined. Those keys don't belong to any section and are stored in + the special field. + If set to false and the ini file contains keys outside a section, + the parser will stop with an error. + + + Defaults to true. + + + + + Duplicated keys are not allowed. WHen a duplicated key is found, the parser will + stop with an error. + + + + + Duplicated keys are allowed. The value of the duplicate key will be the first + value found in the set of duplicated key names. + + + + + Duplicated keys are allowed. The value of the duplicate key will be the last + value found in the set of duplicated key names. + + + + + Duplicated keys are allowed. The value of the duplicate keys will be a string that + results in the concatenation of all the duplicated values found, separated by + the character + + + + + Sets the policy to use when two or more properties with the same key name are found + on the same section + + + Defaults to + + + + + Gets or sets the string used to concatenate duplicated keys. + + + Defaults to ";" + + + + + If true the instance will thrown an exception + if an error is found. + If false the parser will just stop execution and return a null value. + + + Defaults to true. + + + + + If set to false and the finds a duplicate section + the parser will stop with an error. + If set to true, duplicated sections are allowed in the file, but only a + element will be created in the + collection. + + + Defaults to false. + + + + + If set to true, it continues parsing the file even if a bad formed line + is found, but does not count as an error found (i.e. + will return false) + If set to false, it will throw an exception or track an error, + depending on the value of , + when the parser encounters a badly formed line. + + + Defaults to false. + + + + + If set to true, it will trim the whitespace out of the property when parsing. + If set to false, it will consider all the whitespace in the line as part of the + property when extracting the key and values. + + + Defaults to true. + + + + + If set to true, it will trim the whitespace out of the section name when parsing. + If set to false, it will consider all the whitespace in the line as part of the + section name. + + + Defaults to true. + + + + + If set to true, it will trim the whitespace out of the comments when parsing. + If set to false, it will consider all the whitespace in the line as part of the + comment. + + + Defaults to true. + + + + + If set to true, it will extract the comments from the parsed text and add them to + the data structure + If set to false, it will ignore all comments when parsing and not store them + saving memory and allocations. + + + + + Creates a new object that is a copy of the current instance. + + + + + This structure defines the format of the INI file by customization the characters used to define sections + key/values or comments. + Used IniDataParser to read INI files, and an IIniDataFormatter to write a new ini file string. + + + + + Ctor. + + + By default the various delimiters for the data are setted: + ';' for one-line comments + '[' ']' for delimiting a section + '=' for linking key / value pairs + + An example of well formed data with the default values: + + ;section comment
+ [section] ; section comment
+
+ ; key comment
+ key = value ;key comment
+
+ ;key2 comment
+ key2 = value
+
+
+
+
+ + + Copy ctor. + + + Original instance to be copied. + + + + + Sets the string that defines the start of a comment. + A comment spans from the mirst matching comment string + to the end of the line. + + + Defaults to string ";". + String returned will also be trimmed + + + + + Sets the string that defines the start of a section name. + + + Defaults to "[" + String returned will also be trimmed + + + + + Sets the char that defines the end of a section name. + + + Defaults to character ']' + String returned will also be trimmed + + + + + Sets the string used in the ini file to denote a key / value assigment + + + Defaults to character '=' + String returned will also be trimmed + + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + Represents an error ococcurred while parsing data + + + + + Formats a IniData structure to an string + + + + + Produces an string for a given structure + + String that represents an . + Ini data. + + Configuration used by this formatter when converting IniData + to an string + + + + + Represents all data from an INI file + + + + + Initializes an empty IniData instance. + + + + + Initialzes an IniData instance with a given scheme + + + + + + If set to true, it will automatically create a section when you use the indexed + access with a section name that does not exis. + If set to false, it will throw an exception if you try to access a section that + does not exist with the index operator. + + + Defaults to false. + + + + + Configuration used to write an ini file with the proper + delimiter characters and data. + + + If the instance was created by a parser, + this instance is a copy of the used + by the parser (i.e. different objects instances) + If this instance is created programatically without using a parser, this + property returns an instance of + + + + + Global sections. Contains properties which are not + enclosed in any section (i.e. they are defined at the beginning + of the file, before any section. + + + + + Gets the instance + with the specified section name. + with the specified section name. + + + + + Gets or sets all the + for this IniData instance. + + + + + Deletes all data + + + + + Deletes all comments in all sections and properties values + + + + + Merges the other iniData into this one by overwriting existing values. + Comments get appended. + + + IniData instance to merge into this. + If it is null this operation does nothing. + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + See property for more information. + + + + + Represents all sections from an INI file + + + + + Responsible for parsing an string from an ini file, and creating + an structure. + + + + + Ctor + + + + + Scheme that defines the structure for the ini file to be parsed + + + + + True is the parsing operation encounter any problem + + + + + Returns the list of errors found while parsing the ini file. + + + If the configuration option ThrowExceptionOnError is false it + can contain one element for each problem found while parsing; + otherwise it will only contain the very same exception that was + raised. + + + + + Parses a string containing valid ini data + + + String with data in INI format + + + + + Parses a string containing valid ini data + + + Text reader for the source string contaninig the ini data + + + An instance containing the data readed + from the source + + + Thrown if the data could not be parsed + + + + + Parses a string containing valid ini data + + + Text reader for the source string contaninig the ini data + + + An instance containing the data readed + from the source + + + Thrown if the data could not be parsed + + + + + Processes one line and parses the data found in that line + (section or key/value pair who may or may not have comments) + + + + + Proccess a string which contains an ini section.% + + + The string to be processed + + + + + Abstract Method that decides what to do in case we are trying + to add a duplicated key to a section + + + + + Adds a key to a concrete instance, checking + if duplicate keys are allowed in the configuration + + + Key name + + + Key's value + + + collection where the key should be inserted + + + Name of the section where the is contained. + Used only for logging purposes. + + + + + Creates a deep copy of the type T, meaning that all reference types get + copied too instead of copying the reference. + + + + + + Represents all data from an INI file exactly as the + class, but searching for sections and keys names is done with + a case insensitive search. + + + + + Initializes an empty IniData instance. + + + + + Copies an instance of the class + + Original + + + + Information associated to a property from an INI file. + Includes both the key, the value and the comments associated to + the property. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data is deeply copied + + + The instance of the class + used to create the new instance. + + + + + Gets or sets the comment list associated to this property. + Makes a copy og the values when set + + + + + Gets or sets the value associated to this property. + + + + + Gets or sets the name of this property. + + + + + Represents a collection of Keydata. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with a given + search comparer + + + Search comparer used to find the key by name in the collection + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data from the original KeyDataCollection instance is deeply copied + + + The instance of the class + used to create the new instance. + + + + + Gets or sets the value of a property. + + + If we try to assign the value of a property which doesn't exists, + a new one is added with the kay and the value specified + + + key of the property + + + + + Gets the value of a property. + + + Gets the key by int + + + key of the property + + + + + Return the number of keys in the collection + + + + + Adds a new key with the specified name and empty value and comments + + + New key to be added. + + + true if the key was added false if a key with the same name already exist + in the collection + + + + + Adds a new property to the collection + + + Property instance. + + + true if the property was added false if a property with the + same key already exist in the collection + + + + + Adds a new property with the specified key and value to the collection + + + key of the new property to be added. + + + Value associated to the property. + + + true if the property was added, false if a key with the same + name already exist in the collection. + + + + + Clears all comments of this section + + + + + Gets if a specified property with the given key name exists in + the collection. + + + Key name to search + + + true if a property with the givne exists in the collectoin + false otherwise + + + + + Retrieves the data for a specified key given its name + + Name of the key to retrieve. + + A instance holding + the key information or null if the key wasn't found. + + + + + Merges other Property into this, adding new properties if they + did not existed or overwriting values if the properties already + existed. + + + Comments are also merged but they are always added, not overwritten. + + + + + + Deletes all properties in this collection. + + + + + Deletes a previously existing key, including its associated data. + + The key to be removed. + + true if a key with the specified name was removed + false otherwise. + + + + + Allows iteration througt the collection. + + A strong-typed IEnumerator + + + + Implementation needed + + A weak-typed IEnumerator. + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + + + + Collection of Property for a given section + + + + + Information associated to a section in a INI File + Includes both the properties and the comments associated to the section. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data is deeply copied + + + The instance of the class + used to create the new instance. + + + Search comparer. + + + + + Gets or sets the name of the section. + + + The name of the section + + + + + Gets or sets the comment list associated to this section. + + + A list of strings. + + + + + Gets or sets the properties associated to this section. + + + A collection of Property objects. + + + + + Deletes all comments and properties from this Section + + + + + Deletes all comments in this section and in all the properties pairs it contains + + + + + Deletes all the properties pairs in this section. + + + + + Merges otherSection into this, adding new properties if they + did not existed or overwriting values if the properties already + existed. + + + Comments are also merged but they are always added, not overwritten. + + + + + + Represents a collection of Section. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + + StringComparer used when accessing section names + + + + + Initializes a new instance of the class + from a previous instance of . + + + Data is deeply copied + + + The instance of the class + used to create the new instance. + + + + Returns the number of Section elements in the collection + + + + + Gets the Properties associated to a specified section name. + + An instance of as class + holding the properties in the given section, or a null + value if the section doesn't exist. + + + + Creates a new section with empty data. + + + If a section with the same name exists, this operation has no effect. + + Name of the section to be created + true if the a new section with the specified name was added, + false otherwise + If the section name is not valid. + + + + Adds a new Section instance to the collection + + Data. + + + + Removes all entries from this collection + + + + + Gets if a section with a specified name exists in the collection. + + Name of the section to search + + true if a section with the specified name exists in the + collection false otherwise + + + + + Returns the section data from a specify section given its name. + + Name of the section. + + An instance of a class + holding the section data for the currently INI data + + + + + Removes the section with the given name and all its properties + + + true if the section with the specified name was removed, + false otherwise + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Creates a new object that is a copy of the current instance. + + + A new object that is a copy of this instance. + + +
+
diff --git a/Launcher DL/ini-parser [modified]/readme.md b/Launcher DL/ini-parser [modified]/readme.md new file mode 100644 index 0000000..273d5ad --- /dev/null +++ b/Launcher DL/ini-parser [modified]/readme.md @@ -0,0 +1,3 @@ +# this is my modified version of the ini-parser + +## I've already did a PR on the repo [click here](https://github.com/rickyah/ini-parser/pull/248) if you want to see it. \ No newline at end of file diff --git a/LauncherDL.sln b/LauncherDL.sln index 4d3dbd6..e281075 100644 --- a/LauncherDL.sln +++ b/LauncherDL.sln @@ -38,7 +38,6 @@ Global {95478B96-BF5F-4FDB-A305-1B5EB754DBD7}.Release|Any CPU.Build.0 = Release|Any CPU {95478B96-BF5F-4FDB-A305-1B5EB754DBD7}.Release|x64.ActiveCfg = Release|Any CPU {ECA96A04-9B9A-401E-9F64-9D84846C0E80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ECA96A04-9B9A-401E-9F64-9D84846C0E80}.Debug|Any CPU.Build.0 = Debug|Any CPU {ECA96A04-9B9A-401E-9F64-9D84846C0E80}.Debug|x64.ActiveCfg = Debug|Any CPU {ECA96A04-9B9A-401E-9F64-9D84846C0E80}.Debug|x64.Build.0 = Debug|Any CPU {ECA96A04-9B9A-401E-9F64-9D84846C0E80}.Release|Any CPU.ActiveCfg = Release|Any CPU