Update WidgetEvents Sample

Update WidgetEvents Sample

Previous version was a quick and dirty one, and not one I'd like to see as a Sample!
This one is better style and works properly as well!

--- TestApps/Samples/Samples/WidgetEvents.cs
+++ TestApps/Samples/Samples/WidgetEvents.cs
@@ -25,37 +25,54 @@
 // THE SOFTWARE.
 using System;
 using Xwt;
+using Xwt.Drawing;

 namespace Samples
 {
 	public class WidgetEvents: VBox
 	{
-		Label res;
+		Label la = new Label ("Move the mouse here");
+		Label res = new Label ("");
+		bool inside = false;
+		bool moved = false;

 		public WidgetEvents ()
 		{
-			Label la = new Label ("Move the mouse here");
-			res =  new Label ();
 			PackStart (la);
 			PackStart (res);

 			la.MouseEntered += delegate {
-				la.Text = "Mouse has Entered label";
+				inside = true;
+				Application.TimeoutInvoke (100, CheckMouse);
 			};
 			la.MouseExited += delegate {
-				la.Text = "Mouse has Exited label";
-				res.Text = "Mouse has moved out of label";
+				inside = false;
 			};
 			la.MouseMoved += delegate {
-				res.Text = "Mouse is moving in label";
-				Application.TimeoutInvoke (800, MouseStopped);
+				moved = true;
 			};
 		}

-		bool MouseStopped ()
+		bool CheckMouse ()
 		{
-			res.Text = "Mouse has stopped in label";
-			return false;
+			if (!inside) {
+				res.Text = "Mouse has Exited label";
+				la.TextColor = Colors.Black;
+				la.BackgroundColor = Colors.LightGray;
+				la.Text = "Move the mouse here";
+			} else {
+				res.Text = "Mouse has Entered label";
+				la.TextColor = Colors.White;
+				if (moved) {
+					la.BackgroundColor = Colors.Green;
+					la.Text = "Mouse is moving";
+					moved = false;	// reset and check next time
+				} else {
+					la.BackgroundColor = Colors.Red;
+					la.Text = "Mouse has stopped";
+				}
+			}
+			return inside;
 		}

 	}


generator readability

generator readability

--- Discriminated.Generator/Program.cs
+++ Discriminated.Generator/Program.cs
@@ -6,9 +6,7 @@
 using System.IO;
 using System.Text.RegularExpressions;
 using System.Linq;
-using System.Collections.Generic;
 using System;
-using System.Text;

 namespace Discriminated.Generator
 {
@@ -21,16 +19,16 @@
             var sourceDirPath = args[0];
             var sourceFilePath = Path.Combine(sourceDirPath, "Union.cs");

-            var numOfImplementedCases = NumOfImplementedCases(ReadSource(sourceFilePath));
+            var numOfImplementedCases = NumOfTypeParameters(ReadSource(sourceFilePath));
             for (int currMaxCase = numOfImplementedCases-1; currMaxCase >= 2; currMaxCase--)
             {
                 WriteGeneratedClassToFile(
-                    DropExtraCasesFromSource(currMaxCase, numOfImplementedCases, ReadSource(sourceFilePath)),
+                    RemoveExtraTypeParameters(currMaxCase, numOfImplementedCases, ReadSource(sourceFilePath)),
                     Path.Combine(sourceDirPath, string.Format("Union{0}.generated.cs", currMaxCase)));
             }
         }

-        static int NumOfImplementedCases(string source)
+        static int NumOfTypeParameters(string source)
         {
             return Regex.Matches(source, "T\\d+")
                 .Cast<Match>().ToList()
@@ -49,9 +47,9 @@
             File.WriteAllText(filename, content);
         }

-        static string DropExtraCasesFromSource(int maxCaseToLeave, int maxCaseToRemove, string source)
+        static string RemoveExtraTypeParameters(int maxCaseToLeave, int maxCaseToRemove, string source)
         {
-            string linesToDropComma = string.Format("T{0}", maxCaseToLeave);
+            var linesToTrimComma = new[] { string.Format("T{0}", maxCaseToLeave) };

             var linesToRemove = Enumerable
                 .Range(maxCaseToLeave + 1, maxCaseToRemove - maxCaseToLeave)
@@ -59,11 +57,12 @@
                 .SelectMany(x => x).ToList();

             return string.Join(Environment.NewLine,
-                source.Split(new[] { '\r', '\n' })
+                source
+                .Split(new[] { '\r', '\n' })
                 .ToList()
                 .Select(sourceLine => {
-                    if (linesToRemove.Any(p => Regex.IsMatch(sourceLine, p))) return string.Empty;
-                    if (Regex.IsMatch(sourceLine, linesToDropComma)) return sourceLine.TrimEnd(',');
+                    if (linesToRemove.Any(pattern => Regex.IsMatch(sourceLine, pattern))) return string.Empty;
+                    if (linesToTrimComma.Any(pattern => Regex.IsMatch(sourceLine, pattern))) return sourceLine.TrimEnd(',');
                     return sourceLine;
                 }));
         }


Ramping up iterations, to catch the lock case

The code is getting stuck at WaitHandle.WaitAny on
ManualResetEventSlim.net35.cs line 422

--- Tests/System/Threading/Tasks/TaskTest.cs
+++ Tests/System/Threading/Tasks/TaskTest.cs
@@ -318,7 +318,7 @@
                 Task.WaitAll(tasks);
                 Assert.AreEqual(max, achieved, "#1");
             };
-            ParallelTestHelper.Repeat(action, 200);
+            ParallelTestHelper.Repeat(action, 100000);
         }

         [Test]


.userpresnce no longer delted, use .clr if you want to clear

--- NadekoBot/Commands/LogCommand.cs
+++ NadekoBot/Commands/LogCommand.cs
@@ -88,9 +88,7 @@
                 Channel ch;
                 if (loggingPresences.TryGetValue(e.Server, out ch))
                     if (e.Before.Status != e.After.Status) {
-                        var msg = await ch.SendMessage($"**{e.Before.Name}** is now **{e.After.Status}**.");
-                        await Task.Delay(4000);
-                        await msg.Delete();
+                        await ch.SendMessage($"**{e.Before.Name}** is now **{e.After.Status}**.");
                     }
             } catch { }


Promote test case for null arguments

Promote test case for null arguments

--- Tests/UnitTests/ContextExtensionTests.cs
+++ Tests/UnitTests/ContextExtensionTests.cs
@@ -17,6 +17,7 @@
             _testMessage.Context.Promote(new ContextProperty("http://testuri.org#SourceProperty"), "Value");
         }

+        #region TryRead
         [TestMethod]
         public void TryReadValidTest()
         {
@@ -42,14 +43,137 @@

             _testMessage.Context.TryRead(null, out val);
         }
+        #endregion

+        #region Promote
         [TestMethod]
         public void PromoteValidTest()
         {
-            _testMessage.Context.Promote(new ContextProperty("http://testuri.org#TestProperty"),"Value");
+            _testMessage.Context.Promote(new ContextProperty("http://testuri.org#TestProperty"), "Value");

             Assert.IsTrue(_testMessage.Context.IsPromoted(new ContextProperty("http://testuri.org#TestProperty")));
             Assert.AreEqual("Value", _testMessage.Context.Read(new ContextProperty("http://testuri.org#TestProperty")));
         }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void PromoteInvalidArgumentTest()
