minor code formatting

minor code formatting

--- RelhaxModpack/RelhaxModpack/InstallerComponents/InstallEngine.cs
+++ RelhaxModpack/RelhaxModpack/InstallerComponents/InstallEngine.cs
@@ -158,6 +158,251 @@
         }
         #endregion

+        #region Main Install method
+        private async void LOLActuallyRunInstallationAsync()
+        {
+            if(OrderedPackagesToInstall == null || OrderedPackagesToInstall.Count() == 0)
+                throw new BadMemeException("WOW you really suck at programming");
+            if (OnInstallFinish == null || OnInstallProgress == null)
+                throw new BadMemeException("HOW DAFAQ DID YOU FAQ THIS UP???");
+            Logging.WriteToLog("Installation starts now from RunInstallation() in Install Engine");
+            //do more stuff here im sure like init log files
+            //also check enalbed just to be safe
+            List<SelectablePackage> selectedPackages = FlatListSelectablePackages.Where(package => package.Checked && package.Enabled).ToList();
+            //do any list processing here
+            //process any packages that have triggers
+            //reset the internal list first
+            foreach(Trigger trig in Triggers)
+            {
+                if (trig.Total != 0)
+                    trig.Total = 0;
+                if (trig.NumberProcessed != 0)
+                    trig.NumberProcessed = 0;
+                trig.Fired = false;
+            }
+            foreach(DatabasePackage package in PackagesToInstall)
+            {
+                if(package.Triggers.Count > 0)
+                {
+                    foreach(string triggerFromPackage in package.Triggers)
+                    {
+                        //in theory, each database package trigger is unique in each package AND in installer
+                        Trigger match = Triggers.Find(search => search.Name.ToLower().Equals(triggerFromPackage.ToLower()));
+                        if(match == null)
+                        {
+                            Logging.Debug("trigger match is null (no match!) {0}", triggerFromPackage);
+                            continue;
+                        }
+                        match.Total++;
+                    }
+                }
+            }
+            //process packages with data (cache) for cache backup and restore
+            List<SelectablePackage> packagesWithData = selectedPackages.Where(package => package.UserFiles.Count > 0).ToList();
+            //and reset the stopwatch
+            InstallStopWatch.Reset();
+
+            //step 1 on install: backup user mods
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog("Backup of mods, current install time = 0 msec");
+            if (ModpackSettings.BackupModFolder)
+            {
+                if (! BackupMods())
+                {
+                    ReportProgress();
+                    ReportFinish();
+                    return;
+                }
+                Logging.WriteToLog(string.Format("Backup of mods complete, took {0}msec",
+                    InstallStopWatch.Elapsed.TotalMilliseconds - OldTime.TotalMilliseconds));
+            }
+            else
+                Logging.WriteToLog("...skipped");
+
+            //step 2: backup data
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Backup of userdata, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            if (ModpackSettings.SaveUserData)
+            {
+
+            }
+            else
+                Logging.WriteToLog("...skipped");
+
+            //step 3: clear cache
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Cleaning of cache folders, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            if (ModpackSettings.ClearCache)
+            {
+
+            }
+            else
+                Logging.WriteToLog("...skipped");
+
+            //step 4: clear logs
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Cleaning of logs, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            if (ModpackSettings.DeleteLogs)
+            {
+
+            }
+            else
+                Logging.WriteToLog("...skipped");
+
+            //step 5: clean mods folders
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Cleaning of mods foldres, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            if (ModpackSettings.CleanInstallation)
+            {
+
+            }
+            else
+                Logging.WriteToLog("...skipped");
+
+            //step 6: extract mods
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Exctacting mods, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            if (ModpackSettings.CleanInstallation)
+            {
+
+            }
+            else
+                Logging.WriteToLog("...skipped?");
+
+            //step 7: restore data
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Restore of userdata, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            //if statement TODO
+            if (ModpackSettings.SaveUserData)
+            {
+
+            }
+            else
+                Logging.WriteToLog("...skipped");
+
+            //step 8: unpack xml files
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Unpack of xml files, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            List<XmlUnpack> xmlUnpacks = MakeXmlUnpackListList();
+            if (xmlUnpacks.Count > 0)
+            {
+                foreach(XmlUnpack xmlUnpack in xmlUnpacks)
+                {
+                    XMLUtils.UnpackXmlFile(xmlUnpack);
+                }
+            }
+            else
+                Logging.WriteToLog("...skipped (no XmlUnpack entries parsed");
+
+            //step 8: patch files (async option)
+            //make the task array here. so far can be a maximum of 3 items
+            Task[] concurrentTasksAfterMainExtractoin = new Task[3];
+            int taskIndex = 0;
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Patching of files, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            List<Patch> pathces = MakePatchList();
+            if (pathces.Count > 0)
+            {
+                concurrentTasksAfterMainExtractoin[taskIndex++] = Task.Factory.StartNew(() =>
+                {
+                    foreach (Patch patch in pathces)
+                    {
+                        PatchUtils.RunPatch(patch);
+                    }
+                });
+            }
+            else
+                Logging.WriteToLog("...skipped (no patch entries parsed)");
+
+            //step 9: create create shortcuts (async option)
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Creating of shortcuts, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            List<Shortcut> shortcuts = MakeShortcutList();
+            if (shortcuts.Count > 0)
+            {
+                concurrentTasksAfterMainExtractoin[taskIndex++] = Task.Factory.StartNew(() =>
+                {
+                    foreach (Shortcut shortcut in shortcuts)
+                    {
+                        Utils.CreateShortcut(shortcut);
+                    }
+                });
+            }
+            else
+                Logging.WriteToLog("...skipped (no shortcut entries parsed)");
+
+
+
+            //barrier goes here to make sure cleanup is the last thing to do
+            Task.WaitAll(concurrentTasksAfterMainExtractoin);
+
+            //step 9: cleanup (whatever that implies lol)
+            OldTime = InstallStopWatch.Elapsed;
+            Progress.TotalCurrent++;
+            InstallFinishedArgs.ExitCodes++;
+            Logging.WriteToLog(string.Format("Cleanup, current install time = {0} msec", InstallStopWatch.Elapsed.TotalMilliseconds));
+            Cleanup();
+
+            //and i guess we're done
+            //if were'not causing the main thread to await, then yeah report that we'er done
+            if (!AwaitCallback)
+            {
+                InstallFinishedArgs.ExitCodes = InstallerExitCodes.Success;
+                ReportFinish();
+            }
+
+            //report to log install is finished
+            Logging.Info("Install finished, total install time = {0} msec", Logfiles.Application, InstallStopWatch.Elapsed.TotalMilliseconds);
+        }
+        #endregion
+
+        #region Installer methods
+
+        private void BuildContourIcons()
+        {
+            Logging.WriteToLog(string.Format("Creating of atlases, current install time = {0} msec",
+                InstallStopWatch.Elapsed.TotalMilliseconds));
+            List<Atlas> atlases = MakeAtlasList();
+            if (atlases.Count > 0)
+            {
+                foreach (Atlas atlas in atlases)
+                {
+                    Utils.CreateAtlas(atlas);
+                }
+            }
+            else
+                Logging.Error("building contour icons triggered, but none exist!");
+        }
+
         private void ProcessTriggers(List<string> packageTriggers)
         {
             //at least 1 trigger exists
@@ -171,7 +416,7 @@
                     continue;
                 }
                 //this could be in multiple threads, so needs to be done in a lock statement (read modify write operation)
-                lock(Triggers)
+                lock (Triggers)
                 {
                     match.NumberProcessed++;
                     if (match.NumberProcessed >= match.Total)
@@ -190,7 +435,7 @@
                             Logging.Debug("trigger {0} is starting", match.Name);
                             match.Fired = true;
                             //hard_coded list of triggers that can be fired from list at top of class
-                            switch(match.Name)
+                            switch (match.Name)
                             {
                                 case TriggerContouricons:
                                     Task.Run(() => BuildContourIcons());
@@ -204,251 +449,6 @@
                 }
             }
         }