+        {
+            _testMessage.Context.Promote(null, "Value");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void PromoteInvalidArgumentValueTest()
+        {
+            _testMessage.Context.Promote(new ContextProperty("http://testuri.org#TestProperty"), null);
+        }
+        #endregion
+
+        #region Write
+        [TestMethod]
+        public void WriteValidTest()
+        {
+            _testMessage.Context.Write(new ContextProperty("http://testuri.org#TestProperty"), "Value");
+
+            Assert.IsFalse(_testMessage.Context.IsPromoted(new ContextProperty("http://testuri.org#TestProperty")));
+            Assert.AreEqual("Value", _testMessage.Context.Read(new ContextProperty("http://testuri.org#TestProperty")));
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void WriteInvalidArgumentTest()
+        {
+            _testMessage.Context.Write(null, "Value");
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void WriteInvalidArgumentValueTest()
+        {
+            _testMessage.Context.Write(new ContextProperty("http://testuri.org#TestProperty"), null);
+        }
+
+        #endregion
+
+        #region Copy
+        [TestMethod]
+        public void CopyValidTest()
+        {
+            _testMessage.Context.Copy(new ContextProperty("http://testuri.org#SourceProperty"), new ContextProperty("http://testuri.org#DestinationProperty"));
+            object val;
+
+            Assert.IsTrue(_testMessage.Context.TryRead(new ContextProperty("http://testuri.org#DestinationProperty"), out val));
+            Assert.AreEqual("Value", val);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(InvalidOperationException))]
+        public void CopyNonExistingTest()
+        {
+            _testMessage.Context.Copy(new ContextProperty("http://testuri.org#NonExisting"), new ContextProperty("http://testuri.org#DestinationProperty"));
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void CopyNullSourcePropertyTest()
+        {
+            _testMessage.Context.Copy(null, new ContextProperty("http://testuri.org#DestinationProperty"));
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void CopyNullDestinationPropertyTest()
+        {
+            _testMessage.Context.Copy(new ContextProperty("http://testuri.org#NonExisting"), null);
+        }
+        #endregion
+
+        #region IsPromoted
+        [TestMethod]
+        public void IsPromotedTrueValidTest()
+        {
+            Assert.IsTrue(_testMessage.Context.IsPromoted(new ContextProperty("http://testuri.org#SourceProperty")));
+        }
+
+        [TestMethod]
+        public void IsPromotedFalseValidTest()
+        {
+            Assert.IsFalse(_testMessage.Context.IsPromoted(new ContextProperty("http://testuri.org#OtherProperty")));
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void IsPromotedInvalidArgumentTest()
+        {
+            _testMessage.Context.IsPromoted(null);
+        }
+        #endregion
+
+        #region Read
+        [TestMethod]
+        public void ReadExistingValidTest()
+        {
+            object val  = _testMessage.Context.Read(new ContextProperty("http://testuri.org#SourceProperty"));
+
+            Assert.AreEqual("Value", val);
+        }
+
+        [TestMethod]
+        public void ReadNonExistingValidTest()
+        {
+            object val = _testMessage.Context.Read(new ContextProperty("http://testuri.org#NonExisting"));
+
+            Assert.IsNull(val);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void ReadInvalidArgumentTest()
+        {
+            _testMessage.Context.Read(null);
+        }
+
+        #endregion
     }
 }


added channel unblacklist, server not coming, closes #113

--- NadekoBot/Modules/Permissions.cs
+++ NadekoBot/Modules/Permissions.cs
@@ -455,27 +455,22 @@
                     });

                 cgb.CreateCommand(Prefix + "uubl")
-               .Alias(Prefix + "unblacklist")
-               .Description($"Unblacklists a mentioned user.\n**Usage**: {Prefix}uubl [user_mention]")
-               .Parameter("user", ParameterType.Unparsed)
-               .AddCheck(SimpleCheckers.OwnerOnly())
-               .Do(async e =>
-               {
-                   await Task.Run(async () => {
-                       if (!e.Message.MentionedUsers.Any()) return;
-                       var usr = e.Message.MentionedUsers.First();
-                       if (NadekoBot.Config.UserBlacklist.Contains(usr.Id))
-                       {
-                           NadekoBot.Config.UserBlacklist.Remove(usr.Id);
-                           ConfigHandler.SaveConfig();
-                           await e.Channel.SendMessage($"`Sucessfully unblacklisted user {usr.Name}`");
-                       }
-                       else
-                       {
-                           await e.Channel.SendMessage($"`{usr.Name} was not in blacklist`");
-                       }
+                   .Description($"Unblacklists a mentioned user.\n**Usage**: {Prefix}uubl [user_mention]")
+                   .Parameter("user", ParameterType.Unparsed)
+                   .AddCheck(SimpleCheckers.OwnerOnly())
+                   .Do(async e => {
+                       await Task.Run(async () => {
+                           if (!e.Message.MentionedUsers.Any()) return;
+                           var usr = e.Message.MentionedUsers.First();
+                           if (NadekoBot.Config.UserBlacklist.Contains(usr.Id)) {
+                               NadekoBot.Config.UserBlacklist.Remove(usr.Id);
+                               ConfigHandler.SaveConfig();
+                               await e.Channel.SendMessage($"`Sucessfully unblacklisted user {usr.Name}`");
+                           } else {
+                               await e.Channel.SendMessage($"`{usr.Name} was not in blacklist`");
+                           }
+                       });
                    });
-               });

                 cgb.CreateCommand(Prefix + "cbl")
                     .Description("Blacklists a mentioned channel (#general for example).\n**Usage**: ;ubl [channel_mention]")
@@ -485,6 +480,19 @@
                             if (!e.Message.MentionedChannels.Any()) return;
                             var ch = e.Message.MentionedChannels.First();
                             NadekoBot.Config.UserBlacklist.Add(ch.Id);
+                            ConfigHandler.SaveConfig();
+                            await e.Channel.SendMessage($"`Sucessfully blacklisted channel {ch.Name}`");
+                        });
+                    });
+
+                cgb.CreateCommand(Prefix + "cubl")
+                    .Description("Unblacklists a mentioned channel (#general for example).\n**Usage**: ;cubl [channel_mention]")
+                    .Parameter("channel", ParameterType.Unparsed)
+                    .Do(async e => {
+                        await Task.Run(async () => {
+                            if (!e.Message.MentionedChannels.Any()) return;
+                            var ch = e.Message.MentionedChannels.First();
+                            NadekoBot.Config.UserBlacklist.Remove(ch.Id);
                             ConfigHandler.SaveConfig();
                             await e.Channel.SendMessage($"`Sucessfully blacklisted channel {ch.Name}`");
                         });


Change TcipipClient not to close at game finish. Each agent can play games continuously after a game.

--- AIWolfLibCommon/Net/TcpipClient.cs
+++ AIWolfLibCommon/Net/TcpipClient.cs
@@ -32,6 +32,7 @@
         {
             this.host = host;
             this.port = port;
+            isRunning = false;
         }

         public TcpipClient(string host, int port, Role? requestRole)
@@ -39,6 +40,7 @@
             this.host = host;
             this.port = port;
             this.requestRole = requestRole;
+            isRunning = false;
         }

         public bool Connect(IPlayer player)
@@ -70,8 +72,7 @@
                 StreamReader sr = new StreamReader(tcpClient.GetStream());
                 StreamWriter sw = new StreamWriter(tcpClient.GetStream());
                 string line;
-                isRunning = true;
-                while ((line = sr.ReadLine()) != null && isRunning)
+                while ((line = sr.ReadLine()) != null)
                 {
                     Packet packet = DataConverter.GetInstance().ToPacket(line);

@@ -93,18 +94,16 @@
                         sw.Flush();
                     }
                 }
-                Console.WriteLine("Close connection of " + player);
-                sr.Close();
-                sw.Close();
-                tcpClient.Close();
             }
             catch (Exception)
             {
-                throw new AIWolfRuntimeException();
+                if (isRunning)
+                {
+                    throw new AIWolfRuntimeException();
+                }
             }
             finally
             {
-                isRunning = false;
             }
         }

@@ -155,6 +154,7 @@
             switch (packet.Request)
             {
                 case Request.INITIALIZE:
+                    isRunning = true;
                     player.Initialize(gameInfo, gameSetting);
                     break;
                 case Request.DAILY_INITIALIZE:
@@ -166,6 +166,10 @@
                     break;
                 case Request.NAME:
                     returnObject = player.Name;
+                    if (returnObject == null)
+                    {
+                        returnObject = player.GetType().Name;
+                    }
                     break;
                 case Request.ROLE:
                     if (requestRole != null)
@@ -244,8 +248,8 @@

         public void Finish()
         {
+            player.Finish();
             isRunning = false;
-            player.Finish();
         }
     }
 }


Check if `sharedParamsFileName` doesn't exist #3

--- TraverseAllSystems/SharedParameterMgr.cs
+++ TraverseAllSystems/SharedParameterMgr.cs
@@ -80,7 +80,8 @@
         = app.SharedParametersFilename;

       if( null == sharedParamsFileName
-        || 0 == sharedParamsFileName.Length )
+        || 0 == sharedParamsFileName.Length
+        || !File.Exists(sharedParamsFileName) )
       {
         string path = Path.GetTempPath();


Update LogLevel for DebugLogger

Update LogLevel for DebugLogger

--- TriggerSol.JStore.Shared/Bootstrapper.cs
+++ TriggerSol.JStore.Shared/Bootstrapper.cs
@@ -10,7 +10,7 @@
     {
         public Bootstrapper()
         {
-            RegisterLogger(new DebugLogger { Level = LogLevel.OnlyException });
+            RegisterLogger(new DebugLogger { Level = LogLevel.Detailed });
         }

         public void InitDataStore<T>(string dataStorePath) where T: IDataStore, new()


Do not raise OnItemChanged() if legend text not changed

--- Trunk/DotSpatial.Symbology/LegendItem.cs
+++ Trunk/DotSpatial.Symbology/LegendItem.cs
@@ -435,6 +435,7 @@
             }
             set
             {
+                if (value == _legendText) return;
                 _legendText = value;
                 OnItemChanged(this);
             }


adding copyright info to assemblyinfo.cs

--- Tst/UnitTests/Properties/AssemblyInfo.cs
+++ Tst/UnitTests/Properties/AssemblyInfo.cs
@@ -8,9 +8,9 @@
 [assembly: AssemblyTitle("UnitTests")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
+[assembly: AssemblyCompany("Microsoft")]
 [assembly: AssemblyProduct("UnitTests")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2017")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]


mainline: use AppDomain root to locate the logs directory

--- mainline/Common/LogUtil.cs
+++ mainline/Common/LogUtil.cs
@@ -17,6 +17,9 @@

         public static void Setup(string log4netConfig)
         {
+            if (!Path.IsPathRooted(log4netConfig))
+                log4netConfig = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, log4netConfig);
+
             XmlConfigurator.Configure(new FileInfo(log4netConfig));
             m_logger = new Log4NetLogger();
         }


Removing tech debt.

Removing tech debt.

--- ARGame/Assets/Scripts/Vision/MetaLink.cs
+++ ARGame/Assets/Scripts/Vision/MetaLink.cs
@@ -60,7 +60,7 @@

             if (MarkerDetector.Instance == null)
             {
-                throw new MissingComponentException("Missing MarkerDetector instance");
+                throw new MissingComponentException("Missing marker detector instance");
             }
         }


Restored ScreenManager unloading

Restored ScreenManager unloading

--- DromundKaasII/DromundKaas/Game1.cs
+++ DromundKaasII/DromundKaas/Game1.cs
@@ -61,7 +61,7 @@
         /// </summary>
         protected override void UnloadContent()
         {
-            //ScreenManager.Instance.UnloadContent();
+            ScreenManager.Instance.UnloadContent();
             //engineTask.Dispose();
         }


Add test for normalizing DateTimes.

Add test for normalizing DateTimes.

--- Duplicati/UnitTest/UtilityTests.cs
+++ Duplicati/UnitTest/UtilityTests.cs
@@ -202,6 +202,19 @@

         [Test]
         [Category("Utility")]
+        public void NormalizeDateTime()
+        {
+            DateTime baseDateTime = new DateTime(2000, 1, 2, 3, 4, 5);
+            DateTime baseDateTimeUTC = baseDateTime.ToUniversalTime();
+            Assert.AreEqual(baseDateTimeUTC, Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(1)));
+            Assert.AreEqual(baseDateTimeUTC, Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(500)));
+            Assert.AreEqual(baseDateTimeUTC, Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(999)));
+            Assert.AreEqual(baseDateTimeUTC.AddSeconds(-1), Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(-1)));
+            Assert.AreEqual(baseDateTimeUTC.AddSeconds(1), Utility.NormalizeDateTime(baseDateTime.AddSeconds(1.9)));
+        }
+
+        [Test]
+        [Category("Utility")]
         public void ParseBool()
         {
             string[] expectTrue = { "1", "on", "true", "yes" };


Split up large example

Split up large example

--- ApiExamples/CSharp/ApiExamples/ExFont.cs
+++ ApiExamples/CSharp/ApiExamples/ExFont.cs
@@ -1373,7 +1373,7 @@
             //ExFor:Fonts.DefaultFontSubstitutionRule
             //ExFor:Fonts.DefaultFontSubstitutionRule.DefaultFontName
             //ExFor:Fonts.FontSubstitutionSettings.DefaultFontSubstitution
-            //ExSummary:Shows how to with the default font substitution rule.
+            //ExSummary:Shows how to set the default font substitution rule.
             // Create a blank document and a new FontSettings property
             Document doc = new Document();
             FontSettings fontSettings = new FontSettings();
@@ -1409,7 +1409,7 @@
             //ExFor:Fonts.FontSubstitutionRule
             //ExFor:Fonts.FontSubstitutionRule.Enabled
             //ExFor:Fonts.FontSubstitutionSettings.FontConfigSubstitution
-            //ExSummary:Shows OS-dependent font substitution rules.
+            //ExSummary:Shows OS-dependent font config substitution.
             // Create a new FontSettings object and get its font config substitution rule
             FontSettings fontSettings = new FontSettings();
             FontConfigSubstitutionRule fontConfigSubstitution = fontSettings.SubstitutionSettings.FontConfigSubstitution;
@@ -1442,12 +1442,9 @@
         public void FallbackSettings()
         {
             //ExStart
-            //ExFor:Fonts.FontSettings.FallbackSettings
-            //ExFor:Fonts.FontFallbackSettings
-            //ExFor:Fonts.FontFallbackSettings.BuildAutomatic
             //ExFor:Fonts.FontFallbackSettings.LoadMsOfficeFallbackSettings
             //ExFor:Fonts.FontFallbackSettings.LoadNotoFallbackSettings
-            //ExSummary:Shows how to distribute fallback fonts across unicode character code ranges.
+            //ExSummary:Shows how to load pre-defined fallback font settings.
             Document doc = new Document();

             // Create a FontSettings object for our document and get its FallbackSettings attribute
@@ -1455,37 +1452,48 @@
             doc.FontSettings = fontSettings;
             FontFallbackSettings fontFallbackSettings = fontSettings.FallbackSettings;

-            // There are many unicode blocks, usually for different languages/symbol sets, each with many codes for their glyphs,
-            // The vast majority of fonts, while providing us with all the required english characters, cannot cover all other unicode blocks
-            // To make sure that as many unicode character values as possible are represented by glyphs, we can use fallback font schemes that designate fonts to
-            // "patch up" gaps in unicode block representation
-            // By default, we are provided with a robust scheme of ~40 fallback fonts, which can be saved for viewing in the form of an XML document, as we do below
+            // Save the default fallback font scheme in an XML document
+            // For example, one of the elements has a value of "0C00-0C7F" for Range and a corresponding "Vani" value for FallbackFonts
+            // This means that if the font we are using does not have symbols for the 0x0C00-0x0C7F unicode block,
+            // the symbols from the "Vani" font will be used as a substitute
             fontFallbackSettings.Save(ArtifactsDir + "Font.FallbackSettings.Default.xml");

-            // Each element in this document has a "Ranges" attribute, which specifies a range of unicode codes,
-            // and a "FallbackFonts" attribute, which designates a font that governs that range
-            // In this instance, the "Mongolian Baiti" font covers the "1800-18FF" range
-            // This means that if the font that we are using does not have glyphs within the "1800-18FF" unicode block, and we insert characters from within that range,
-            // we will fall back to the "Mongolian Baiti" font to make sure we get proper text and not rectangles
-
-            // Aside from the default fallback font scheme, there are 4 others we can choose from
-            // 1: Use the default Microsoft Office scheme, which is the same one as the default that Aspose uses
+            // There are two pre-defined font fallback schemes we can choose from
+            // 1: Use the default Microsoft Office scheme, which is the same one as the default
             fontFallbackSettings.LoadMsOfficeFallbackSettings();
             fontFallbackSettings.Save(ArtifactsDir + "Font.FallbackSettings.LoadMsOfficeFallbackSettings.xml");

             // 2: Use the scheme built from Google Noto fonts
             fontFallbackSettings.LoadNotoFallbackSettings();
             fontFallbackSettings.Save(ArtifactsDir + "Font.FallbackSettings.LoadNotoFallbackSettings.xml");
-
-            // 3: Set the fonts to come exclusively from a local folder
-            // Then, automatically generate a scheme that attempts to cover as many Unicode codes with fonts as possible
+            //ExEnd
+        }
+
+        [Test]
+        public void FallbackSettingsCustom()
+        {
+            //ExStart
+            //ExFor:Fonts.FontSettings.FallbackSettings
+            //ExFor:Fonts.FontFallbackSettings
+            //ExFor:Fonts.FontFallbackSettings.BuildAutomatic
+            //ExSummary:Shows how to distribute fallback fonts across unicode character code ranges.
+            Document doc = new Document();
+
+            // Create a FontSettings object for our document and get its FallbackSettings attribute
+            FontSettings fontSettings = new FontSettings();
+            doc.FontSettings = fontSettings;
+            FontFallbackSettings fontFallbackSettings = fontSettings.FallbackSettings;
+
+            // Set our fonts to be sourced exclusively from the "MyFonts" folder
             FolderFontSource folderFontSource = new FolderFontSource(MyDir + @"\MyFonts", false);
             fontSettings.SetFontsSources(new FontSourceBase[] { folderFontSource });

+            // Calling BuildAutomatic() will generate a fallback scheme that distributes accessible fonts across as many unicode character codes as possible
+            // In our case, it only has access to the handful of fonts inside the "MyFonts" folder
             fontFallbackSettings.BuildAutomatic();
             fontFallbackSettings.Save(ArtifactsDir + "Font.FontFallbackSettings.BuildAutomatic.xml");

-            // 4: Take a scheme from a local file
+            // We can also load a custom substitution scheme from a file like this
             // This scheme applies the "Arvo" font across the "0000-00ff" unicode blocks, the "Squarish Sans CT" font across "0100-024f",
             // and the "M+ 2m" font in every place that none of the other fonts cover
             fontFallbackSettings.Load(MyDir + "Font.FallbackSettings.Custom.xml");
@@ -1522,18 +1530,51 @@
         public void TableSubstitutionRule()
         {
             //ExStart
+            //ExFor:Fonts.TableSubstitutionRule
+            //ExFor:Fonts.TableSubstitutionRule.LoadLinuxSettings
+            //ExFor:Fonts.TableSubstitutionRule.LoadWindowsSettings
+            //ExFor:Fonts.TableSubstitutionRule.Save(System.IO.Stream)
+            //ExFor:Fonts.TableSubstitutionRule.Save(System.String)
+            //ExSummary:Shows how to access font substitution tables for Windows and Linux.
+            // Create a blank document and a new FontSettings object
+            Document doc = new Document();
+            FontSettings fontSettings = new FontSettings();
+            doc.FontSettings = fontSettings;
+
+            // Create a new table substitution rule and load the default Windows font substitution table
+            TableSubstitutionRule tableSubstitutionRule = fontSettings.SubstitutionSettings.TableSubstitution;
+            tableSubstitutionRule.LoadWindowsSettings();
+
+            // In Windows, the default substitute for the "Times New Roman CE" font is "Times New Roman"
+            Assert.AreEqual(new[] { "Times New Roman" }, tableSubstitutionRule.GetSubstitutes("Times New Roman CE").ToArray());
+
+            // We can save the table for viewing in the form of an XML document
+            tableSubstitutionRule.Save(ArtifactsDir + "Font.TableSubstitutionRule.Windows.xml");
+
+            // Linux has its own substitution table
+            // If "FreeSerif" is unavailable to substitute for "Times New Roman CE", we then look for "Liberation Serif", and so on
+            tableSubstitutionRule.LoadLinuxSettings();
+            Assert.AreEqual(new[] { "FreeSerif", "Liberation Serif", "DejaVu Serif" }, tableSubstitutionRule.GetSubstitutes("Times New Roman CE").ToArray());
+
+            // Save the Linux substitution table using a stream
+            using (FileStream fileStream = new FileStream(ArtifactsDir + "Font.TableSubstitutionRule.Linux.xml", FileMode.Create))
+            {
+                tableSubstitutionRule.Save(fileStream);
+            }
+            //ExEnd
+        }
+
+        [Test]
+        public void TableSubstitutionRuleCustom()
+        {
+            //ExStart
             //ExFor:Fonts.FontSubstitutionSettings.TableSubstitution
-            //ExFor:Fonts.TableSubstitutionRule
             //ExFor:Fonts.TableSubstitutionRule.AddSubstitutes(System.String,System.String[])
             //ExFor:Fonts.TableSubstitutionRule.GetSubstitutes(System.String)
             //ExFor:Fonts.TableSubstitutionRule.Load(System.IO.Stream)
             //ExFor:Fonts.TableSubstitutionRule.Load(System.String)
-            //ExFor:Fonts.TableSubstitutionRule.LoadLinuxSettings
-            //ExFor:Fonts.TableSubstitutionRule.LoadWindowsSettings
-            //ExFor:Fonts.TableSubstitutionRule.Save(System.IO.Stream)
-            //ExFor:Fonts.TableSubstitutionRule.Save(System.String)
             //ExFor:Fonts.TableSubstitutionRule.SetSubstitutes(System.String,System.String[])
-            //ExSummary:Shows how to substitute fonts.
+            //ExSummary:Shows how to work with custom font substitution tables.
             // Create a blank document and a new FontSettings object
             Document doc = new Document();
             FontSettings fontSettings = new FontSettings();
@@ -1541,21 +1582,6 @@

             // Create a new table substitution rule and load the default Windows font substitution table
             TableSubstitutionRule tableSubstitutionRule = fontSettings.SubstitutionSettings.TableSubstitution;
-            tableSubstitutionRule.LoadWindowsSettings();
-
-            // In Windows, the default substitute for the "Times New Roman CE" font is "Times New Roman"
-            Assert.AreEqual(new[] { "Times New Roman" }, tableSubstitutionRule.GetSubstitutes("Times New Roman CE").ToArray());
-
-            // We can save the table for viewing in the form of an XML document
-            tableSubstitutionRule.Save(ArtifactsDir + "Font.TableSubstitutionRule.Windows.xml");
-
-            // Linux has its own substitution table
-            // If "FreeSerif" is unavailable to substitute for "Times New Roman CE", we then look for "Liberation Serif", and so on
-            tableSubstitutionRule.LoadLinuxSettings();
-            Assert.AreEqual(new[] { "FreeSerif", "Liberation Serif", "DejaVu Serif" }, tableSubstitutionRule.GetSubstitutes("Times New Roman CE").ToArray());
-
-            // Save the Linux substitution table
-            tableSubstitutionRule.Save(ArtifactsDir + "Font.TableSubstitutionRule.Linux.xml");

             // If we select fonts exclusively from our own folder, we will need a custom substitution table
             FolderFontSource folderFontSource = new FolderFontSource(MyDir + @"\MyFonts", false);


[version-checker] fix cocoapods github auth

--- Util/VersionChecker/common/CocoaPods.csx
+++ Util/VersionChecker/common/CocoaPods.csx
@@ -14,6 +14,9 @@

     public override string FetchNewestAvailableVersion ()
     {
+        var githubClientId = System.Environment.GetEnvironmentVariable ("GITHUB_CLIENT_ID");
+        var githubClientSecret = System.Environment.GetEnvironmentVariable ("GITHUB_CLIENT_SECRET");
+
         // CocoaPods moved to using a folder prefix in their Specs repo in order to avoid
         // having all the specs in a single directory
         // The formula is the first 3 chars of the md5 value of the Pod ID
@@ -31,14 +34,12 @@
         http.DefaultRequestHeaders.UserAgent.ParseAdd ("Xamarin-Internal/1.0");

         var tree = string.Format ("master:Specs/{0}", podIdPath);
-
-        //Console.WriteLine ("https://api.github.com/repos/{0}/{1}/git/trees/{2}", "CocoaPods", "Specs", tree);

         var url = string.Format ("https://api.github.com/repos/{0}/{1}/git/trees/{2}", "CocoaPods", "Specs", System.Net.WebUtility.UrlEncode (tree));

         if (!string.IsNullOrEmpty (githubClientId) && !string.IsNullOrEmpty (githubClientSecret))
             url += "?client_id=" + githubClientId + "&client_secret=" + githubClientSecret;
-
+
         var data = http.GetStringAsync (url).Result;

         var json = JObject.Parse (data);


Outcome<TObservation>: Simplified implementation of InformMany...

--- Application/iSynaptic.Commons/Outcome.cs
+++ Application/iSynaptic.Commons/Outcome.cs
@@ -145,16 +145,11 @@
             var self = @this;
             return new Outcome<U>(() =>
             {
-                var outcome = self.Observations
+                var outcomes = self.Observations
                     .Select(selector)
-                    .Aggregate(
-                    new { Success = true, Observations = Enumerable.Empty<U>() }, (ag, obs) => new
-                    {
-                        Success = ag.Success && obs.WasSuccessful,
-                        Observations = ag.Observations.Concat(obs.Observations)
-                    });
-
-                return new Outcome<U>(outcome.Success, outcome.Observations);
+                    .ToArray();
+
+                return new Outcome<U>(outcomes.All(x => x.WasSuccessful), outcomes.SelectMany(x => x.Observations));
             });
         }


Remove ApplicationClosed event from ApplicationController

--- ApplicationView/ApplicationController.cs
+++ ApplicationView/ApplicationController.cs
@@ -266,8 +266,6 @@

 		public ApplicationView MainView;

-		public event EventHandler ApplicationClosed;
-
 		private EventHandler unregisterEvents;

 		private Dictionary<string, List<PrintItemAction>> registeredLibraryActions = new Dictionary<string, List<PrintItemAction>>();
@@ -504,16 +502,7 @@
 					UiThread.RunOnIdle(ReloadAll);
 				}
 			}, ref unregisterEvents);