-
-        #region Main Install method
-        private async void LOLActuallyRunInstallationAsync()
-        {
-            if(OrderedPackagesToInstall == null || OrderedPackagesToInstall.Count() == 0)
-                throw new BadMemeException("WOW you really suck at programming");
-            if (OnInstallFinish == null || OnInstallProgress == null)
-                throw new BadMemeException("HOW DAFAQ DID YOU FAQ THIS UP???");
-            Logging.WriteToLog("Installation starts now from RunInstallation() in Install Engine");
-            //do more stuff here im sure like init log files
-            //also check enalbed just to be safe
-            List<SelectablePackage> selectedPackages = FlatListSelectablePackages.Where(package => package.Checked && package.Enabled).ToList();
-            //do any list processing here
-            //process any packages that have triggers
-            //reset the internal list first
-            foreach(Trigger trig in Triggers)
-            {
-                if (trig.Total != 0)
-                    trig.Total = 0;
-                if (trig.NumberProcessed != 0)
-                    trig.NumberProcessed = 0;
-                trig.Fired = false;
-            }
-            foreach(DatabasePackage package in PackagesToInstall)
-            {
-                if(package.Triggers.Count > 0)
-                {
-                    foreach(string triggerFromPackage in package.Triggers)
-                    {
-                        //in theory, each database package trigger is unique in each package AND in installer
-                        Trigger match = Triggers.Find(search => search.Name.ToLower().Equals(triggerFromPackage.ToLower()));
-                        if(match == null)
-                        {
-                            Logging.Debug("trigger match is null (no match!) {0}", triggerFromPackage);
-                            continue;
-                        }
-                        match.Total++;
-                    }
-                }
-            }
-            //process packages with data (cache) for cache backup and restore
-            List<SelectablePackage> packagesWithData = selectedPackages.Where(package => package.UserFiles.Count > 0).ToList();
-            //and reset the stopwatch
-            InstallStopWatch.Reset();
-
-            //step 1 on install: backup user mods
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog("Backup of mods, current install time = 0 msec");
-            if (ModpackSettings.BackupModFolder)
-            {
-                if (! BackupMods())
-                {
-                    ReportProgress();
-                    ReportFinish();
-                    return;
-                }
-                Logging.WriteToLog(string.Format("Backup of mods complete, took {0}msec",
-                    InstallStopWatch.Elapsed.TotalMilliseconds - OldTime.TotalMilliseconds));
-            }
-            else
-                Logging.WriteToLog("...skipped");
-
-            //step 2: backup data
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Backup of userdata, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            if (ModpackSettings.SaveUserData)
-            {
-
-            }
-            else
-                Logging.WriteToLog("...skipped");
-
-            //step 3: clear cache
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Cleaning of cache folders, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            if (ModpackSettings.ClearCache)
-            {
-
-            }
-            else
-                Logging.WriteToLog("...skipped");
-
-            //step 4: clear logs
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Cleaning of logs, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            if (ModpackSettings.DeleteLogs)
-            {
-
-            }
-            else
-                Logging.WriteToLog("...skipped");
-
-            //step 5: clean mods folders
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Cleaning of mods foldres, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            if (ModpackSettings.CleanInstallation)
-            {
-
-            }
-            else
-                Logging.WriteToLog("...skipped");
-
-            //step 6: extract mods
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Exctacting mods, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            if (ModpackSettings.CleanInstallation)
-            {
-
-            }
-            else
-                Logging.WriteToLog("...skipped?");
-
-            //step 7: restore data
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Restore of userdata, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            //if statement TODO
-            if (ModpackSettings.SaveUserData)
-            {
-
-            }
-            else
-                Logging.WriteToLog("...skipped");
-
-            //step 8: unpack xml files
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Unpack of xml files, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            List<XmlUnpack> xmlUnpacks = MakeXmlUnpackListList();
-            if (xmlUnpacks.Count > 0)
-            {
-                foreach(XmlUnpack xmlUnpack in xmlUnpacks)
-                {
-                    XMLUtils.UnpackXmlFile(xmlUnpack);
-                }
-            }
-            else
-                Logging.WriteToLog("...skipped (no XmlUnpack entries parsed");
-
-            //step 8: patch files (async option)
-            //make the task array here. so far can be a maximum of 3 items
-            Task[] concurrentTasksAfterMainExtractoin = new Task[3];
-            int taskIndex = 0;
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Patching of files, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            List<Patch> pathces = MakePatchList();
-            if (pathces.Count > 0)
-            {
-                concurrentTasksAfterMainExtractoin[taskIndex++] = Task.Factory.StartNew(() =>
-                {
-                    foreach (Patch patch in pathces)
-                    {
-                        PatchUtils.RunPatch(patch);
-                    }
-                });
-            }
-            else
-                Logging.WriteToLog("...skipped (no patch entries parsed)");
-
-            //step 9: create create shortcuts (async option)
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Creating of shortcuts, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            List<Shortcut> shortcuts = MakeShortcutList();
-            if (shortcuts.Count > 0)
-            {
-                concurrentTasksAfterMainExtractoin[taskIndex++] = Task.Factory.StartNew(() =>
-                {
-                    foreach (Shortcut shortcut in shortcuts)
-                    {
-                        Utils.CreateShortcut(shortcut);
-                    }
-                });
-            }
-            else
-                Logging.WriteToLog("...skipped (no shortcut entries parsed)");
-
-
-
-            //barrier goes here to make sure cleanup is the last thing to do
-            Task.WaitAll(concurrentTasksAfterMainExtractoin);
-
-            //step 9: cleanup (whatever that implies lol)
-            OldTime = InstallStopWatch.Elapsed;
-            Progress.TotalCurrent++;
-            InstallFinishedArgs.ExitCodes++;
-            Logging.WriteToLog(string.Format("Cleanup, current install time = {0} msec", InstallStopWatch.Elapsed.TotalMilliseconds));
-            Cleanup();
-
-            //and i guess we're done
-            //if were'not causing the main thread to await, then yeah report that we'er done
-            if (!AwaitCallback)
-            {
-                InstallFinishedArgs.ExitCodes = InstallerExitCodes.Success;
-                ReportFinish();
-            }
-
-            //report to log install is finished
-            Logging.Info("Install finished, total install time = {0} msec", Logfiles.Application, InstallStopWatch.Elapsed.TotalMilliseconds);
-        }
-        #endregion
-
-        private void BuildContourIcons()
-        {
-            Logging.WriteToLog(string.Format("Creating of atlases, current install time = {0} msec",
-                InstallStopWatch.Elapsed.TotalMilliseconds));
-            List<Atlas> atlases = MakeAtlasList();
-            if (atlases.Count > 0)
-            {
-                foreach (Atlas atlas in atlases)
-                {
-                    Utils.CreateAtlas(atlas);
-                }
-            }
-            else
-                Logging.Error("building contour icons triggered, but none exist!");
-        }
-
-        #region Installer methods
         private bool BackupMods()
         {
             //check first if the directory exists first


changed sort to use qsort per advice from Ricardo.

--- cocos2d/sprite_nodes/CCSpriteBatchNode.cs
+++ cocos2d/sprite_nodes/CCSpriteBatchNode.cs
@@ -214,6 +214,54 @@
             m_pobTextureAtlas.RemoveAllQuads();
         }

+        // Quick sort taken from http://snipd.net/quicksort-in-c
+        public static void Quicksort(CCNode[] elements, int left, int right)
+        {
+            int i = left, j = right;
+            CCNode pivot = elements[(left + right) / 2];
+
+            while (i <= j)
+            {
+                /*
+                           (pivot.m_nZOrder < elements[i].m_nZOrder ||
+                            (pivot.m_nZOrder == elements[i].m_nZOrder && pivot.m_uOrderOfArrival < elements[i].m_uOrderOfArrival)))
+                 */
+                while ((elements[i].m_nZOrder < pivot.m_nZOrder ||
+                            (pivot.m_nZOrder == elements[i].m_nZOrder && elements[i].m_uOrderOfArrival < pivot.m_uOrderOfArrival)))
+                {
+                    i++;
+                }
+
+                while ((elements[j].m_nZOrder > pivot.m_nZOrder ||
+                            (pivot.m_nZOrder == elements[j].m_nZOrder && elements[j].m_uOrderOfArrival > pivot.m_uOrderOfArrival)))
+                {
+                    j--;
+                }
+
+                if (i <= j)
+                {
+                    // Swap
+                    CCNode tmp = elements[i];
+                    elements[i] = elements[j];
+                    elements[j] = tmp;
+
+                    i++;
+                    j--;
+                }
+            }
+
+            // Recursive calls
+            if (left < j)
+            {
+                Quicksort(elements, left, j);
+            }
+
+            if (i < right)
+            {
+                Quicksort(elements, i, right);
+            }
+        }
+
         //override sortAllChildren
         public override void SortAllChildren()
         {
@@ -221,9 +269,12 @@
             {
                 int j = 0, count = m_pChildren.count;
                 CCNode[] elements = m_pChildren.Elements;
-                CCNode tempItem;
-
-                //insertion sort
+                // CCNode tempItem;
+
+                //insertion sort - change to qsort per RIQ
+                Quicksort(elements, 0, count - 1);
+
+                /*
                 for (int i = 1; i < count; i++)
                 {
                     tempItem = elements[i];
@@ -240,6 +291,7 @@

                     elements[j + 1] = tempItem;
                 }
+                */

                 //sorted now check all children
                 if (count > 0)


fixed potential issue with null values in excel export

--- TheWheel.OpenXml/Extensions.cs
+++ TheWheel.OpenXml/Extensions.cs
@@ -89,7 +89,7 @@
                 foreach (var column in cols)
                 {
                     var value = column.Evaluate(item);
-                    string stringValue = null;
+                    string stringValue = "";
                     if (value != null)
                     {
                         stringValue = value.ToString();


Setting timer in chat now works

Setting timer in chat now works

--- TimerChange.mod/TimerChange.cs
+++ TimerChange.mod/TimerChange.cs
@@ -10,13 +10,14 @@
 using Mono.Cecil;

 namespace TimerChange.mod {
-    public class TimerChange : BaseMod {
+    public class TimerChange : BaseMod, ICommListener {
         private FieldInfo activeColorField;
         private FieldInfo leftColorField;
         private FieldInfo roundTimeField;
         private FieldInfo roundTimerField;
         private FieldInfo showClockField;
         private MethodInfo endTurnMethod;
+        private int timeout = 91;

         public TimerChange() {
             activeColorField = typeof(BattleMode).GetField("activeColor", BindingFlags.Instance | BindingFlags.NonPublic);
@@ -25,6 +26,8 @@
             roundTimerField = typeof(BattleMode).GetField("roundTimer", BindingFlags.Instance | BindingFlags.NonPublic);
             showClockField = typeof(BattleMode).GetField("showClock", BindingFlags.Instance | BindingFlags.NonPublic);
             endTurnMethod = typeof(BattleMode).GetMethod("endTurn", BindingFlags.Instance | BindingFlags.NonPublic);
+
+            App.Communicator.addListener(this);
         }

         public static string GetName() {
@@ -53,23 +56,55 @@
         }

         public override void AfterInvoke(InvocationInfo info, ref object returnValue) {
-            if (info.target is BattleMode && info.targetMethod.Equals("_handleMessage")) {
-                BattleMode target = (BattleMode)info.target;
-                Message msg = (Message) info.arguments[0];
-                if (msg is GameInfoMessage) {
-                    showClockField.SetValue(target, true);
-                    roundTimeField.SetValue(target, 30);
+            // timeout larger than 90 does not make any sense, smaller than 0 also makes no sense
+            if (timeout > 0 && timeout < 90) {
+                if (info.target is BattleMode && info.targetMethod.Equals("_handleMessage")) {
+                    BattleMode target = (BattleMode)info.target;
+                    Message msg = (Message) info.arguments[0];
+                    if (msg is GameInfoMessage) {
+                        showClockField.SetValue(target, true);
+                        roundTimeField.SetValue(target, timeout);
+                    }
+                }
+                if (info.target is BattleMode && info.targetMethod.Equals("OnGUI")) {
+                    BattleMode target = (BattleMode)info.target;
+                    if (activeColorField.GetValue(target).Equals(leftColorField.GetValue(target))) {
+                        float roundTimer = (float)roundTimerField.GetValue(target);
+                        float roundTime = (float)roundTimeField.GetValue(target);
+                        float timePassed = (roundTimer >= 0f) ? Mathf.Floor(Time.time - roundTimer) : 0f;
+                        int seconds = Mathf.Max(0, (int)(roundTime + 1 - timePassed)); // add +1 so round stops 1 second AFTER hitting 0
+                        if (seconds == 0) {
+                            endTurnMethod.Invoke(target, new object[] {});
+                        }
+                    }
                 }
             }
-            if (info.target is BattleMode && info.targetMethod.Equals("OnGUI")) {
-                BattleMode target = (BattleMode)info.target;
-                if (activeColorField.GetValue(target).Equals(leftColorField.GetValue(target))) {
-                    float roundTimer = (float)roundTimerField.GetValue(target);
-                    float roundTime = (float)roundTimeField.GetValue(target);
-                    float timePassed = (roundTimer >= 0f) ? Mathf.Floor(Time.time - roundTimer) : 0f;
-                    int seconds = Mathf.Max(0, (int)(roundTime + 1 - timePassed)); // add +1 so round stops 1 second AFTER hitting 0
-                    if (seconds == 0) {
-                        endTurnMethod.Invoke(target, new object[] {});
+        }
+
+        public void onReconnect() {
+            return;
+        }
+
+        public void handleMessage(Message msg) {
+            if (msg is RoomChatMessageMessage) {
+                RoomChatMessageMessage rcMsg = (RoomChatMessageMessage)msg;
+                string[] cmds = rcMsg.text.ToLower().Split(' ');
+                if (cmds[0].Equals("/timerchange") || cmds[0].Equals("/tc")) {
+                    try {
+                        timeout = Convert.ToInt32(cmds[1]);
+                        RoomChatMessageMessage newMsg = new RoomChatMessageMessage();
+                        newMsg.from = GetName(); // name of the mod, that is
+                        newMsg.roomName = App.ArenaChat.ChatRooms.GetCurrentRoom();
+                        if (timeout < 0 || timeout > 90) {
+                            newMsg.text = "Match timeout set to default.";
+                        }
+                        else {
+                            newMsg.text = "Match timeout set to " + timeout + " seconds";
+                        }
+                        App.ChatUI.handleMessage(newMsg);
+                        App.ArenaChat.ChatRooms.ChatMessage(newMsg);
+                    }
+                    catch (Exception) {
                     }
                 }
             }


[trunk] Clang C++ compiler options derive from the C options. This has been patched in the GenerateFiles.py already

--- packages/Clang/3.1/Scripts/CxxCompilerOptionCollectionDelegates.cs
+++ packages/Clang/3.1/Scripts/CxxCompilerOptionCollectionDelegates.cs
@@ -11,6 +11,7 @@
         }
         protected override void SetDelegates(Opus.Core.DependencyNode node)
         {
+            base.SetDelegates(node);
             this["ExceptionHandler"].PrivateData = new PrivateData(ExceptionHandlerCommandLineProcessor);
         }
     }


Throw errors when something goes wrong

Throw errors when something goes wrong

When something goes wrong, i.e. a note exists under a name when your
trying to add it, it now throws an exception. This means all exceptions
can be caught by the main loop and displayed easier.

--- Todo-List/Todo-List/Program.cs
+++ Todo-List/Todo-List/Program.cs
@@ -101,30 +101,28 @@
         {
             string name = GetName(cmd);

-            // Throw error if name already exists or no name was provided
-            if (NoteSorter.NoteIndex(name) != -1 || name.Length == 0)
-            {
-                Console.WriteLine("Error! No name was provided, or the note already exists!");
-            }
-            else
-            {
-                // Get the string of categories
-                string catString;
-                try
-                {
-                    catString = cmd.Substring(cmd.IndexOf('"') + name.Length + 3).ToUpper();
-                }
-                catch (ArgumentOutOfRangeException)
-                {
-                    catString = string.Empty;
-                }
-
-                // Construct the list of categories
-                string[] categories = catString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
-
-                // Create and add the note
-                NoteSorter.AddNote(new Note(name, categories));
-            }
+            if (NoteSorter.NoteIndex(name) != -1)
+            {
+                // Throw error if name already exists
+                throw new Exception("The note already exists!");
+            }
+
+            // Get the string of categories
+            string catString;
+            try
+            {
+                catString = cmd.Substring(cmd.IndexOf('"') + name.Length + 3).ToUpper();
+            }
+            catch (ArgumentOutOfRangeException)
+            {
+                catString = string.Empty;
+            }
+
+            // Construct the list of categories
+            string[] categories = catString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+
+            // Create and add the note
+            NoteSorter.AddNote(new Note(name, categories));
         }

         /// <summary>
@@ -143,15 +141,13 @@
         {
             string name = GetName(cmd);

-            // Throw error if name doesn't exists or no name was provided
             if (NoteSorter.NoteIndex(name) == -1 || name.Length == 0)
             {
-                Console.WriteLine("Error! No name was provided, or the note doesn't exists!");
-            }
-            else
-            {
-                NoteSorter.RemoveNote(NoteSorter.Notes[NoteSorter.NoteIndex(name)]);
-            }
+                // Throw error if name doesn't exists
+                throw new Exception("No note found under the provided name!");
+            }
+
+            NoteSorter.RemoveNote(NoteSorter.Notes[NoteSorter.NoteIndex(name)]);
         }

         /// <summary>


bug fix

bug fix

--- Tyvj/Views/Status/Index.cshtml
+++ Tyvj/Views/Status/Index.cshtml
@@ -49,7 +49,7 @@
 <script>
     var contest_id = @(ViewBag.DestContestID != null ? ((int)ViewBag.DestContestID).ToString() : "null");
     var problem_id = null;
-    var username = @(ViewBag.DestUsername !=null?(string)ViewBag.DestUsername:"null");
+    var username = "@(ViewBag.DestUsername !=null?(string)ViewBag.DestUsername:"")";
     var result = null;
     $("#btnSearch").click(function () {
         problem_id = $("#txtProblemID").val();


Putting IconFileBase messages on hold; where we're going, it's just gonna be a boatload of clutter.

--- UIconEdit.Core/IconFileBase.cs
+++ UIconEdit.Core/IconFileBase.cs
@@ -194,7 +194,7 @@

         internal static IconFileBase Load(Stream input, IconTypeCode? id, IconLoadExceptionHandler handler)
         {
-#if DEBUG
+#if DEBUG && MESSAGE
             Stopwatch sw = Stopwatch.StartNew();
 #endif
 #if LEAVEOPEN
@@ -494,8 +494,10 @@
                                 new Tuple<Size, Size>(new Size(entry.BWidth, entry.BHeight), new Size(loadedImage.PixelWidth, loadedImage.PixelHeight)), i);
                         }

+#if DEBUG && MESSAGE
                         Debug.WriteLine("Reading type {0}, width:{1}, height:{2}, bit depth:{3}",
                             isPng ? "PNG" : "BMP", loadedImage.PixelWidth, loadedImage.PixelHeight, bitDepth);
+#endif

                         IconEntry resultEntry;

@@ -521,7 +523,7 @@
                         offset += entry.ResourceLength;
                     }
                 }
-#if DEBUG
+#if DEBUG && MESSAGE
                 sw.Stop();
                 Debug.WriteLine("Finished processing all entries in {0}ms.", sw.Elapsed.TotalMilliseconds);
 #endif
@@ -679,7 +681,7 @@
                 uint offset = (uint)(6 + (entries.Count * 16));

                 List<MemoryStream> streamList = new List<MemoryStream>();
-#if DEBUG
+#if DEBUG && MESSAGE
                 Stopwatch sw = Stopwatch.StartNew();
 #endif
                 foreach (IconEntry curEntry in entries)
@@ -695,7 +697,7 @@
                     ms.CopyTo(output);
                     ms.Dispose();
                 }
-#if DEBUG
+#if DEBUG && MESSAGE
                 sw.Stop();
                 Debug.WriteLine("Finished processing all entries in {0}ms.", sw.Elapsed.TotalMilliseconds);
 #endif
@@ -885,8 +887,10 @@
 #endif
             }

+#if DEBUG && MESSAGE
             Debug.WriteLine("Writing type {0} - width:{1}, height:{2}, bit depth:{3}, computed bits per pixel:{4}, length:{5}",
                 isPng ? "PNG" : "BMP", entry.Width, entry.Height, entry.BitDepth, GetImgY(entry), writeStream.Length);
+#endif

             length = (uint)writeStream.Length;
             writer.Write(length); //12


Rollback mistakenly committed commented lines

--- src/Couchbase.Lite.Tests.iOS/AppDelegate.cs
+++ src/Couchbase.Lite.Tests.iOS/AppDelegate.cs
@@ -37,12 +37,13 @@

             // tests can be inside the main assembly
             AddTestAssembly(Assembly.GetExecutingAssembly());
-            //AutoStart = true;
-            //TerminateAfterExecution = true;
-            //using (var str = GetType().Assembly.GetManifestResourceStream("result_ip"))
-            //using (var sr = new StreamReader(str)) {
-            //    Writer = new TcpTextWriter(sr.ReadToEnd().TrimEnd(), 12345);
-            //}
+            AutoStart = true;
+            TerminateAfterExecution = true;
+            using (var str = GetType().Assembly.GetManifestResourceStream("result_ip"))
+            using (var sr = new StreamReader(str))
+            {
+                Writer = new TcpTextWriter(sr.ReadToEnd().TrimEnd(), 12345);
+            }

             return base.FinishedLaunching(app, options);
         }


#30248 new txn types

#30248 new txn types

--- src/DotNetClientApi/Data/TransactionType.cs
+++ src/DotNetClientApi/Data/TransactionType.cs
@@ -18,5 +18,7 @@
         Error = 10,
         DepositFee = 11,
         ReferralCommission = 12,
+        ReservedFutureUse = 13,
+        StatementFee = 14
     }
 }


linux test

linux test

--- src/DotNetTor.Tests/TotServerClientTests.cs
+++ src/DotNetTor.Tests/TotServerClientTests.cs
@@ -58,6 +58,8 @@
 			TotClient client = await manager.EstablishTotConnectionAsync(serverEndPoint);

 			await server.StopAsync();
+
+			server = new TotServer(serverEndPoint);
 			await server.StartAsync();
 			await server.StopAsync();


Use Application Insights

Use Application Insights

--- src/Duracellko.PlanningPoker.Web/Program.cs
+++ src/Duracellko.PlanningPoker.Web/Program.cs
@@ -12,6 +12,7 @@

         public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
             WebHost.CreateDefaultBuilder(args)
+                .UseApplicationInsights()
                 .UseStartup<Startup>();
     }
 }


documentation changes

documentation changes

--- src/EasyRpc.AspNetCore/IApiConfiguration.cs
+++ src/EasyRpc.AspNetCore/IApiConfiguration.cs
@@ -85,7 +85,7 @@
         /// <param name="types"></param>
         /// <returns></returns>
         ITypeSetExposureConfiguration Expose(IEnumerable<Type> types);
-
+
         /// <summary>
         /// Add header to all responses
         /// </summary>


Kill some more nullguard

Kill some more nullguard

--- src/GitHub.UI.Reactive/Controls/ViewBase.cs
+++ src/GitHub.UI.Reactive/Controls/ViewBase.cs
@@ -80,7 +80,6 @@
         /// <summary>
         /// Gets a value reflecting the associated view model's <see cref="IHasErrorState.ErrorMessage"/> property.
         /// </summary>
-        [AllowNull]
         public string ErrorMessage
         {
             get { return (string)GetValue(ErrorMessageProperty); }


... graph changed

... graph changed

--- src/HeathcareSystem/DataStuff/GraphStuff.cs
+++ src/HeathcareSystem/DataStuff/GraphStuff.cs
@@ -48,17 +48,17 @@
             var result = new List<object>();
             var diseases = context.Diseases.ToList();
             var list = new List<object>();
-            list.Add(new { Name = "Bến Cát", Ammount = 10 });
-            list.Add(new { Name = "Phú Giáo", Ammount = 30 });
-            list.Add(new { Name = "Tp.Thủ Dầu Một", Ammount = 20 });
-            list.Add(new { Name = "Bàu Bàng", Ammount = 20 });
+            list.Add(new { Name = "Bến Cát", Ammount = 11 });
+            list.Add(new { Name = "Phú Giáo", Ammount = 29 });
+            list.Add(new { Name = "Tp.Thủ Dầu Một", Ammount = 23 });
+            list.Add(new { Name = "Bàu Bàng", Ammount = 17 });
             list.Add(new { Name = "Dầu Tiếng", Ammount = 20 });
             result.Add(new { Name = "Hypotension", Provinces = list});

             list = new List<object>();
             list.Add(new { Name = "Bến Cát", Ammount = 15 });
-            list.Add(new { Name = "Phú Giáo", Ammount = 15 });
-            list.Add(new { Name = "Bàu Bàng", Ammount = 20 });
+            list.Add(new { Name = "Phú Giáo", Ammount = 14 });
+            list.Add(new { Name = "Bàu Bàng", Ammount = 21 });
             result.Add(new { Name = "Anemia", Provinces = list});

             list = new List<object>();


Eliminated some unchecked scopes.

Eliminated some unchecked scopes.

--- src/KiteBotCore/Modules/Rank/RankService.cs
+++ src/KiteBotCore/Modules/Rank/RankService.cs
@@ -17,6 +17,7 @@
         {
             _discordFactory = discordContextFactory;
             client.UserJoined += AddUser;
+            client.MessageReceived += UpdateLastActivity;

         }

@@ -24,14 +25,11 @@
         {
             using (DiscordContext db = _discordFactory.Create(new DbContextFactoryOptions()))
             {
-                unchecked
-                {
-                    long key = (long) inputUser.Id;
-                    User user = await db.FindAsync<User>(key);
+                User user = await db.FindAsync<User>(inputUser.Id.ConvertToUncheckedLong());

-                    Debug.Assert(user != null);
-                    return user.JoinedAt.Value;
-                }
+                Debug.Assert(user != null);
+                return user.JoinedAt.Value;
+
             }
         }

@@ -39,34 +37,29 @@
         {
             using (DiscordContext db = _discordFactory.Create(new DbContextFactoryOptions()))
             {
-                unchecked
+                Guild guild = await db.FindAsync<Guild>(userInput.Guild.Id.ConvertToUncheckedLong());
+                User user = await db.FindAsync<User>(userInput.Id.ConvertToUncheckedLong());
+
+                if (user == null)
                 {
-                    long guildKey = (long)userInput.Guild.Id;
-                    Guild guild = await db.FindAsync<Guild>(guildKey);
+                    user = new User()
+                    {
+                        Name = userInput.Username,
+                        Guild = guild,
+                        Id = userInput.Id,
+                        JoinedAt = userInput.JoinedAt,
+                        LastActivityAt = DateTimeOffset.UtcNow,
+                        Messages = new List<Message>()
+                    };
+                    guild.Users.Add(user);
+                }
+                else
+                {
+                    user.LastActivityAt = DateTimeOffset.UtcNow;
+                }
+                await db.SaveChangesAsync();
+                await UpdateUserRoles(userInput);

-                    long userKey = (long)userInput.Id;
-                    User user = await db.FindAsync<User>(userKey);
-
-                    if (user == null)
-                    {
-                        user = new User()
-                        {
-                            Name = userInput.Username,
-                            Guild = guild,
-                            Id = userInput.Id,
-                            JoinedAt = userInput.JoinedAt,
-                            LastActivityAt = DateTimeOffset.UtcNow,
-                            Messages = new List<Message>()
-                        };
-                        guild.Users.Add(user);
-                    }
-                    else
-                    {
-                        user.LastActivityAt = DateTimeOffset.UtcNow;
-                    }
-                    await db.SaveChangesAsync();
-                    await UpdateUserRoles(userInput);
-                }
             }
         }

@@ -74,5 +67,26 @@
         {

         }
+
+        internal async Task UpdateLastActivity(SocketMessage message)
+        {
+            SocketGuildChannel messageChannel = (message.Channel as SocketGuildChannel);
+            if (messageChannel != null)
+            {
+                using (DiscordContext db = _discordFactory.Create(new DbContextFactoryOptions()))
+                {
+                    await db.FindAsync<User>(message.Author.Id.ConvertToUncheckedLong());
+                }
+            }
+        }
+    }
+
+    public static class IdHelper
+    {
+        public static long ConvertToUncheckedLong(this ulong u)
+        {
+            unchecked { return (long)u; }
+        }
     }
 }