-
-			// Remove consumed ClientToken from running list on shutdown
-			ApplicationClosed += (s, e) =>
-			{
-				ApplicationSettings.Instance.ReleaseClientToken();
-
-				// Release the waiting ThumbnailGeneration task so it can shutdown gracefully
-				thumbGenResetEvent?.Set();
-			};
-
+
 			PrinterConnection.ErrorReported.RegisterEvent((s, e) =>
 			{
 				var foundStringEventArgs = e as FoundStringEventArgs;
@@ -716,6 +705,9 @@

 		public void OnApplicationClosed()
 		{
+			// Release the waiting ThumbnailGeneration task so it can shutdown gracefully
+			thumbGenResetEvent?.Set();
+
 			// Save changes before close
 			if (this.ActivePrinter != null
 				&& this.ActivePrinter != emptyPrinter)
@@ -723,7 +715,7 @@
 				this.ActivePrinter.Bed.Save();
 			}

-			ApplicationClosed?.Invoke(null, null);
+			ApplicationSettings.Instance.ReleaseClientToken();
 		}

 		static void LoadOemOrDefaultTheme()


add if UNITY_EDITOR

add if UNITY_EDITOR

--- Assets/Plugins/AU/Editor/ShowInEditor.cs
+++ Assets/Plugins/AU/Editor/ShowInEditor.cs
@@ -6,11 +6,16 @@
 //

 using UnityEngine;
-using UnityEditor;
 using System.Collections;
 using System.Reflection;
 using System.Collections.Generic;
 using System.Linq;
+
+#if UNITY_EDITOR
+
+using UnityEditor;
+
+#endif

 namespace AU
 {
@@ -163,6 +168,8 @@

     }

+#if UNITY_EDITOR
+
     public static class EditorHelper
     {
         public abstract class MemberField
@@ -201,7 +208,7 @@
             {
                 get
                 {
-                    if (_attribute.Range == null && _attribute.RangeMin != _attribute.RangeMax)
+                    if(_attribute.Range == null && _attribute.RangeMin != _attribute.RangeMax)
                         _attribute.Range = new ShowInEditorRange(_attribute.RangeMin, _attribute.RangeMax);
                     return _attribute.Range;
                 }
@@ -614,7 +621,7 @@

                 case SerializedPropertyType.Float:
                     return DrawFloatField(name, value, sysType, range, style);
-
+
                 case SerializedPropertyType.Boolean:
                     return EditorGUILayout.Toggle(name, (bool)value);

@@ -682,7 +689,7 @@

                 case SerializedPropertyType.Float:
                     return DrawFloatField("", value, sysType, range, style);
-
+
                 case SerializedPropertyType.Boolean:
                     // for some reason, editor gui layout doesn't work here
                     return GUILayout.Toggle((bool)value, new GUIContent(""), new GUILayoutOption[] { GUILayout.Width(24) });
@@ -720,7 +727,7 @@
                         for (int i = 0; i < arr.Count; ++i)
                         {
                             System.Object v = arr[i];
-                            if (v != null)
+                            if(v != null)
                                 EditorGUILayout.LabelField(string.Format("[{0}]", i), arr[i].ToString());
                             else
                                 EditorGUILayout.LabelField(string.Format("[{0}]", i), "(null)");
@@ -875,7 +882,7 @@
                     {
                         field.BindRefernecedObject(arr[i]);
                         DrawObjectReference(arr[i], field.Members, defaultColor);
-                    }
+                     }
                 }
                 else
                 {
@@ -925,7 +932,7 @@
             {
                 DrawArrayField((ArrayFieldField)field);
             }
-            else if (field is ButtonGroupField)
+            else if(field is ButtonGroupField)
             {
                 DrawButtonGroup((ButtonGroupField)field);
             }
@@ -1002,7 +1009,7 @@
                             realType = field.FieldType.GetElementType();

                         bool isObjectRef = !FieldField.IsReadOnly(attribute, field);
-
+
                         isObjectRef &= (realType.IsClass ||
                                         (realType.IsValueType && !realType.IsEnum && !realType.IsPrimitive));

@@ -1141,5 +1148,7 @@
         }

     }
-
+
+#endif
 }