+


check if previous/previous line in list #173

--- src/MarkdownEdit/Models/ListInputHandler.cs
+++ src/MarkdownEdit/Models/ListInputHandler.cs
@@ -40,9 +40,17 @@
                 firstMatch?.Action(firstMatch.Match);
             };

-            Action<Action> onlyIfIncreased = func =>
+            Action<Action> ifIncreased = func =>
             {
                 if (lineCountIncreased) func();
+            };
+
+            Action<string, Action> atEndOfList = (symbol, action) =>
+            {
+                var previous = line.PreviousLine;
+                if (previous == null || previous.Length == 0) return;
+                var previousText = document.GetText(previous.Offset, previous.Length);
+                if (previousText.StartsWith(symbol)) action();
             };

             document.BeginUpdate();
@@ -50,16 +58,16 @@
             match(text, new[]
             {
                 new PM(UnorderedListCheckboxPattern,
-                    m => onlyIfIncreased(() => document.Insert(editor.SelectionStart, m.Groups[0].Value.TrimStart() + " "))),
+                    m => ifIncreased(() => document.Insert(editor.SelectionStart, m.Groups[0].Value.TrimStart() + " "))),

                 new PM(UnorderedListCheckboxEndPattern,
-                    m => document.Remove(line)),
+                    m => atEndOfList(m.Groups[0].Value , () => document.Remove(line))),

                 new PM(UnorderedListPattern,
-                    m => onlyIfIncreased(() => document.Insert(editor.SelectionStart, m.Groups[0].Value.TrimStart() + " "))),
+                    m => ifIncreased(() => document.Insert(editor.SelectionStart, m.Groups[0].Value.TrimStart() + " "))),

                 new PM(UnorderedListEndPattern,
-                    m => document.Remove(line)),
+                    m =>  atEndOfList(m.Groups[0].Value , () => document.Remove(line))),

                 new PM(OrderedListPattern, m =>
                 {
@@ -74,13 +82,13 @@
                 }),

                 new PM(OrderedListEndPattern,
-                    m => document.Remove(line)),
+                    m =>  atEndOfList(m.Groups[0].Value , () => document.Remove(line))),

                 new PM(BlockQuotePattern,
-                    m => onlyIfIncreased(() => document.Insert(editor.SelectionStart, m.Groups[1].Value.TrimStart()))),
+                    m => ifIncreased(() => document.Insert(editor.SelectionStart, m.Groups[1].Value.TrimStart()))),

                 new PM(BlockQuoteEndPattern,
-                    m => document.Remove(line))
+                    m =>  atEndOfList(m.Groups[0].Value , () => document.Remove(line)))
             });

             document.EndUpdate();


Experimental async mode for spending a maximum number of ms on evaluation

--- ink-engine-runtime/Story.cs
+++ ink-engine-runtime/Story.cs
@@ -3,6 +3,7 @@
 using System.Linq;
 using System.Text;
 using System.IO;
+using System.Diagnostics;

 namespace Ink.Runtime
 {
@@ -246,184 +247,280 @@
             if( !_hasValidatedExternals )
                 ValidateExternalBindings ();

-
-            return ContinueInternal ();
-        }
-
-
-        string ContinueInternal()
-		{
-			bool canContinue_cached = canContinue;
-			if (!canContinue_cached) {
+            //return ContinueInternal ();
+
+            ContinueInternal ();
+
+            return currentText;
+        }
+
+        public bool asyncContinueComplete {
+            get {
+                return !_asyncContinueActive;
+            }
+        }
+
+        public void ContinueAsync (float millisecsLimitAsync)
+        {
+            if( !_hasValidatedExternals )
+                ValidateExternalBindings ();
+
+            ContinueInternal (millisecsLimitAsync);
+        }
+
+        void ContinueInternal (float millisecsLimitAsync = 0)
+        {
+            if( _profiler != null )
+                _profiler.PreContinue();
+
+            var isAsyncTimeLimited = millisecsLimitAsync > 0;
+
+            // Doing either:
+            //  - full run through non-async (so not active and don't want to be)
+            //  - Starting async run-through
+            if (!_asyncContinueActive) {
+                _asyncContinueActive = isAsyncTimeLimited;
+				PrepareContinue ();
+            }
+
+            // Start timing
+            var durationStopwatch = new Stopwatch ();
+            durationStopwatch.Start ();
+
+            bool outputStreamEndsInNewline = false;
+            do {
+
+                try {
+                    outputStreamEndsInNewline = ContinueSingleStep ();
+                } catch(StoryException e) {
+                    AddError (e.Message, e.useEndLineNumber);
+                    break;
+                }
+
+                if (outputStreamEndsInNewline)
+                    break;
+
+                // Run out of async time?
+                if (_asyncContinueActive && durationStopwatch.ElapsedMilliseconds > millisecsLimitAsync) {
+                    break;
+                }
+
+            } while(canContinue);
+
+            durationStopwatch.Stop ();
+
+            // 4 outcomes:
+            //  - got newline (so finished this line of text)
+            //  - can't continue (e.g. choices or ending)
+            //  - ran out of time during evaluation
+            //  - error
+            //
+            // Successfully finished evaluation in time (or in error)
+            if (outputStreamEndsInNewline || !canContinue) {
+                CompleteContinue ();
+                _asyncContinueActive = false;
+            }
+
+            if( _profiler != null )
+                _profiler.PostContinue();
+        }
+
+        void PrepareContinue ()
+        {
+            if (!canContinue) {
                 throw new StoryException ("Can't continue - should check canContinue before calling Continue");
             }

-			if( _profiler != null )
-				_profiler.PreContinue();
-
             _state.ResetOutput ();

             _state.didSafeExit = false;

             _state.variablesState.batchObservingVariableChanges = true;
-
-            //_previousContainer = null;
-
-            try {
-
-                StoryState stateAtLastNewline = null;
-
-                // The basic algorithm here is:
-                //
-                //     do { Step() } while( canContinue && !outputStreamEndsInNewline );
-                //
-                // But the complexity comes from:
-                //  - Stepping beyond the newline in case it'll be absorbed by glue later
-                //  - Ensuring that non-text content beyond newlines are generated - i.e. choices,
-                //    which are actually built out of text content.
-                // So we have to take a snapshot of the state, continue prospectively,
-                // and rewind if necessary.
-                // This code is slightly fragile :-/
-                //
-
-                do {
-
-					if( _profiler != null )
-						_profiler.PreStep();
-
-                    // Run main step function (walks through content)
-                    Step();
-
-					if( _profiler != null )
-						_profiler.PostStep();
-
-                    // Run out of content and we have a default invisible choice that we can follow?
-					canContinue_cached = canContinue;
-					if( !canContinue_cached ) {
-                        TryFollowDefaultInvisibleChoice();
-						canContinue_cached = canContinue;
-                    }
-
-					if( _profiler != null )
-						_profiler.PreSnapshot();
-
-                    // Don't save/rewind during string evaluation, which is e.g. used for choices
-                    if( !state.inStringEvaluation ) {
-
-                        // We previously found a newline, but were we just double checking that
-                        // it wouldn't immediately be removed by glue?
-                        if( stateAtLastNewline != null ) {
-
-                            // Cover cases that non-text generated content was evaluated last step
-                            string currText = currentText;
-                            int prevTextLength = stateAtLastNewline.currentText.Length;
-
-                            // Take tags into account too, so that a tag following a content line:
-                            //   Content
-                            //   # tag
-                            // ... doesn't cause the tag to be wrongly associated with the content above.
-                            int prevTagCount = stateAtLastNewline.currentTags.Count;
-
-                            // Output has been extended?
-                            if( !currText.Equals(stateAtLastNewline.currentText) || prevTagCount != currentTags.Count ) {
-
-                                // Original newline still exists?
-                                if( currText.Length >= prevTextLength && currText[prevTextLength-1] == '\n' ) {
-
-                                    RestoreStateSnapshot(stateAtLastNewline);
-                                    break;
-                                }
-
-                                // Newline that previously existed is no longer valid - e.g.
-                                // glue was encounted that caused it to be removed.
-                                else {
-                                    stateAtLastNewline = null;
-                                }
-                            }
-
+        }
+
+
+
+
+        bool ContinueSingleStep ()
+        {
+            if (_profiler != null)
+                _profiler.PreStep ();
+
+            // Run main step function (walks through content)
+            Step ();
+
+            if (_profiler != null)
+                _profiler.PostStep ();
+
+            // Run out of content and we have a default invisible choice that we can follow?
+            if (!canContinue) {
+
+                TryFollowDefaultInvisibleChoice ();
+            }
+
+            if (_profiler != null)
+                _profiler.PreSnapshot ();
+
+            // Don't save/rewind during string evaluation, which is e.g. used for choices
+            if (!state.inStringEvaluation) {
+
+                // We previously found a newline, but were we just double checking that
+                // it wouldn't immediately be removed by glue?
+                if (_stateAtLastNewline != null) {
+
+                    // Cover cases that non-text generated content was evaluated last step
+                    string currText = currentText;
+                    int prevTextLength = _stateAtLastNewline.currentText.Length;
+
+                    // Take tags into account too, so that a tag following a content line:
+                    //   Content
+                    //   # tag
+                    // ... doesn't cause the tag to be wrongly associated with the content above.
+                    int prevTagCount = _stateAtLastNewline.currentTags.Count;
+
+                    // Output has been extended?
+                    if (!currText.Equals (_stateAtLastNewline.currentText) || prevTagCount != currentTags.Count) {
+
+                        // Original newline still exists?
+                        if (currText.Length >= prevTextLength && currText [prevTextLength - 1] == '\n') {
+                            RestoreStateSnapshot (_stateAtLastNewline);
+
+                            // Hit a newline for sure, we're done
+                            return true;
                         }

-                        // Current content ends in a newline - approaching end of our evaluation
-                        if( state.outputStreamEndsInNewline ) {
-
-                            // If we can continue evaluation for a bit:
-                            // Create a snapshot in case we need to rewind.
-                            // We're going to continue stepping in case we see glue or some
-                            // non-text content such as choices.
-							if( canContinue_cached ) {
-
-								// Don't bother to record the state beyond the current newline.
-								// e.g.:
-								// Hello world\n			// record state at the end of here
-								// ~ complexCalculation()   // don't actually need this unless it generates text
-								if( stateAtLastNewline == null )
-                                	stateAtLastNewline = StateSnapshot();
-                            }
-
-                            // Can't continue, so we're about to exit - make sure we
-                            // don't have an old state hanging around.
-                            else {
-                                stateAtLastNewline = null;
-                            }
-
-                        }
-
-                    }
-
-					if( _profiler != null )
-						_profiler.PostSnapshot();
-
-				} while(canContinue_cached);
-
-
-                // Need to rewind, due to evaluating further than we should?
-                if( stateAtLastNewline != null ) {
-
-					if( _profiler != null )
-						_profiler.PreRestore();
-
-                    RestoreStateSnapshot(stateAtLastNewline);
-
-					if( _profiler != null )
-						_profiler.PostRestore();
-                }
-
-                // Finished a section of content / reached a choice point?
-                if( !canContinue ) {
-
-                    if( state.callStack.canPopThread ) {
-                        Error("Thread available to pop, threads should always be flat by the end of evaluation?");
-                    }
-
-					if( state.generatedChoices.Count == 0 && !state.didSafeExit && _temporaryEvaluationContainer == null ) {
-                        if( state.callStack.CanPop(PushPopType.Tunnel) ) {
-                            Error("unexpectedly reached end of content. Do you need a '->->' to return from a tunnel?");
-                        } else if( state.callStack.CanPop(PushPopType.Function) ) {
-                            Error("unexpectedly reached end of content. Do you need a '~ return'?");
-                        } else if( !state.callStack.canPop ) {
-                            Error("ran out of content. Do you need a '-> DONE' or '-> END'?");
-                        } else {
-                            Error("unexpectedly reached end of content for unknown reason. Please debug compiler!");
+                        // Newline that previously existed is no longer valid - e.g.
+                        // glue was encounted that caused it to be removed.
+                        else {
+                            _stateAtLastNewline = null;
                         }
                     }

                 }

-
-            } catch(StoryException e) {
-                AddError (e.Message, e.useEndLineNumber);
-            } finally {
-
-                state.didSafeExit = false;
-
-                _state.variablesState.batchObservingVariableChanges = false;
-            }
-
-			if( _profiler != null )
-				_profiler.PostContinue();
-
-            return currentText;
-		}
+                // Current content ends in a newline - approaching end of our evaluation
+                if (state.outputStreamEndsInNewline) {
+
+                    // If we can continue evaluation for a bit:
+                    // Create a snapshot in case we need to rewind.
+                    // We're going to continue stepping in case we see glue or some
+                    // non-text content such as choices.
+                    if (canContinue) {
+
+                        // Don't bother to record the state beyond the current newline.
+                        // e.g.:
+                        // Hello world\n            // record state at the end of here
+                        // ~ complexCalculation()   // don't actually need this unless it generates text
+                        if (_stateAtLastNewline == null)
+                            _stateAtLastNewline = StateSnapshot ();
+                    }
+
+                    // Can't continue, so we're about to exit - make sure we
+                    // don't have an old state hanging around.
+                    else {
+                        _stateAtLastNewline = null;
+                    }
+
+                }
+
+            }
+
+            if (_profiler != null)
+                _profiler.PostSnapshot ();
+
+            // outputStreamEndsInNewline = false
+            return false;
+        }
+
+        void CompleteContinue ()
+        {
+            // Need to rewind, due to evaluating further than we should?
+            if( _stateAtLastNewline != null ) {
+
+                if( _profiler != null )
+                    _profiler.PreRestore();
+
+				RestoreStateSnapshot (_stateAtLastNewline);
+                _stateAtLastNewline = null;
+
+                if( _profiler != null )
+                    _profiler.PostRestore();
+            }
+
+            // Finished a section of content / reached a choice point?
+            if( !canContinue ) {
+
+                if( state.callStack.canPopThread ) {
+
+					Error ("Thread available to pop, threads should always be flat by the end of evaluation?");
+                }
+
+                if( state.generatedChoices.Count == 0 && !state.didSafeExit && _temporaryEvaluationContainer == null ) {
+                    if( state.callStack.CanPop(PushPopType.Tunnel) ) {
+
+						Error ("unexpectedly reached end of content. Do you need a '->->' to return from a tunnel?");
+                    } else if( state.callStack.CanPop(PushPopType.Function) ) {
+
+						Error ("unexpectedly reached end of content. Do you need a '~ return'?");
+                    } else if( !state.callStack.canPop ) {
+
+						Error ("ran out of content. Do you need a '-> DONE' or '-> END'?");
+                    } else {
+
+						Error ("unexpectedly reached end of content for unknown reason. Please debug compiler!");
+                    }
+                }
+
+            }
+
+            state.didSafeExit = false;
+
+            _state.variablesState.batchObservingVariableChanges = false;
+        }
+
+  //      string ContinueInternal()
+		//{
+  //          //         PrepareContinue ();
+
+  //          //         try {
+
+  //          //             // The basic algorithm here is:
+  //          //             //
+  //          //             //     do { Step() } while( canContinue && !outputStreamEndsInNewline );
+  //          //             //
+  //          //             // But the complexity comes from:
+  //          //             //  - Stepping beyond the newline in case it'll be absorbed by glue later
+  //          //             //  - Ensuring that non-text content beyond newlines are generated - i.e. choices,
+  //          //             //    which are actually built out of text content.
+  //          //             // So we have to take a snapshot of the state, continue prospectively,
+  //          //             // and rewind if necessary.
+  //          //             // This code is slightly fragile :-/
+  //          //             //
+  //          //             do {
+
+  //          //                 bool outputStreamEndsInNewline = ContinueSingleStep ();
+  //          //                 if (outputStreamEndsInNewline) break;
+
+  //          //	} while(canContinue);
+
+  //          //             CompleteContinue ();
+
+  //          //         } catch(StoryException e) {
+  //          //             AddError (e.Message, e.useEndLineNumber);
+  //          //         } finally {
+
+  //          //             state.didSafeExit = false;
+
+  //          //             _state.variablesState.batchObservingVariableChanges = false;
+  //          //         }
+
+  //          //if( _profiler != null )
+  //          //	_profiler.PostContinue();
+
+  //          ContinueInternalLimited ();
+
+  //          return currentText;
+		//}

         /// <summary>
         /// Check whether more content is available if you were to call <c>Continue()</c> - i.e.
@@ -2104,6 +2201,9 @@

         StoryState _state;

+        bool _asyncContinueActive;
+        StoryState _stateAtLastNewline = null;
+
 		Profiler _profiler;
 	}
 }


*Added documentation comments to this class

*Changed class operations to match changes in IParameterBuilder

--- projects/Core/Implementation/ParameterBuilder.cs
+++ projects/Core/Implementation/ParameterBuilder.cs
@@ -4,12 +4,35 @@

 namespace LateBindingHelper.Implementation
 {
+    /// <summary>
+    ///
+    /// </summary>
     public class ParameterBuilder : IParameterBuilder
     {
+        #region Private Members
+        /// <summary>
+        /// Holds the list of parameters
+        /// </summary>
         private List<object> _parameters = new List<object>();
-        private List<bool> _isRef = new List<bool>();
+
+        /// <summary>
+        /// Holds which position in the list of parameters
+        /// is passed with by reference semantics of by value
+        /// semantics
+        /// </summary>
+        private List<bool> _isRef = new List<bool>();
+        #endregion
+
         #region Miembros de IParameterList

+        /// <summary>
+        /// Adds a parameter to the list which is meant to be called using by value semantics.
+        /// </summary>
+        /// <param name="value">An object with the parameter value.</param>
+        /// <returns>
+        /// A reference to the <see cref="IParameterBuilder"/>instance which
+        /// called this method.
+        /// </returns>
         public IParameterBuilder AddParameter(object value)
         {
             _parameters.Add(value);
@@ -18,6 +41,14 @@
             return this;
         }

+        /// <summary>
+        /// Adds a parameter to the list which is meant to be called using by reference semantics.
+        /// </summary>
+        /// <param name="value">An object with the parameter value.</param>
+        /// <returns>
+        /// A reference to the <see cref="IParameterBuilder"/>instance which
+        /// called this method.
+        /// </returns>
         public IParameterBuilder AddRefParameter(object value)
         {

@@ -27,27 +58,29 @@
             return this;
         }

+        /// <summary>
+        /// Removes all parameters in the list
+        /// </summary>
         public void Clear()
         {
             _parameters.Clear();
             _isRef.Clear();
         }
-        public object[] AsArray
+
+        /// <summary>
+        /// Access the parameter list as an array
+        /// </summary>
+        /// <returns></returns>
+        public object[] GetParametersAsArray()
         {
-            get
-            {
-                return _parameters.ToArray();
-            }
-
-            set
-            {
-                for (int i = 0; i <value.Length; ++i)
-                {
-                    _parameters[i] = value[i];
-                }
-            }
+            return _parameters.ToArray();
         }

+        /// <summary>
+        /// Indexer to the parameter list
+        /// </summary>
+        /// <value></value>
+        /// <returns>The parameter </returns>
         public object this[int index]
         {
             get
@@ -56,11 +89,23 @@
             }
         }

-        public IList<bool> ISReferenceParameter
+        /// <summary>
+        /// Gets a list of booleans with the same length as the total
+        /// number of parameters in the list. Each position in the
+        /// array of booleans has the value <c>true</c> or <c>false</c>
+        /// if the parameter with the same position index
+        /// is passed by reference or not respectively.
+        /// </summary>
+        /// <returns>An IList of booleans.</returns>
+        public IList<bool> GetReferenceParameterList()
         {
-            get { return _isRef.AsReadOnly();  }
+            return _isRef.AsReadOnly();
         }

+        /// <summary>
+        /// Returns the total number of parameters in the list.
+        /// </summary>
+        /// <value></value>
         public int Count
         {
             get { return _parameters.Count; }


メモリリークを…防げたのか？

メモリリークを…防げたのか？

--- WPFTests/RectangleTest.xaml.cs
+++ WPFTests/RectangleTest.xaml.cs
@@ -53,6 +53,7 @@
                         Stretch = Stretch.Fill,
                         Viewbox = new Rect(random.Next(5) * 0.2, 0, 0.2, 1),
                     };
+                    brush.Freeze();
                     rectMap[x, y] = new Rectangle()
                     {
                         Width = 32 * vs,


Login page with bootstrap

Login page with bootstrap

--- WUI/Views/Account/Login.cshtml
+++ WUI/Views/Account/Login.cshtml
@@ -5,44 +5,35 @@
 }

 <hgroup class="title">
-
@ViewBag.Title.

+
@ViewBag.Title

 </hgroup>

-
Utilisez un compte local pour vous connecter.

 @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
     @Html.AntiForgeryToken()
     @Html.ValidationSummary(true)

-    <fieldset>
-        <legend>Formulaire de connexion</legend>
-

-

-                @Html.LabelFor(m => m.UserName)
-                @Html.TextBoxFor(m => m.UserName)
-                @Html.ValidationMessageFor(m => m.UserName)
-

-

-                @Html.LabelFor(m => m.Password)
-                @Html.PasswordFor(m => m.Password)
-                @Html.ValidationMessageFor(m => m.Password)
-

-

-                @Html.CheckBoxFor(m => m.RememberMe)
-                @Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" })
-

-

-        <input type="submit" value="Se connecter" />
-    </fieldset>
-

-        @Html.ActionLink("Register", "Register") si vous n’avez pas de compte.
-

+

+        @Html.LabelFor(m => m.UserName)
+        @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
+        @Html.ValidationMessageFor(m => m.UserName)
+

+
+

+        @Html.LabelFor(m => m.Password)
+        @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
+        @Html.ValidationMessageFor(m => m.Password)
+

+
+

+
+            @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe)
+
+

+
+    <button type="submit" class="btn btn-default">Se connecter</button>
+
 }
-

-
-

-
Utilisez un autre service pour vous connecter.

-    @Html.Action("ExternalLoginsList", new { ReturnUrl = ViewBag.ReturnUrl })

 @section Scripts {


Lower feerate in test

Lower feerate in test

--- WalletWasabi.Tests/RegTests.cs
+++ WalletWasabi.Tests/RegTests.cs
@@ -2259,7 +2259,7 @@
 			decimal coordinatorFeePercent = 0.1m;
 			int anonymitySet = 100;
 			int connectionConfirmationTimeout = 120;
-			var roundConfig = new CcjRoundConfig(denomination, 140, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 50, 50, 1);
+			var roundConfig = new CcjRoundConfig(denomination, 1008, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 50, 50, 1);
 			coordinator.UpdateRoundConfig(roundConfig);
 			coordinator.FailAllRoundsInInputRegistration();
 			await rpc.GenerateAsync(100); // So to make sure we have enough money.


Replace direct input calls with aliceclient calls

--- WalletWasabi.Tests/RegTests.cs
+++ WalletWasabi.Tests/RegTests.cs
@@ -1701,23 +1701,14 @@
 				roundState = await satoshiClient.GetRoundStateAsync(roundId);
 				Assert.Equal(CcjRoundPhase.ConnectionConfirmation, roundState.Phase);
 				Assert.Equal(2, roundState.RegisteredPeerCount);
-
-
-				using (var response = await torClient.SendAsync(HttpMethod.Post, "/api/v1/btc/chaumiancoinjoin/inputs/", inputsRequest.ToHttpStringContent()))
-				{
-					Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
-					string message = await response.Content.ReadAsJsonAsync<string>();
-					Assert.Equal("Input is already registered in another round.", message);
-				}
+
+				httpRequestException = await Assert.ThrowsAsync<HttpRequestException>(async () => await aliceClient.PostInputsAsync(inputsRequest));
+				Assert.Equal($"{HttpStatusCode.BadRequest.ToReasonString()}\nInput is already registered in another round.", httpRequestException.Message);

 				// Wait until input registration times out.
 				await Task.Delay(3000);
-				using (var response = await torClient.SendAsync(HttpMethod.Post, "/api/v1/btc/chaumiancoinjoin/inputs/", inputsRequest.ToHttpStringContent()))
-				{
-					Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
-					string message = await response.Content.ReadAsJsonAsync<string>();
-					Assert.StartsWith("Input is banned from participation for", message);
-				}
+				httpRequestException = await Assert.ThrowsAsync<HttpRequestException>(async () => await aliceClient.PostInputsAsync(inputsRequest));
+				Assert.StartsWith($"{HttpStatusCode.BadRequest.ToReasonString()}\nInput is banned from participation for", httpRequestException.Message);

 				states = await satoshiClient.GetAllRoundStatesAsync();
 				foreach (var rs in states.Where(x => x.Phase == CcjRoundPhase.InputRegistration))
@@ -1748,20 +1739,14 @@
 				}
 				scriptBytes = new Key().PubKey.GetSegwitAddress(network).ScriptPubKey.ToBytes();
 				(BlindingFactor, BlindedData) = blindingKey.PubKey.Blind(scriptBytes);
-				inputsRequest.BlindedOutputScriptHex = ByteHelpers.ToHex(BlindedData);
-				proof = key.SignMessage(inputsRequest.BlindedOutputScriptHex);
-				inputsRequest.Inputs = new List<InputProofModel> { new InputProofModel { Input = new OutPoint(hash, index), Proof = proof } };
-				Guid uniqueAliceId = Guid.Empty;
-				using (var response = await torClient.SendAsync(HttpMethod.Post, "/api/v1/btc/chaumiancoinjoin/inputs/", inputsRequest.ToHttpStringContent()))
-				{
-					Assert.Equal(HttpStatusCode.OK, response.StatusCode);
-					var inputsResp = await response.Content.ReadAsJsonAsync<InputsResponse>();
-					Assert.NotNull(inputsResp.BlindedOutputSignature);
-					Assert.NotEqual(Guid.Empty, inputsResp.UniqueId);
-					uniqueAliceId = inputsResp.UniqueId;
-					Assert.True(inputsResp.RoundId > 0);
-					roundId = inputsResp.RoundId;
-				}
+
+				inputsResponse = await aliceClient.PostInputsAsync(new Key().ScriptPubKey, BlindedData, new InputProofModel { Input = new OutPoint(hash, index), Proof = key.SignMessage(ByteHelpers.ToHex(BlindedData)) });
+
+				Assert.NotNull(inputsResponse.BlindedOutputSignature);
+				Assert.NotEqual(Guid.Empty, inputsResponse.UniqueId);
+				Guid uniqueAliceId = inputsResponse.UniqueId;
+				Assert.True(inputsResponse.RoundId > 0);
+				roundId = inputsResponse.RoundId;
 				using (var response = await torClient.SendAsync(HttpMethod.Post, $"/api/v1/btc/chaumiancoinjoin/confirmation?uniqueId={uniqueAliceId}&roundId={roundId}"))
 				{
 					Assert.True(response.IsSuccessStatusCode);
@@ -1834,16 +1819,13 @@
 					Assert.Equal("Round is not running.", await response.Content.ReadAsJsonAsync<string>());
 				}

-				using (var response = await torClient.SendAsync(HttpMethod.Post, "/api/v1/btc/chaumiancoinjoin/inputs/", inputsRequest.ToHttpStringContent()))
-				{
-					Assert.Equal(HttpStatusCode.OK, response.StatusCode);
-					var inputsResp = await response.Content.ReadAsJsonAsync<InputsResponse>();
-					Assert.NotNull(inputsResp.BlindedOutputSignature);
-					Assert.NotEqual(Guid.Empty, inputsResp.UniqueId);
-					uniqueAliceId = inputsResp.UniqueId;
-					Assert.True(inputsResp.RoundId > 0);
-					roundId = inputsResp.RoundId;
-				}
+				inputsResponse = await aliceClient.PostInputsAsync(new Key().ScriptPubKey, BlindedData, new InputProofModel { Input = new OutPoint(hash, index), Proof = key.SignMessage(ByteHelpers.ToHex(BlindedData)) });
+				Assert.NotNull(inputsResponse.BlindedOutputSignature);
+				Assert.NotEqual(Guid.Empty, inputsResponse.UniqueId);
+				uniqueAliceId = inputsResponse.UniqueId;
+				Assert.True(inputsResponse.RoundId > 0);
+				roundId = inputsResponse.RoundId;
+
 				using (var response = await torClient.SendAsync(HttpMethod.Post, $"/api/v1/btc/chaumiancoinjoin/confirmation?uniqueId={uniqueAliceId}&roundId={roundId}"))
 				{
 					Assert.True(response.IsSuccessStatusCode);
@@ -1909,39 +1891,17 @@

 				var input1 = new OutPoint(hash1, index1);
 				var input2 = new OutPoint(hash2, index2);
-				var request1 = new InputsRequest
-				{
-					BlindedOutputScriptHex = blindedOutputScriptHex1,
-					Inputs = new List<InputProofModel> { new InputProofModel { Input = input1, Proof = key1.SignMessage(blindedOutputScriptHex1) } },
-					ChangeOutputScript = new Key().ScriptPubKey.ToString()
-				};
-				var request2 = new InputsRequest
-				{
-					BlindedOutputScriptHex = blindedOutputScriptHex2,
-					Inputs = new List<InputProofModel> { new InputProofModel { Input = input2, Proof = key2.SignMessage(blindedOutputScriptHex2) } },
-					ChangeOutputScript = new Key().ScriptPubKey.ToString()
-				};
-
-				Guid uniqueAliceId1 = Guid.Empty;
-				Guid uniqueAliceId2 = Guid.Empty;
-				byte[] unblindedSignature1 = null;
-				byte[] unblindedSignature2 = null;
-				using (var response = await torClient.SendAsync(HttpMethod.Post, "/api/v1/btc/chaumiancoinjoin/inputs/", request1.ToHttpStringContent()))
-				{
-					Assert.Equal(HttpStatusCode.OK, response.StatusCode);
-					var inputsResp = await response.Content.ReadAsJsonAsync<InputsResponse>();
-					uniqueAliceId1 = inputsResp.UniqueId;
-					roundId = inputsResp.RoundId;
-					unblindedSignature1 = blindingKey.PubKey.UnblindSignature(inputsResp.BlindedOutputSignature, blinded1.BlindingFactor);
-				}
-				using (var response = await torClient.SendAsync(HttpMethod.Post, "/api/v1/btc/chaumiancoinjoin/inputs/", request2.ToHttpStringContent()))
-				{
-					Assert.Equal(HttpStatusCode.OK, response.StatusCode);
-					var inputsResp = await response.Content.ReadAsJsonAsync<InputsResponse>();
-					uniqueAliceId2 = inputsResp.UniqueId;
-					Assert.Equal(roundId, inputsResp.RoundId);
-					unblindedSignature2 = blindingKey.PubKey.UnblindSignature(inputsResp.BlindedOutputSignature, blinded2.BlindingFactor);
-				}
+
+				inputsResponse = await aliceClient.PostInputsAsync(new Key().ScriptPubKey, blinded1.BlindedData, new InputProofModel { Input = input1, Proof = key1.SignMessage(blindedOutputScriptHex1) });
+				Guid uniqueAliceId1 = inputsResponse.UniqueId;
+				roundId = inputsResponse.RoundId;
+				byte[] unblindedSignature1 = blindingKey.PubKey.UnblindSignature(inputsResponse.BlindedOutputSignature, blinded1.BlindingFactor);
+
+				inputsResponse = await aliceClient.PostInputsAsync(new Key().ScriptPubKey, blinded2.BlindedData, new InputProofModel { Input = input2, Proof = key2.SignMessage(blindedOutputScriptHex2) });
+				Guid uniqueAliceId2 = inputsResponse.UniqueId;
+				Assert.Equal(roundId, inputsResponse.RoundId);
+				byte[] unblindedSignature2 = blindingKey.PubKey.UnblindSignature(inputsResponse.BlindedOutputSignature, blinded2.BlindingFactor);
+
 				var roundHash = "";
 				using (var response = await torClient.SendAsync(HttpMethod.Post, $"/api/v1/btc/chaumiancoinjoin/confirmation?uniqueId={uniqueAliceId1}&roundId={roundId}"))
 				{


Updated xml-docs for AddNLog-methods to instead use AddNLogWeb (#669)

--- src/NLog.Web.AspNetCore/AspNetExtensions.cs
+++ src/NLog.Web.AspNetCore/AspNetExtensions.cs
@@ -134,8 +134,9 @@
         }

         /// <summary>
-        /// Apply NLog configuration from XML config.
-        /// </summary>
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and explicit load NLog.config from path
+        /// </summary>
+        /// <remarks>Recommended to use AddNLogWeb() to avoid name-collission issue with NLog.Extension.Logging namespace</remarks>
         /// <param name="builder">The logging builder</param>
         /// <param name="configFileName">Path to NLog configuration file, e.g. nlog.config. </param>
         public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, string configFileName)
@@ -144,7 +145,7 @@
         }

         /// <summary>
-        /// Apply NLog configuration from XML config.
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and explicit load NLog.config from path
         /// </summary>
         /// <param name="builder">The logging builder</param>
         /// <param name="configFileName">Path to NLog configuration file, e.g. nlog.config. </param>
@@ -161,8 +162,9 @@
         }

         /// <summary>