+


Add list command to enumerate IDX content

--- OpenKh.Command.IdxImg/Program.cs
+++ OpenKh.Command.IdxImg/Program.cs
@@ -5,12 +5,13 @@
 using System.IO;
 using System.Reflection;
 using System.ComponentModel.DataAnnotations;
+using System.Linq;

 namespace OpenKh.Command.IdxImg
 {
     [Command("OpenKh.Command.IdxImg")]
     [VersionOptionFromMember("--version", MemberName = nameof(GetVersion))]
-    [Subcommand(typeof(ExtractCommand))]
+    [Subcommand(typeof(ExtractCommand), typeof(ListCommand))]
     class Program
     {
         static int Main(string[] args)
@@ -119,6 +120,61 @@
             }
         }

+        private class ListCommand
+        {
+            private Program Parent { get; set; }
+
+            [Required]
+            [FileExists]
+            [Option(CommandOptionType.SingleValue, Description = "Kingdom Hearts II IDX file, paired with a IMG", ShortName = "i", LongName = "idx")]
+            public string InputIdx { get; set; }
+
+            [Option(CommandOptionType.NoValue, Description = "Sort file list by their position in the IMG", ShortName = "s", LongName = "sort")]
+            public bool Sort { get; set; }
+
+            protected int OnExecute(CommandLineApplication app)
+            {
+                var entries = OpenIdx(InputIdx).GetNameEntries();
+                if (Sort)
+                    entries = entries.OrderBy(x => x.Entry.Offset);
+
+                foreach (var entry in entries)
+                    Console.WriteLine(entry.Name);
+
+                return 0;
+            }
+
+            public static List<string> ExtractIdx(Img img, Idx idx, string basePath)
+            {
+                var idxs = new List<string>();
+
+                foreach (var entry in idx.GetNameEntries())
+                {
+                    var fileName = entry.Name;
+                    if (fileName == null)
+                        fileName = $"@noname/{entry.Entry.Hash32:X08}-{entry.Entry.Hash16:X04}";
+
+                    Console.WriteLine(fileName);
+
+                    var outputFile = Path.Combine(basePath, fileName);
+                    var outputDir = Path.GetDirectoryName(outputFile);
+                    if (Directory.Exists(outputDir) == false)
+                        Directory.CreateDirectory(outputDir);
+
+                    using (var file = File.Create(outputFile))
+                    {
+                        // TODO handle decompression
+                        img.FileOpen(entry.Entry).CopyTo(file);
+                    }
+
+                    if (Path.GetExtension(fileName) == ".idx")
+                        idxs.Add(outputFile);
+                }
+
+                return idxs;
+            }
+        }
+
         private static Idx OpenIdx(string fileName)
         {
             using (var idxStream = File.OpenRead(fileName))


Fix typos

Fix typos

--- OptigemLdapSync/NewUserReport.cs
+++ OptigemLdapSync/NewUserReport.cs
@@ -112,8 +112,8 @@
             pdfdoc.Add(table);

             pdfdoc.Add(new Paragraph(this.CreatePhrase("1.) Nach einem Klick rechts oben auf \"Login\" erscheint das Anmeldeformular")));
-            pdfdoc.Add(new Paragraph(this.CreatePhrase("2.) Der o.g.Benutzername kann mit Kleinbuchstaben und Punkt in der Mitte eingegeben werden")));
-            pdfdoc.Add(new Paragraph(this.CreatePhrase("3.) Das per eMail zugeschickte persönliche, geheime Passwort ist einzugeben")));
+            pdfdoc.Add(new Paragraph(this.CreatePhrase("2.) Der o.g. Benutzername kann mit Kleinbuchstaben und Punkt in der Mitte eingegeben werden")));
+            pdfdoc.Add(new Paragraph(this.CreatePhrase("3.) Das per E-Mail zugeschickte persönliche, geheime Passwort ist einzugeben")));
             pdfdoc.Add(new Paragraph(this.CreatePhrase("4.) Klick auf \"Anmelden\" gewährt den Intranetzugang, erkennbar durch den Login-Namen oben rechts")));

             pdfdoc.Add(new Paragraph(this.CreatePhrase("Nachdem der untere Abschnitt dieses Schreibens mit Kenntnisnahme der Datenschutzerklärung unterschrieben im Gemeindebüro (Fach) angekommen ist, wird an die bekannte bzw. noch anzugebende E-Mail-Adresse das Passwort verschickt (bitte vertraulich behandeln).")) { SpacingBefore = MillimetersToPoints(4), Alignment = Element.ALIGN_JUSTIFIED });


The commit that made you play sounds

The commit that made you play sounds

+Added audio source functions to actorcontroller

--- Assets/Scripts/Player/ActorController.cs
+++ Assets/Scripts/Player/ActorController.cs
@@ -13,8 +13,12 @@

 public class ActorController : MonoBehaviour {

+ 	public AudioClip[] audioClips;
+
 	public static ActorController actor;
 	Animator animator;
+
+

 	public bool isControlledLocally;

@@ -251,6 +255,17 @@

 	public void TakeDamage(float damageValue) {
 		Debug.Log("TakeDamage:" + damageValue);
+	}
+
+
+	void PlayOneShotRandom(){
+		AudioClip audio = audioClips[Random.Range(0,audioClips.Length)];
+		GetComponent<AudioSource>().PlayOneShot(audio);
+	}
+
+	void PlayOneShot(string clip){
+		AudioClip audio = Resources.Load<AudioClip>("Sounds/"+clip);
+		GetComponent<AudioSource>().PlayOneShot(audio);
 	}

@@ -436,5 +451,4 @@
 			}
 		}
 	}