-        /// Configure NLog from API
-        /// </summary>
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and explicit load NLog LoggingConfiguration
+        /// </summary>
+        /// <remarks>Recommended to use AddNLogWeb() to avoid name-collission issue with NLog.Extension.Logging namespace</remarks>
         /// <param name="builder">The logging builder</param>
         /// <param name="configuration">Config for NLog</param>
         public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, LoggingConfiguration configuration)
@@ -171,7 +173,7 @@
         }

         /// <summary>
-        /// Configure NLog from API
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and explicit load NLog LoggingConfiguration
         /// </summary>
         /// <param name="builder">The logging builder</param>
         /// <param name="configuration">Config for NLog</param>
@@ -181,8 +183,9 @@
         }

         /// <summary>
-        /// Configure NLog from API
-        /// </summary>
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and explicit load NLog LoggingConfiguration
+        /// </summary>
+        /// <remarks>Recommended to use AddNLogWeb() to avoid name-collission issue with NLog.Extension.Logging namespace</remarks>
         /// <param name="builder">The logging builder</param>
         /// <param name="configuration">Config for NLog</param>
         /// <param name="options">Options for registration of the NLog LoggingProvider and enabling features.</param>
@@ -192,7 +195,7 @@
         }

         /// <summary>
-        /// Configure NLog from API
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and explicit load NLog LoggingConfiguration
         /// </summary>
         /// <param name="builder">The logging builder</param>
         /// <param name="configuration">Config for NLog</param>
@@ -211,8 +214,9 @@
         }

         /// <summary>
-        /// Enable NLog as logging provider for Microsoft Extension Logging
-        /// </summary>
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and provide isolated LogFactory
+        /// </summary>
+        /// <remarks>Recommended to use AddNLogWeb() to avoid name-collission issue with NLog.Extension.Logging namespace</remarks>
         /// <param name="builder"></param>
         /// <param name="factoryBuilder">Initialize NLog LogFactory with NLog LoggingConfiguration.</param>
         public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, Func<IServiceProvider, LogFactory> factoryBuilder)
@@ -221,7 +225,7 @@
         }

         /// <summary>
-        /// Enable NLog as logging provider for Microsoft Extension Logging
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and provide isolated LogFactory
         /// </summary>
         /// <param name="builder"></param>
         /// <param name="factoryBuilder">Initialize NLog LogFactory with NLog LoggingConfiguration.</param>
@@ -239,7 +243,7 @@
         }

         /// <summary>
-        /// Configure NLog from API
+        /// Enable NLog as logging provider for Microsoft Extension Logging, and provide isolated LogFactory
         /// </summary>
         /// <param name="builder">The logging builder</param>
         /// <param name="logFactory">NLog LogFactory</param>
@@ -256,7 +260,7 @@
         }

         /// <summary>
-        /// Use NLog for Dependency Injected loggers.
+        /// Enable NLog as logging provider for Microsoft Extension Logging.
         /// </summary>
         public static IWebHostBuilder UseNLog(this IWebHostBuilder builder)
         {
@@ -264,7 +268,7 @@
         }

         /// <summary>
-        /// Use NLog for Dependency Injected loggers.
+        /// Enable NLog as logging provider for Microsoft Extension Logging.
         /// </summary>
         /// <param name="builder"></param>
         /// <param name="options">Options for registration of the NLog LoggingProvider and enabling features.</param>
@@ -280,7 +284,7 @@
         }

         /// <summary>
-        /// Use NLog for Dependency Injected loggers.
+        /// Enable NLog as logging provider for Microsoft Extension Logging.
         /// </summary>
         public static IHostBuilder UseNLog(this IHostBuilder builder)
         {
@@ -288,7 +292,7 @@
         }

         /// <summary>
-        /// Use NLog for Dependency Injected loggers.
+        /// Enable NLog as logging provider for Microsoft Extension Logging.
         /// </summary>
         /// <param name="builder"></param>
         /// <param name="options">Options for registration of the NLog LoggingProvider and enabling features.</param>


reveal commented-out tests

reveal commented-out tests

--- src/NMoneys.Tests/MoneyTester.Arithmetic.cs
+++ src/NMoneys.Tests/MoneyTester.Arithmetic.cs
@@ -348,22 +348,21 @@
 		}

 #pragma warning disable 169
-		// TODO: check commented code
 		private static readonly TestCaseData[] _round =
 		{
-			/*new TestCaseData(CurrencyIsoCode.XTS, 2.345m, 2.34m).SetName("2 decimal places"),
+			new TestCaseData(CurrencyIsoCode.XTS, 2.345m, 2.34m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.USD, 2.345m, 2.34m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.JPY, 2.345m, 2m).SetName("0 decimal places"),

 			new TestCaseData(CurrencyIsoCode.XTS, 2.355m, 2.36m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.USD, 2.355m, 2.36m).SetName("2 decimal places"),
-			new TestCaseData(CurrencyIsoCode.JPY, 2.355m, 2m).SetName("0 decimal places"),*/
+			new TestCaseData(CurrencyIsoCode.JPY, 2.355m, 2m).SetName("0 decimal places"),

 			new TestCaseData(CurrencyIsoCode.XTS, 2m /3, 0.67m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.USD, 2m / 3, 0.67m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.JPY, 2m / 3, 1m).SetName("0 decimal places"),

-			/*new TestCaseData(CurrencyIsoCode.XTS, 0.5m, 0.50m).SetName("2 decimal places"),
+			new TestCaseData(CurrencyIsoCode.XTS, 0.5m, 0.50m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.USD, 0.5m, 0.50m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.JPY, 0.5m, 0m).SetName("0 decimal places"),

@@ -373,7 +372,7 @@

 			new TestCaseData(CurrencyIsoCode.XTS, 1.499999m, 1.50m).SetName("2 decimal places"),
 			new TestCaseData(CurrencyIsoCode.USD, 1.499999m, 1.50m).SetName("2 decimal places"),
-			new TestCaseData(CurrencyIsoCode.JPY, 1.499999m, 1m).SetName("0 decimal places"),*/
+			new TestCaseData(CurrencyIsoCode.JPY, 1.499999m, 1m).SetName("0 decimal places")
 		};
 #pragma warning restore 169