-
 }


simplified cors policy

simplified cors policy

--- src/Api/Startup.cs
+++ src/Api/Startup.cs
@@ -122,14 +122,6 @@
             services.AddBaseServices();
             services.AddDefaultServices(globalSettings);

-            // Cors
-            services.AddCors(config =>
-            {
-                config.AddPolicy("All", policy => policy
-                    .AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials()
-                    .SetPreflightMaxAge(TimeSpan.FromDays(1)));
-            });
-
             // MVC
             services.AddMvc(config =>
             {
@@ -197,7 +189,7 @@
             app.UseStaticFiles();

             // Add Cors
-            app.UseCors("All");
+            app.UseCors(policy => policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());

             // Add authentication to the request pipeline.
             app.UseAuthentication();


fix layout

fix layout

--- BTCPayServer/Views/Shared/_Layout.cshtml
+++ BTCPayServer/Views/Shared/_Layout.cshtml
@@ -38,9 +38,9 @@

-                @if (env.ChainType != NBXplorer.ChainType.Main)
+                @if (env.NetworkType != NBitcoin.NetworkType.Mainnet)
                 {
-                    @env.ChainType.ToString()
+                    @env.NetworkType.ToString()
                 }

             <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">


Fix schedule for evals

Fix schedule for evals

--- Battery-Commander.Web/Jobs/JobHandler.cs
+++ Battery-Commander.Web/Jobs/JobHandler.cs
@@ -25,7 +25,7 @@

             registry.Schedule<SqliteBackupJob>().ToRunEvery(1).Days().At(hours: 11, minutes: 0);

-            registry.Schedule<EvaluationDueReminderJob>().ToRunNow();
+            registry.Schedule<EvaluationDueReminderJob>().ToRunEvery(1).Weeks().On(DayOfWeek.Friday).At(hours: 12, minutes: 0);

             JobManager.Initialize(registry);
         }


Add url to get unicorns

Add url to get unicorns

--- Bbl.KnockoutJs/Bbl.KnockoutJs/Startup.cs
+++ Bbl.KnockoutJs/Bbl.KnockoutJs/Startup.cs
@@ -1,4 +1,7 @@
-using Nancy;
+using System.IO;
+using System.Linq;
+using System.Web.Hosting;
+using Nancy;
 using Owin;

 namespace Bbl.KnockoutJs
@@ -13,9 +16,33 @@

     public class IndexModule : NancyModule
     {
+        private const string UnicornsPath = "/Content/Unicorn/";
+
         public IndexModule()
         {
             Get["/"] = parameters => View["index"];
+
+            Get["/api/unicorns"] = parameters =>
+                {
+                    var imagesDirectory = HostingEnvironment.MapPath("~" + UnicornsPath);
+                    return new DirectoryInfo(imagesDirectory)
+                        .EnumerateFiles()
+                        .Select(ConvertToDto);
+                };
+        }
+
+        private dynamic ConvertToDto(FileInfo file)
+        {
+            var name = Path.GetFileNameWithoutExtension(file.Name);
+
+            return new
+                   {
+                       Key = name,
+                       ImagePath = UnicornsPath + file.Name,
+                       Name = name.Replace('_', ' '),
+                       Keywords = name.Split('_'),
+                       CreationDate = file.CreationTime
+                   };
         }
     }
 }