version upped to 1.1.1

version upped to 1.1.1

--- src/NadekoBot/Services/Impl/StatsService.cs
+++ src/NadekoBot/Services/Impl/StatsService.cs
@@ -15,7 +15,7 @@
         private DiscordShardedClient client;
         private DateTime started;

-        public const string BotVersion = "1.1.0";
+        public const string BotVersion = "1.1.1";

         public string Author => "Kwoth#2560";
         public string Library => "Discord.Net";


Fix human tag

Fix human tag

--- src/NetworkInterface/Discord/DiscordUser.cs
+++ src/NetworkInterface/Discord/DiscordUser.cs
@@ -61,7 +61,7 @@

         public override string GetHumanTag()
         {
-            return userInterface.NicknameMention;
+            return String.Format("@{0}#{1}", GetUsername(), userInterface.Discriminator);
         }

         public override void SendMessage(string message)


Avoid throwing exceptions when conditionally unwrapping oracle packages.

--- src/SJP.Schematic.Oracle/OracleUnwrapper.cs
+++ src/SJP.Schematic.Oracle/OracleUnwrapper.cs
@@ -30,16 +30,15 @@
                 return false;
             }

-            try
-            {
-                unwrapped = DecodeBase64Package(payload);
+            if (TryDecodeBase64Package(payload, out var decodedPackage)
+                && !string.IsNullOrWhiteSpace(decodedPackage))
+            {
+                unwrapped = decodedPackage;
                 return true;
             }
-            catch (InvalidDataException)
-            {
-                unwrapped = null;
-                return false;
-            }
+
+            unwrapped = null;
+            return false;
         }

         /// <summary>
@@ -70,7 +69,7 @@
             if (!TryGetPayload(input, out var payload))
                 throw new InvalidDataException("The given input is not a wrapped definition");

-            return DecodeBase64Package(payload);
+            return DecodeBase64PackageUnsafe(payload);
         }

         // The expected input is:
@@ -196,7 +195,7 @@
             }
         }

-        private static string DecodeBase64Package(string base64Input)
+        private static string DecodeBase64PackageUnsafe(string base64Input)
         {
             if (base64Input == null)
                 throw new ArgumentNullException(nameof(base64Input));
@@ -235,6 +234,51 @@
             var decompressed = writer.ToArray();
             var textResult = Encoding.UTF8.GetString(decompressed);
             return textResult.TrimEnd('\0'); // remove a trailing NUL char
+        }
+
+        private static bool TryDecodeBase64Package(string base64Input, out string? decodedPackage)
+        {
+            decodedPackage = null;
+
+            if (base64Input == null)
+                return false;
+
+            var bytes = Convert.FromBase64String(base64Input);
+
+            var mappedCharBuffer = new Span<byte>(new byte[bytes.Length]);
+            for (var i = 0; i < bytes.Length; i++)
+            {
+                mappedCharBuffer[i] = CharMap[bytes[i]];
+            }
+
+            const int hashSize = 20; // bytes
+            var hashBuffer = mappedCharBuffer[..hashSize];
+            var dataBuffer = mappedCharBuffer[hashSize..];
+
+            using (var sha1 = new SHA1Managed())
+            {
+                var computedHashBuffer = new Span<byte>(new byte[hashSize]);
+
+                var areEqual = sha1.TryComputeHash(dataBuffer, computedHashBuffer, out _)
+                    && computedHashBuffer.SequenceEqual(hashBuffer);
+
+                if (!areEqual)
+                    return false;
+            }
+
+            // need to skip zlib header bytes and trim trailing zlib checksum bytes to enable decompression
+            var trimmedBuffer = ZlibToDeflate(dataBuffer);
+
+            using var reader = new MemoryStream(trimmedBuffer.ToArray());
+            using var unzipper = new DeflateStream(reader, CompressionMode.Decompress);
+            using var writer = new MemoryStream(trimmedBuffer.Length);
+            unzipper.CopyTo(writer);
+
+            var decompressed = writer.ToArray();
+            var textResult = Encoding.UTF8.GetString(decompressed);
+            decodedPackage = textResult.TrimEnd('\0'); // remove a trailing NUL char
+
+            return true;
         }

         private static bool IsValidBase64String(string input)


fix wrong resolve of merge conflict

fix wrong resolve of merge conflict

--- Source/Examples/ExampleLibrary/Series/HistogramSeriesExamples.cs
+++ Source/Examples/ExampleLibrary/Series/HistogramSeriesExamples.cs
@@ -90,7 +90,9 @@
             Random rnd = new Random();

             HistogramSeries chs = new HistogramSeries();
-            chs.Items.AddRange(HistogramHelpers.Collect(SampleNormal(rnd, mean, std, n), -std * 4, std * 4, 100, true));
+            var binningOptions = new BinningOptions(BinningOutlierMode.CountOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues);
+            var binBreaks = HistogramHelpers.CreateUniformBins(-std * 4, std * 4, 100);
+            chs.Items.AddRange(HistogramHelpers.Collect(SampleNormal(rnd, mean, std, n), binBreaks, binningOptions));
             chs.StrokeThickness = 1;

             double LimitHi = mean + 1.96 * std;
@@ -132,7 +134,7 @@

             return model;
         }
-
+
         private static IEnumerable<double> SampleExps(Random rnd, double mean, int count)
         {
             for (int i = 0; i < count; i++)


Bug fix

Bug fix

--- Source/HelixToolkit.Wpf.SharpDX/Model/Elements3D/ItemsModel3D.cs
+++ Source/HelixToolkit.Wpf.SharpDX/Model/Elements3D/ItemsModel3D.cs
@@ -246,6 +246,10 @@
                         throw new InvalidOperationException("Cannot create a Model3D from ItemTemplate.");
                     }
                 }
+            }
+            if (UseOctreeHitTest && Children.Count > 0)
+            {
+                mOctreeManager.RequestRebuild();
             }
         }


Correct StyleCop errors in InterlacedView3D

--- Source/HelixToolkit.Wpf/Controls/Stereo/InterlacedView3D.xaml.cs
+++ Source/HelixToolkit.Wpf/Controls/Stereo/InterlacedView3D.xaml.cs
@@ -31,7 +31,7 @@
                 new UIPropertyMetadata(0.0, HorizontalOffsetChanged));

         /// <summary>
-        /// Identifies the <see cref="Method"/> dependency property.
+        /// Identifies the <see cref="EvenLeft"/> dependency property.
         /// </summary>
         public static readonly DependencyProperty EvenLeftProperty = DependencyProperty.Register(
             "EvenLeft", typeof(bool), typeof(InterlacedView3D), new UIPropertyMetadata(true));
@@ -67,6 +67,9 @@
             }
         }

+        /// <summary>
+        /// Updates the <see cref="EvenLeft"/> property based on the vertical position of the control.
+        /// </summary>
         public void UpdateEvenLeft()
         {
             if (this.IsLoaded)


Updated Sprite.cs

Updated Sprite.cs

--- Yetibyte.Himalaya/Graphics/Sprite.cs
+++ Yetibyte.Himalaya/Graphics/Sprite.cs
@@ -63,7 +63,7 @@

         // Methods

-        public virtual void Draw(SpriteBatch spriteBatch, GameTime gameTime) {
+        public virtual void Draw(SpriteBatch spriteBatch, Vector2 position) {


ZUGFeRD 2.1 update: trade allow charge profile awareness

--- ZUGFeRD/InvoiceDescriptor21Writer.cs
+++ ZUGFeRD/InvoiceDescriptor21Writer.cs
@@ -277,7 +277,7 @@
                         Writer.WriteEndElement();
                         #endregion

-                        _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason);
+                        _writeOptionalElementString(Writer, "ram:Reason", tradeAllowanceCharge.Reason, Profile.Extended | Profile.XRechnung);

                         Writer.WriteEndElement(); // !AppliedTradeAllowanceCharge
                     }


Impementation of GameMenu

Impementation of GameMenu

--- ScorpicoreRush/ScorpicoreRush/ScorpicoreRush.cs
+++ ScorpicoreRush/ScorpicoreRush/ScorpicoreRush.cs
@@ -18,7 +18,38 @@

     class ScorpicoreRush
     {
-
+        static int gamefieldWidth = 70;
+        static int windowWidth = 100;
+        static int windowHeight = 30;
+        static int playerLives = 10;
+        static int gameLevel = 1;
+        static int points = 0;
+        static void PrintOnPosition(int positionX, int positionY, char itemCharacter, ConsoleColor itemColor = ConsoleColor.Gray)
+        {
+            Console.ForegroundColor = itemColor;
+            Console.SetCursorPosition(positionX, positionY);
+            Console.Write(itemCharacter);
+        }
+        static void PrintTextInGameMenu(int positionX, int positionY, string menuText, ConsoleColor textColor = ConsoleColor.Gray)
+        {
+            Console.ForegroundColor = textColor;
+            Console.SetCursorPosition(positionX, positionY);
+            Console.Write(menuText);
+        }
+        static void DrawGameMenu()
+        {
+            for (int i = 0; i < Console.WindowHeight; i++)
+            {
+                PrintOnPosition(gamefieldWidth, i, '|');
+            }
+            PrintTextInGameMenu(gamefieldWidth + 1, 0, "-----------------------------");
+            PrintTextInGameMenu(gamefieldWidth + 4, 1, "*** SCORPICORE RUSH ***");
+            PrintTextInGameMenu(gamefieldWidth + 1, 2, "-----------------------------");
+            PrintTextInGameMenu(gamefieldWidth + 11, 4, "Points: " + points);
+            PrintTextInGameMenu(gamefieldWidth + 11, 6, "Lives: " + playerLives);
+            PrintTextInGameMenu(gamefieldWidth + 11, 8, "Level: " + gameLevel);
+
+        }
         static void Main()
         {
             int points = 0;
@@ -31,15 +62,17 @@
             HeroPosition.Enqueue(HeroStartPosition);

             Queue<Position> bulletPosition = new Queue<Position>();
-
+
+

             string hero = "<^>";
             string bullet = "o";

             Console.CursorVisible = false;
-            Console.BufferHeight = Console.WindowHeight;
-            Console.BufferWidth = Console.WindowWidth;
+            Console.BufferHeight = Console.WindowHeight = windowHeight;
+            Console.BufferWidth = Console.WindowWidth = windowWidth;

+            DrawGameMenu();
             //moving the Hero

             Console.ForegroundColor = ConsoleColor.DarkYellow;      //<---------Eventually change color with levels