Fixed delete settings path.

Fixed delete settings path.

--- BetterDefaultBrowser/MainWindow2.xaml.cs
+++ BetterDefaultBrowser/MainWindow2.xaml.cs
@@ -103,7 +103,7 @@

         private void deleteSettingsMenuItem_Click(object sender, RoutedEventArgs e)
         {
-            System.IO.Directory.Delete(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\BetterDefaultBrowser", true);
+            System.IO.Directory.Delete(HardcodedValues.DATA_FOLDER, true);
             Application.Current.Shutdown();
         }


made ShellCommandExecutor public

made ShellCommandExecutor public

--- Bounce.Framework/ShellCommandExecutor.cs
+++ Bounce.Framework/ShellCommandExecutor.cs
@@ -4,7 +4,7 @@
 using System.IO;

 namespace Bounce.Framework {
-    class ShellCommandExecutor : IShellCommandExecutor {
+    public class ShellCommandExecutor : IShellCommandExecutor {
         public void ExecuteAndExpectSuccess(string commandName, string commandArgs) {
             var output = Execute(commandName, commandArgs);


Added "GetEmptyCells" function to Board class

--- src/Board/Board.cs
+++ src/Board/Board.cs
@@ -92,7 +92,7 @@
         /// Gets a list of the values which may go here.
         /// </summary>
         /// <param name="Where">The <see cref="Location"/> of the cell to check.</param>
-        /// <returns>A <see cref="List{T}"/> of possible values. We start with a list of digits 1-9, and remove any which are found in the same row, column, or zone.</returns>
+        /// <returns>A <see cref="List{int}"/> of possible values. We start with a list of digits 1-9, and remove any which are found in the same row, column, or zone.</returns>
         public List<int> GetCandidates(Location Where)
         {
             List<int> result = new List<int>();
@@ -114,6 +114,21 @@
             return result;
         }

+        /// <summary>
+        /// Returns a list of <see cref="Location"/>s which are empty. Useful for solving or grading a board.
+        /// </summary>
+        /// <returns>A <see cref="List{Location}"/></returns>
+        public List<Location> GetEmptyCells()
+        {
+            List<Location> result = new List<Location>();
+
+            foreach (Location loc in Location.All)
+                if (this[loc] == 0)
+                    result.Add(loc);
+
+            return result;
+        }
+
         [DataMember]
         private int[] data = new int[81];
         private static int[] ZoneIndices = { 0, 3, 6, 27, 30, 33, 54, 57, 60 };


Added XmlReports, a collection of sales reportn to dealers and removed using in JsRepor class

--- CarsFactory/CarsFactory.Models/Dealer.cs
+++ CarsFactory/CarsFactory.Models/Dealer.cs
@@ -1,19 +1,39 @@
-namespace CarsFactory.Models
-{
-    using System.ComponentModel.DataAnnotations;
-    using System.ComponentModel.DataAnnotations.Schema;
-
-    public class Dealer
-    {
-        [Key]
-        public int Id { get; set; }
-
-        [Required]
-        public string Name { get; set; }
-
-        [ForeignKey("Address")]
-        public int AddressId { get; set; }
-
-        public virtual Address Address { get; set; }
-    }
-}
+namespace CarsFactory.Models
+{
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.ComponentModel.DataAnnotations.Schema;
+
+    public class Dealer
+    {
+        private ICollection<SalesReport> salesReports;
+
+        public Dealer()
+        {
+            this.salesReports = new HashSet<SalesReport>();
+        }
+
+        [Key]
+        public int Id { get; set; }
+
+        [Required]
+        public string Name { get; set; }
+
+        [ForeignKey("Address")]
+        public int AddressId { get; set; }
+
+        public virtual Address Address { get; set; }
+
+        public virtual ICollection<SalesReport> SalesReports
+        {
+            get
+            {
+                return this.salesReports;
+            }
+            set
+            {
+                this.salesReports = value;
+            }
+        }
+    }
+}


Added header content

Added header content

--- ChartJSNet.Sample/Views/SPA/Index.cshtml
+++ ChartJSNet.Sample/Views/SPA/Index.cshtml
@@ -1,5 +1,4 @@
-
-@{
+@{
     ViewBag.Title = "Index";
     Layout = "~/Views/Shared/_SPALayout.cshtml";
 }
@@ -75,7 +74,7 @@

-
Notebook

+
ChartJS.NET Wrapper

                 Nav Menu

@@ -86,27 +85,30 @@

-
Best Ideas Start On Paper

-
Revolvationary notebook with eco-friendly paper,advanced surface technology and degital sharing integration.

-                    Order Now
-

-

-
Best Ideas Start On Paper

-
Revolvationary notebook with eco-friendly paper,advanced surface technology and degital sharing integration.

-                    Order Now
-

-

-
Best Ideas Start On Paper

-
Revolvationary notebook with eco-friendly paper,advanced surface technology and degital sharing integration.

-                    Order Now
-
-

-

-
Best Ideas Start On Paper

-
Revolvationary notebook with eco-friendly paper,advanced surface technology and degital sharing integration.

-                    Order Now
-
-

+
Simple, Clean Wrapper for Chart.js

+

+                        This is a simple to use .NET wrapper for the Chart.js charting library.  It is
+                        written in C# using SOLID principles.
+

+                    @*Order Now*@
+

+                @*

+
Best Ideas Start On Paper

+
Revolvationary notebook with eco-friendly paper,advanced surface technology and degital sharing integration.

+                        Order Now
+

+

+
Best Ideas Start On Paper

+
Revolvationary notebook with eco-friendly paper,advanced surface technology and degital sharing integration.

+                        Order Now
+
+

+

+
Best Ideas Start On Paper

+
Revolvationary notebook with eco-friendly paper,advanced surface technology and degital sharing integration.

+                        Order Now
+
+
*@

@@ -310,7 +312,7 @@

-
+


changed the class to implement an interface to be able to share the code

--- Code/TrackingApp.Droid/StringSettings.cs
+++ Code/TrackingApp.Droid/StringSettings.cs
@@ -9,25 +9,42 @@
 using Android.Runtime;
 using Android.Views;
 using Android.Widget;
+using TrackingApp.Library.Interfaces;

 namespace TrackingApp.Droid
 {
-    public static class StringSettings
+    public class StringSettings : IStringSettings
     {
-        private static IDictionary<string, string> _settings;
+        private static StringSettings _settings;
+        private IDictionary<string, string> _values;

-        public static IDictionary<string, string> Setttings
+        public static IStringSettings Setttings
+        {
+            get
+            {
+                if (_settings == null)
+                {
+                    _settings = new StringSettings();
+                    _settings.LoadSettings();
+                }
+                return _settings;
+            }
+        }
+
+        public string this[string key]
         {
             get
             {
                 if (_settings == null) LoadSettings();
-                return _settings;
+                return _settings[key];
             }
         }

-        public static void LoadSettings()
+
+        public void LoadSettings()
         {
-            _settings = new Dictionary<string, string>()
+
+            _values = new Dictionary<string, string>()
             {
                 {"ApplicationName",  Application.Context.GetString(Resource.String.ApplicationName)},
                 {"Hello",  Application.Context.GetString(Resource.String.Hello)},


update WPF

update WPF

--- WpfWebView/WpfWebView/MainWindow.xaml.cs
+++ WpfWebView/WpfWebView/MainWindow.xaml.cs
@@ -34,7 +34,7 @@
             var options = new OidcClientOptions()
             {
                 Authority = "https://demo.identityserver.io/",
-                ClientId = "native.code",
+                ClientId = "interactive.public",
                 Scope = "openid profile email",
                 RedirectUri = "http://127.0.0.1/sample-wpf-app",
                 Browser = new WpfEmbeddedBrowser()


Added a convenience method Dictionary.Has(key) so I don't have to keep remembering to use ContainsKey().

--- Extensions/DictionaryExtensions.cs
+++ Extensions/DictionaryExtensions.cs
@@ -28,4 +28,8 @@

         return foundValue;
     }
+
+    public static bool Has<K, V>(this Dictionary<K, V> dictionary, K key) {
+        return dictionary.ContainsKey(key);
+    }
 }


commit

commit

--- Ztop.Todo.Web/Views/Report/Errand.cshtml
+++ Ztop.Todo.Web/Views/Report/Errand.cshtml
@@ -74,7 +74,7 @@
             交通费用

-                    <input type="text" class="form-control" placeholder="交通费用" readonly="readonly" name="" value="" />
+                    <input type="text" class="form-control" placeholder="交通费用" readonly="readonly" name="Traffic" value="" />

                         <button type="button" class="btn btn-success" data-toggle="modal" data-target="#Traffic">费用详情</button>

@@ -115,9 +115,26 @@
                 <duv class="input-group">
                     <input type="text" class="form-control" placeholder="出差补贴" readonly="readonly" name="" value="" />

-                        <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#">补贴详情</button>
+                        <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#SubSide">补贴详情</button>

                 </duv>
+

+

+

+

+                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
+
补贴详情

+

+

+
+

+

+                                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
+                                <button type="button" class="btn btn-primary" name="SubSide-OK" data-dismiss="modal">确定</button>
+

+

+

+

@@ -170,7 +187,7 @@

                         公里数：
-                        <input type="text" class="form-control" name="KiloMeters" placeholder="公里数" />
+                        <input type="text" class="form-control" name="KiloMeters" placeholder="公里数" targetType="@(type)" />
                         公里
                         车牌：
                         @if (type == BusType.Company)
@@ -189,6 +206,14 @@
                     @if (type == BusType.Company)
                     {

+                            过路费:
+                            <input type="text" class="form-control" name="Toll" placeholder="过路费" targetType="Company" />
+                            元
+                            油费：
+                            <input type="text" class="form-control" name="Petrol" placeholder="油费" />
+                            元
+

+

                             司机：
                             <select name="Driver" class="form-control">
                                 @foreach (Driver driver in Enum.GetValues(typeof(Driver)))
@@ -200,15 +225,15 @@
                             <input type="text" name="CarPetty" placeholder="车补" class="form-control" readonly="readonly" />
                             元

+
+                    }
+                    else
+                    {

-                            过路费:
-                            <input type="text" class="form-control" name="Toll" placeholder="过路费" />
-                            元
-                            油费：
-                            <input type="text" class="form-control" name="Petrol" placeholder="油费" />
+                            过路费：
+                            <input type="text" class="form-control" name="Toll" placeholder="过路费" targetType="Personal" />
                             元

-
                     }

             }
@@ -220,8 +245,9 @@
     var BUSHtml = $("#BUSBUS").html();
     var CarHtml = $("#CarCar").html();
     $(function () {
+        var mans = [];
         $("button[name='Person-OK']").click(function () {
-            var mans = [];
+            mans.splice(0, mans.length);
             $("input[name='Person']:checked").each(function () {
                 mans.push($(this).val());
             });
@@ -235,9 +261,10 @@
                 $("#ViewTraffic").append(BUSHtml);
             } else if (val == "自驾车") {
                 $("#ViewTraffic").append(CarHtml);
+                //公司车栏中选择司机的时候，自动计算车补
                 $("select[name='Driver']").unbind("change").bind("change", function () {
                     var money = .0;
-                    var kilo = parseFloat($("#ViewTraffic input[name='KiloMeters']").val());
+                    var kilo = parseFloat($("#ViewTraffic input[name='KiloMeters']")[0].value);
                     if (kilo != NaN && kilo != undefined) {
                         var driver = $(this).val();
                         if (driver == "无") {
@@ -248,14 +275,121 @@
                             money = kilo * 0.2;
                         }
                         $("#ViewTraffic input[name='CarPetty']").val(money);
+                        StatisticCompany();
                     } else {
                         alert("未获取公里数，无法计算车补金额！");
                     }
-
                 });
-            }
-
-        });
+
+                //绑定公司车以及自备车栏中填写油费之后，自动计算合计金额
+                $("input[name='Petrol']").unbind("change").bind("change", function () {
+                    StatisticCompany();
+                });
+                //绑定公司车以及自备车栏中填写过路费之后，自动计算合计金额
+                $("input[name='Toll']").unbind("change").bind("change", function () {
+                    var type = $(this).attr("targetType");
+                    if (type == "Company") {
+                        StatisticCompany();
+                    } else if (type = "Personal") {
+                        StatisticPersonal();
+                    }
+                });
+                //绑定公司车以及自备车栏中填写公里数之后，自动计算合计金额
+                $("input[name='KiloMeters']").unbind("change").bind("change", function () {
+                    var type = $(this).attr("targetType");
+                    if (type == "Company") {
+                        StatisticCompany();
+                    } else if (type == "Personal") {
+                        StatisticPersonal();
+                    }
+                });
+
+            }
+            StatisticTraffic();
+        });
+
+        //自动统计公司车的金额
+        function StatisticCompany() {
+            var sum = 0;
+            var carPetty = parseFloat($("#ViewTraffic input[name='CarPetty']").val());
+            if (!isNaN(carPetty)) {
+                sum += carPetty;
+            }
+            var petrol = parseFloat($("#ViewTraffic input[name='Petrol']").val());
+            if (!isNaN(petrol)) {
+                sum += petrol;
+            }
+            var toll = parseFloat($("#ViewTraffic input[name='Toll']")[0].value);
+            if (!isNaN(toll)) {
+                sum += toll;
+            }
+            $("#ViewTraffic input[name='CostCompany']").val(sum);
+        }
+
+        //自动统计自备车的金额
+        function StatisticPersonal() {
+            var sum = 0;
+            var kile = parseFloat($("#ViewTraffic input[name='KiloMeters']")[1].value);
+            if (!isNaN(kile)) {
+                $("#ViewTraffic input[name='CostPersonal']").val(kile * 1.5);
+            }
+        }
+
+        //交通费用中点击确定，自动计算交通费用
+        function StatisticTraffic() {
+            var sum = 0;
+            $("#ViewTraffic input[name='BusType']:checked").each(function () {
+                var type = $(this).val();
+                var cost = parseFloat($("#ViewTraffic input[name='Cost" + type + "']").val());
+                if (!isNaN(cost)) {
+                    sum += cost;
+                }
+            });
+
+            $("input[name='Traffic']").val(sum);
+        }
+
+        //当点击交通费用详情中确定的时候，自动计算交通费用
+        $("button[name='Traffic-OK']").click(function () {
+            StatisticTraffic();
+        });
+
+        $("#SubSide").on("show.bs.modal", function (e) {
+            if (mans.length > 0) {
+                return true;
+            } else {
+                alert("请选择出差人员再录入出差补贴详情！");
+                return false;
+            }
+        });
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

@@ -359,32 +493,6 @@
             return val;
         }

-        //计算公司派车合计金额
-        function StatisticCompany() {
-            var sum = .0;
-            var val = $("input[name='CarPetty']").val();
-            if (val != undefined && val != NaN && val != "") {
-                sum += parseFloat(val);
-            }
-            val = $("input[name='Petrol']").val();
-            if (val != undefined && val != NaN && val != "") {
-                sum += parseFloat(val);
-            }
-            val = $("input[name='Toll']")[0].value;
-            if (val != undefined && val != NaN && val != "") {
-                sum += parseFloat(val);
-            }
-            $("input[name='CostCompany']").val(sum);
-        };
-        //计算自备车车补金额
-        function StatisticPersonal() {
-            var kile = GetKile();
-            if (isNaN(kile)) {
-                alert("未获取公里数！");
-                return;
-            }
-            $("input[name='CostPersonal']").val(kile * 1.5);
-        }
         //在公司派车中选择司机 自动计算车补
         $("select[name='Driver']").change(function () {
             var val = $(this).val();