isolate possible exception on ActivateWindow

--- Assets/Plugins/Editor/RiderUnityIntegration.cs
+++ Assets/Plugins/Editor/RiderUnityIntegration.cs
@@ -144,7 +144,16 @@
       proc.Start();

       if (new FileInfo(riderPath).Extension == ".exe")
-        ActivateWindow();
+      {
+        try
+        {
+          ActivateWindow();
+        }
+        catch (Exception e)
+        {
+          Debug.Log("Exception on ActivateWindow: " + e);
+        }
+      }
     }

     private static void ActivateWindow()


add String to Decimal Ext

add String to Decimal Ext

--- src/Aardvark.Base/Extensions/StringExtensions.cs
+++ src/Aardvark.Base/Extensions/StringExtensions.cs
@@ -100,6 +100,23 @@
         public static DateTime ToDateTime(this string self)
         {
             return DateTime.Parse(self, Localization.FormatEnUS);
+        }
+
+        public static decimal ToDecimal(this string self, decimal def)
+        {
+            decimal result;
+
+            if (!decimal.TryParse(self, out result))
+            {
+                result = def;
+            }
+
+            return result;
+        }
+
+        public static decimal ToDecimal(this string self)
+        {
+            return decimal.Parse(self, Localization.FormatEnUS);
         }

         #endregion


This is done

This is done

--- MyQuizBackend/src/MYVote/Classes/ExceptionHandler.cs
+++ MyQuizBackend/src/MYVote/Classes/ExceptionHandler.cs
@@ -30,8 +30,6 @@
     {
         if (exception == null) return;

-        //TODO log exception to some logfile
-
         var code = HttpStatusCode.InternalServerError;

         writeExceptionToLogFile(exception);


Duration of sound is reduced

Duration of sound is reduced

in order not to slow the game


Shouldn't return from Catch, rethrow it

Shouldn't return from Catch, rethrow it

--- src/Aggregates.NET/Internal/ExceptionRejector.cs
+++ src/Aggregates.NET/Internal/ExceptionRejector.cs
@@ -47,7 +47,7 @@
             catch (Exception e)
             {
                 if (GetNumberOfFirstLevelRetries(context.PhysicalMessage) < _maxRetries)
-                    return;
+                    throw;

                 _errorsMeter.Mark();


Fixed bug with empty result

Fixed bug with empty result

--- BibliographicSystem/ParseMethod/ParseMethod.cs
+++ BibliographicSystem/ParseMethod/ParseMethod.cs
@@ -11,16 +11,19 @@

 namespace BibliographicSystem.ParseMethod
 {
+    /// <summary>
+    /// Class for parsing Google.Scholar
+    /// </summary>
     public class ParseMethod
     {
-        public string GetQueryUrl(string query)
+        private string GetQueryUrl(string query)
         {
             query = HttpUtility.UrlEncode(query);
             const string url = "http://scholar.google.com/scholar?hl=en&q=";
             query = string.Concat(url, query);
             return query;
         }
-
+
         private string GetPageContent(string url)
         {
             var request = (HttpWebRequest)WebRequest.Create(url);
@@ -148,6 +151,11 @@
             return bibtex;
         }

+        /// <summary>
+        /// Main class method
+        /// </summary>
+        /// <param name="query"> String from text box </param>
+        /// <returns> List of articles from Google.Scholar </returns>
         public List<ScholarArticle> GetScholarArticlesByQuery(string query)
         {
             // getting page content from scholar page (with given query)
@@ -160,7 +168,7 @@
             var doc = new HtmlDocument();
             doc.LoadHtml(pageContent);

-            for (var i = 1; i <= 10; i++)
+            for (var i = 1; i <= 11; i++)
             {
                 var article = new ScholarArticle();
                 var xPathBiblioCheck = $"//*[@id='gs_ccl_results']/div[{i}]/div[2]";
@@ -187,7 +195,7 @@
                     var citiationsCheck = doc.DocumentNode.SelectSingleNode(xPathCitiations).InnerText;
                     article.Citiations = citiationsCheck.StartsWith("Cited by") ? citiationsCheck : "No citiations for this article. ";

-                    scholarArticles.Insert(i - 1, article);
+                    scholarArticles.Add(article);
                 }
                 else
                 {
@@ -207,7 +215,7 @@
                         var citiationsCheck = doc.DocumentNode.SelectSingleNode(xPathCitiations).InnerText;
                         article.Citiations = citiationsCheck.StartsWith("Cited by") ? citiationsCheck : "No citiations for this article. ";

-                        scholarArticles.Insert(i - 1, article);
+                        scholarArticles.Add(article);
                     }

                     else
@@ -216,20 +224,23 @@
                         var xPathTitleCheck = $"//*[@id='gs_ccl_results']/div[{i}]/div/h3";
                         var xPathSpanNode = $"//*[@id='gs_ccl_results']/div[{i}]/div/h3/span";
                         var titleMatchNode = doc.DocumentNode.SelectSingleNode(xPathTitleCheck);
-                        var spanNode = doc.DocumentNode.SelectSingleNode(xPathSpanNode);
-                        titleMatchNode.RemoveChild(spanNode);
-                        article.Title = titleMatchNode.InnerText;
-
-                        string xPathInfo = $"//*[@id='gs_ccl_results']/div[{i}]/div/div[1]";
-                        article.Info = doc.DocumentNode.SelectSingleNode(xPathInfo).InnerText;
-
-                        article.Reference = "This article does not have a reference";
-
-                        var xPathCitiations = $"//*[@id='gs_ccl_results']/div[{i}]/div/div[2]/a[1]";
-                        var citiationsCheck = doc.DocumentNode.SelectSingleNode(xPathCitiations).InnerText;
-                        article.Citiations = citiationsCheck.StartsWith("Cited by") ? citiationsCheck : "No citiations for this article. ";
-
-                        scholarArticles.Insert(i - 1, article);
+                        if (titleMatchNode != null)
+                        {
+                            var spanNode = doc.DocumentNode.SelectSingleNode(xPathSpanNode);
+                            titleMatchNode.RemoveChild(spanNode);
+                            article.Title = titleMatchNode.InnerText;
+
+                            string xPathInfo = $"//*[@id='gs_ccl_results']/div[{i}]/div/div[1]";
+                            article.Info = doc.DocumentNode.SelectSingleNode(xPathInfo).InnerText;
+
+                            article.Reference = "This article does not have a reference";
+
+                            var xPathCitiations = $"//*[@id='gs_ccl_results']/div[{i}]/div/div[2]/a[1]";
+                            var citiationsCheck = doc.DocumentNode.SelectSingleNode(xPathCitiations).InnerText;
+                            article.Citiations = citiationsCheck.StartsWith("Cited by") ? citiationsCheck : "No citiations for this article. ";
+
+                            scholarArticles.Add(article);
+                        }
                     }
                 }
             }


Fix paths with whitespace

Fix paths with whitespace

--- OpenKh.Tools.ModsManager/ViewModels/MainViewModel.cs
+++ OpenKh.Tools.ModsManager/ViewModels/MainViewModel.cs
@@ -151,7 +151,7 @@
                         {
                             FileName = ConfigurationService.Pcsx2Location,
                             WorkingDirectory = Path.GetDirectoryName(ConfigurationService.Pcsx2Location),
-                            Arguments = ConfigurationService.IsoLocation
+                            Arguments = $"\"{ConfigurationService.IsoLocation}\""
                         }));
                         break;
                     case 2:


Remove delaunay supertriangle after triangulation.

--- Blueprints/Datastructures/Geometry/Delaunay.cs
+++ Blueprints/Datastructures/Geometry/Delaunay.cs
@@ -95,9 +95,13 @@
             // This is a triangle which encompasses all the sample points.
             // The supertriangle coordinates are added to the end of the
             // vertex list.
-            Points.Add(new Pixel<T>(Math.Sub(xmid, Math.Mul2(dmax)), Math.Sub(ymid, dmax)));
-            Points.Add(new Pixel<T>(xmid,                            Math.Add(ymid, Math.Mul2(dmax))));
-            Points.Add(new Pixel<T>(Math.Add(xmid, Math.Mul2(dmax)), Math.Sub(ymid, dmax)));
+            var st1 = new Pixel<T>(Math.Sub(xmid, Math.Mul2(dmax)), Math.Sub(ymid, dmax));
+            var st2 = new Pixel<T>(xmid,                            Math.Add(ymid, Math.Mul2(dmax)));
+            var st3 = new Pixel<T>(Math.Add(xmid, Math.Mul2(dmax)), Math.Sub(ymid, dmax));
+
+            Points.Add(st1);
+            Points.Add(st2);
+            Points.Add(st3);

             // The supertriangle is the first triangle in the triangle list.
             var Triangles = new List<ITriangle<T>>();
@@ -191,16 +195,24 @@

             //T _NoP = (T) (Object) _NumberOfPixels;

-            //for (int i = Triangle2.Count - 1; i >= 0; i--)
-            //{
-
-            //    if (Triangle2[i].P1.IsLargerThanOrEquals(_NoP) ||
-            //        Triangle2[i].P2.IsLargerThanOrEquals(_NoP) ||
-            //        Triangle2[i].P3.IsLargerThanOrEquals(_NoP))
-
-            //        Triangle2.RemoveAt(i);
-
-            //}
+            for (int i = Triangles.Count - 1; i >= 0; i--)
+            {
+
+                if (Triangles[i].P1.Equals(st1) ||
+                    Triangles[i].P1.Equals(st2) ||
+                    Triangles[i].P2.Equals(st3) ||
+
+                    Triangles[i].P2.Equals(st1) ||
+                    Triangles[i].P2.Equals(st2) ||
+                    Triangles[i].P2.Equals(st3) ||
+
+                    Triangles[i].P3.Equals(st1) ||
+                    Triangles[i].P3.Equals(st2) ||
+                    Triangles[i].P3.Equals(st3))
+
+                    Triangles.RemoveAt(i);
+
+            }

             #endregion


Fixes a bug when in Places Query when the landing point was not a whole number.

--- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -1500,8 +1500,8 @@
                 QueryBlock.Desc = Utils.StringToBytes(((ILandObject)Places[i]).LandData.Description);
                 QueryBlock.Dwell = ((ILandObject)Places[i]).LandData.Dwell;
                 QueryBlock.Flags = 0;
-                QueryBlock.GlobalX = (float)Convert.ToInt32(Xs[i]);
-                QueryBlock.GlobalY = (float)Convert.ToInt32(Ys[i]);
+                QueryBlock.GlobalX = (float)Convert.ToDouble(Xs[i]);
+                QueryBlock.GlobalY = (float)Convert.ToDouble(Ys[i]);
                 QueryBlock.GlobalZ = 0;
                 QueryBlock.Name = Utils.StringToBytes(((ILandObject)Places[i]).LandData.Name);
                 QueryBlock.OwnerID = ((ILandObject)Places[i]).LandData.OwnerID;


Ensure route order - Use insert instead of add whan we register the PageRoute instance

--- BrickPile.Core/DefaultBrickPileBootstrapper.cs
+++ BrickPile.Core/DefaultBrickPileBootstrapper.cs
@@ -265,7 +265,8 @@
         /// <param name="routes">The routes.</param>
         protected void RegisterCustomRoutes(RouteCollection routes)
         {
-            routes.Add("PageRoute",
+            // ensure that the the PageRoute is first in the collection
+            routes.Insert(0,
                 new PageRoute(
                     new VirtualPathResolver(),
                     new RouteResolver(
@@ -305,6 +306,7 @@
                                 () =>
                                     ((MvcHandler) HttpContext.Current.Handler).RequestContext.RouteData.Values[
                                         PageRoute.CurrentPageKey] as IPage));
+
                 expression.For<IStructureInfo>()
                     .UseSpecial(
                         x =>


Added majority of opcodes

Added majority of opcodes

Still have to add input and fix some bugs, but most of the stuff is there

--- Chip8/Chip8.cs
+++ Chip8/Chip8.cs
@@ -2,6 +2,7 @@
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
 using System;
+using System.Collections.Generic;
 using System.IO;

 namespace Chip8
@@ -22,7 +23,6 @@
         ushort stackPointer;

         byte[,] display;
-        bool redraw;

         ushort delay;
         ushort soundDelay;
@@ -40,13 +40,12 @@
             counter = 0x200;

             registers = new ushort[16];
-            addressPointer = (char) 0x0;
+            addressPointer = (char)0x0;

             stack = new ushort[12];
             stackPointer = 0;

-            display = new byte[64,32];
-            redraw = true;
+            display = new byte[64, 32];

             delay = 0;
             soundDelay = 0;
@@ -76,12 +75,12 @@
             }
         }

-        private void LoadFile(string file)
+        private void LoadFile(string file)
         {
             using (Stream reader = File.OpenRead(file))
             {
                 int offset = 0;
-                while(reader.Position != reader.Length)
+                while (reader.Position != reader.Length)
                 {
                     memory[0x200 + offset] = (ushort)(reader.ReadByte() & 0xFF);
                     offset++;
@@ -103,13 +102,17 @@

         protected override void UnloadContent()
         {
-
+
         }

         protected override void Update(GameTime gameTime)
         {
-            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
+            KeyboardState state = Keyboard.GetState();
+
+            if (state.IsKeyDown(Keys.Escape))
+            {
                 Exit();
+            }

             //We need the opcode in the form of 0xXXXX
             //memory[counter] << 8 gets the first two parts of it, in the form of 0xXX, and shifts it to the left to form 0xXX00
@@ -144,14 +147,12 @@
                     }
                 case 0x1000:
                     {
-                        int address = opcode & 0x0FFF;
-                        counter = (ushort)address;
+                        counter = (ushort)(opcode & 0x0FFF);
                         break;
                     }
                 case 0x2000: //Call subroutine at 0x2NNN
                     {
                         ushort address = (ushort)(opcode & 0x0FFF);
-                        Console.WriteLine(address.ToString("x"));
                         stack[stackPointer] = counter;
                         stackPointer++;
                         counter = address;
@@ -173,34 +174,127 @@
                     }
                 case 0x4000:
                     {
+                        int x = (opcode & 0x0F00) >> 8;
+                        int nn = (opcode & 0x00FF);
+                        if (registers[x] != nn)
+                        {
+                            counter += 4;
+                        }
+                        else
+                        {
+                            counter += 2;
+                        }
                         break;
                     }
                 case 0x5000:
                     {
+                        int x = opcode & 0x0F00 >> 8;
+                        int y = opcode & 0x00F0 >> 4;
+                        if (registers[x] == registers[y])
+                        {
+                            counter += 4;
+                        }
+                        else
+                        {
+                            counter += 2;
+                        }
                         break;
                     }
                 case 0x6000:
                     {
                         ushort x = (ushort)((opcode & 0x0F00) >> 8);
-                        ushort NN = (ushort)(opcode & 0x00FF);
-                        registers[x] = NN;
+                        registers[x] = (ushort)(opcode & 0x00FF);
                         counter += 2;
                         break;
                     }
                 case 0x7000:
                     {
                         int x = (opcode & 0x0F00) >> 8;
-                        ushort nn = (ushort)(opcode & 0x00FF);
-                        registers[x] += nn;
+                        registers[x] = (ushort)((registers[x] + (opcode & 0x00FF)) & 0xFF);
                         counter += 2;
                         break;
                     }
                 case 0x8000:
                     {
+                        int x = opcode & 0x0F00 >> 8;
+                        int y = opcode & 0x00F0 >> 4;
+                        switch (opcode & 0x000F)
+                        {
+                            case 0x0000:
+                                {
+                                    registers[x] = registers[y];
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x0001:
+                                {
+                                    registers[x] |= registers[y];
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x0002:
+                                {
+                                    registers[x] &= registers[y];
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x0003:
+                                {
+                                    registers[x] ^= registers[y];
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x0004:
+                                {
+                                    registers[0xF] = (registers[y] > (255 - registers[x])) ? (ushort)1 : (ushort)0;
+                                    registers[x] = (ushort)((registers[y] + registers[x]) & 0xFF);
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x0005:
+                                {
+                                    registers[0xF] = (registers[x] > registers[y]) ? (ushort)1 : (ushort)0;
+                                    registers[x] = (ushort)((registers[x] - registers[y]) & 0xFF);
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x0006:
+                                {
+                                    ushort bit = (ushort)(registers[x] & 0x1);
+                                    registers[x] = (ushort)(registers[x] >> 1);
+                                    registers[0xF] = bit;
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x0007:
+                                {
+                                    registers[0xF] = (registers[x] > registers[y]) ? (ushort)0 : (ushort)1;
+                                    registers[x] = (ushort)((registers[y] - registers[x]) & 0xFF);
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x000E:
+                                {
+                                    registers[0xF] = (ushort)(registers[x] & 0x80);
+                                    registers[x] = (ushort)(registers[x] << 1);
+                                    counter += 2;
+                                    break;
+                                }
+                        }
                         break;
                     }
                 case 0x9000:
                     {
+                        int x = registers[(opcode & 0x0F00) >> 8];
+                        int y = registers[(opcode & 0x00F0) >> 4];
+                        if (x != y)
+                        {
+                            counter += 4;
+                        }
+                        else
+                        {
+                            counter += 2;
+                        }
                         break;
                     }
                 case 0xA000:
@@ -211,10 +305,16 @@
                     }
                 case 0xB000:
                     {
+                        addressPointer = (ushort)((opcode & 0x0FFF) + (registers[0] & 0xFF));
                         break;
                     }
                 case 0xC000:
                     {
+                        int x = (opcode & 0x0F00) >> 8;
+                        int nn = (opcode & 0x00FF);
+
+                        registers[x] = (ushort)(new Random().Next(256) & nn);
+                        counter += 2;
                         break;
                     }
                 case 0xD000:
@@ -223,19 +323,20 @@
                         int x = registers[(opcode & 0x0F00) >> 8];
                         int y = registers[(opcode & 0x00F0) >> 4];
                         int height = opcode & 0x000F;
-
                         registers[0xF] = 0;

-                        for(int _y = 0; _y < height; _y++)
+                        for (int _y = 0; _y < height; _y++)
                         {
                             ushort pixel = memory[addressPointer + _y];
                             for (int _x = 0; _x < 8; _x++)
                             {
-                                if((pixel & (0x80 >> _x)) != 0)
-                                {
-                                    if (display[x + _x, y + _y] == 1)
+                                if ((pixel & (0x80 >> _x)) != 0)
+                                {
+                                    int totalX = (x + _x) % 64;
+                                    int totalY = (y + _y) % 32;
+                                    if (display[totalX, totalY] == 1)
                                         registers[0xF] = 1;
-                                    display[x + _x, y + _y] ^= 1;
+                                    display[totalX, totalY] ^= 1;
                                 }
                             }
                         }
@@ -245,46 +346,71 @@
                     }
                 case 0xE000:
                     {
+                        switch (opcode & 0x00FF)
+                        {
+                            case 0x009E:
+                                {
+                                    //TODO: Check if key down
+                                    counter += 2;
+                                    break;
+                                }
+                            case 0x00A1:
+                                {
+                                    //TODO: Check if key up
+                                    counter+=4;
+                                    break;
+                                }
+                        }
                         break;
                     }
                 case 0xF000:
                     {
-                        switch(opcode & 0x00FF)
+                        switch (opcode & 0x00FF)
                         {
                             case 0x0007:
                                 {
-                                    int x = opcode & 0x0F00 >> 8;
+                                    int x = (opcode & 0x0F00) >> 8;
                                     registers[x] = delay;
                                     counter += 2;
                                     break;
                                 }
+                            case 0x000A:
+                                {
+                                    //TODO: Read User input
+                                    break;
+                                }
                             case 0x0015:
                                 {
-                                    int x = opcode & 0x0F00 >> 8;
+                                    int x = (opcode & 0x0F00) >> 8;
                                     delay = registers[x];
                                     counter += 2;
                                     break;
                                 }
                             case 0x0018:
                                 {
-                                    int x = opcode & 0x0F00 >> 8;
+                                    int x = (opcode & 0x0F00) >> 8;
                                     soundDelay = registers[x];
                                     counter += 2;
                                     break;
                                 }
+                            case 0x001E:
+                                {
+                                    int x = (opcode & 0x0F00) >> 8;
+                                    addressPointer += registers[x];
+                                    counter += 2;
+                                    break;
+                                }
                             case 0x0029:
                                 {
-                                    int x = opcode & 0x0F00 >> 8;
+                                    int x = (opcode & 0x0F00) >> 8;
                                     int character = registers[x];
-                                    //Console.WriteLine(character);
-                                    //Console.WriteLine((ushort)(0x050 + (character * 5)));
                                     addressPointer = (ushort)(0x050 + (character * 5));
                                     counter += 2;
                                     break;
                                 }
                             case 0x0033:
                                 {
-                                    int vx = registers[opcode & 0x0F00 >> 8], hundreds, tens;
+                                    int vx = registers[(opcode & 0x0F00) >> 8], hundreds, tens;
                                     hundreds = ((vx - (vx % 100)) / 100);
                                     vx -= hundreds * 100;
                                     tens = ((vx - (vx % 10)) / 10);
@@ -296,17 +422,28 @@
                                     counter += 2;
                                     break;
                                 }
-                            case 0x0065:
+                            case 0x0055:
                                 {
                                     int x = opcode & 0x0F00 >> 8;
                                     for (int i = 0; i < x; i++)
                                     {
-                                        registers[i] = memory[addressPointer + 1];
+                                        memory[addressPointer + i] = registers[i];
                                     }
                                     addressPointer += (ushort)(x + 1);
                                     counter += 2;
                                     break;
                                 }
+                            case 0x0065:
+                                {
+                                    int x = opcode & 0x0F00 >> 8;
+                                    for (int i = 0; i < x; i++)
+                                    {
+                                        registers[i] = memory[addressPointer + i];
+                                    }
+                                    addressPointer += (ushort)(x + 1);
+                                    counter += 2;
+                                    break;
+                                }
                         }
                         break;
                     }
@@ -315,6 +452,14 @@
                         Console.WriteLine("Error");
                         break;
                     }
+            }
+            if (delay > 0)
+            {
+                delay--;
+            }
+            if (soundDelay > 0)
+            {
+                soundDelay--;
             }
             base.Update(gameTime);
         }
@@ -327,7 +472,7 @@
             {
                 for (int j = 0; j < 32; j++)
                 {
-                    Color color = display[i,j] == 1 ? Color.White : Color.Black;
+                    Color color = display[i, j] == 1 ? Color.White : Color.Black;
                     spriteBatch.Draw(pixel, new Rectangle(i * 16, j * 16, 16, 16), color);
                 }
             }


Update designer so we won't lose stuff if we make changes

--- src/BloomExe/Workspace/WorkspaceView.Designer.cs
+++ src/BloomExe/Workspace/WorkspaceView.Designer.cs
@@ -368,12 +368,6 @@
 			this._L10NSharpExtender.LocalizationManagerId = "Bloom";
 			this._L10NSharpExtender.PrefixForNewItems = "HelpMenu";
 			//
-			// _applicationUpdateCheckTimer
-			//
-			this._applicationUpdateCheckTimer.Enabled = true;
-			this._applicationUpdateCheckTimer.Interval = 60000;
-			this._applicationUpdateCheckTimer.Tick += new System.EventHandler(this._applicationUpdateCheckTimer_Tick);
-			//
 			// _tabStrip
 			//
 			this._tabStrip.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(29)))), ((int)(((byte)(148)))), ((int)(((byte)(164)))));
@@ -417,9 +411,9 @@
 			this._collectionTab.SelectedFont = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
 			this._collectionTab.SelectedTextColor = System.Drawing.Color.WhiteSmoke;
 			this._collectionTab.Size = new System.Drawing.Size(103, 71);
-			this._collectionTab.TextChanged += HandleTabTextChanged;
 			this._collectionTab.Text = "Collections";
 			this._collectionTab.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
+			this._collectionTab.TextChanged += new System.EventHandler(this.HandleTabTextChanged);
 			//
 			// _editTab
 			//
@@ -439,9 +433,9 @@
 			this._editTab.SelectedFont = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
 			this._editTab.SelectedTextColor = System.Drawing.Color.WhiteSmoke;
 			this._editTab.Size = new System.Drawing.Size(69, 71);
-			this._editTab.TextChanged += HandleTabTextChanged;
 			this._editTab.Text = "Edit";
 			this._editTab.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
+			this._editTab.TextChanged += new System.EventHandler(this.HandleTabTextChanged);
 			//
 			// _publishTab
 			//
@@ -463,9 +457,15 @@
 			this._publishTab.SelectedFont = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
 			this._publishTab.SelectedTextColor = System.Drawing.Color.WhiteSmoke;
 			this._publishTab.Size = new System.Drawing.Size(83, 71);
-			this._publishTab.TextChanged += HandleTabTextChanged;
 			this._publishTab.Text = "Publish";
 			this._publishTab.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
+			this._publishTab.TextChanged += new System.EventHandler(this.HandleTabTextChanged);
+			//
+			// _applicationUpdateCheckTimer
+			//
+			this._applicationUpdateCheckTimer.Enabled = true;
+			this._applicationUpdateCheckTimer.Interval = 60000;
+			this._applicationUpdateCheckTimer.Tick += new System.EventHandler(this._applicationUpdateCheckTimer_Tick);
 			//
 			// WorkspaceView
 			//


[AppleDocWizard] Delete doc xar file after download

--- samples/macdoc/AppleDocWizard/AppleDocHandler.cs
+++ samples/macdoc/AppleDocWizard/AppleDocHandler.cs
@@ -177,6 +177,9 @@
 				}
 			} finally {
 				evt.Set ();
+				// Delete the .xar file
+				if (File.Exists (path))
+					File.Delete (path);
 			}
 		}


test commit with debug output per folder fetch. NOT FOR PRODUCTION, SPEWY

--- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -1255,6 +1255,7 @@
                                                List<InventoryFolderBase> folders, int version,
                                                bool fetchFolders, bool fetchItems)
         {
+            m_log.DebugFormat("[CLIENT]: Request folder details for folder {0}", folderID.ToString());
             // An inventory descendents packet consists of a single agent section and an inventory details
             // section for each inventory item.  The size of each inventory item is approximately 550 bytes.
             // In theory, UDP has a maximum packet size of 64k, so it should be possible to send descendent


Fixed IRuntimeFacetHandler so it inherits from IFacetHandler.

--- src/BoboBrowse.Net/Facets/RuntimeFacetHandler.cs
+++ src/BoboBrowse.Net/Facets/RuntimeFacetHandler.cs
@@ -6,7 +6,7 @@
     using System.Linq;
     using System.Text;

-    public interface IRuntimeFacetHandler
+    public interface IRuntimeFacetHandler : IFacetHandler
     {
         void Close();
         T GetFacetData<T>(BoboIndexReader reader);


Mantis#1428. Thank you kindly, fdg for a patch that solves: When you copy an item in inventory and paste it, the name gets lost.  Also when you use "Save as" in the Appearance Editing window the  created item in inventory has always the name "New <item-type>",  regardless of what you typed in as name.

--- OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -513,6 +513,11 @@

             if (asset != null)
             {
+                if (newName != String.Empty)
+                {
+                    asset.Name = newName;
+                }
+
                 if (remoteClient.AgentId == oldAgentID)
                 {
                     CreateNewInventoryItem(


Adicionando a palavra 'Juros' no boleto da Caixa

--- src/Boleto.Net/BoletoImpressao/BoletoBancario.cs
+++ src/Boleto.Net/BoletoImpressao/BoletoBancario.cs
@@ -840,7 +840,10 @@
                 html.Append(GeraHtmlReciboCedente());
             }

-            //html.Append(!FormatoCarne ? !FormatoPropaganda ? GeraHtmlReciboCedente() : GeraHtmlPropaganda(GeraHtmlReciboCedente()) : GeraHtmlCarne(GeraHtmlReciboCedente()));
+ 	    if (Boleto.Banco.Codigo == 104)
+                html.Replace("Mora / Multa", "Mora / Multa / Juros");
+
+	    //html.Append(!FormatoCarne ? !FormatoPropaganda ? GeraHtmlReciboCedente() : GeraHtmlPropaganda(GeraHtmlReciboCedente()) : GeraHtmlCarne(GeraHtmlReciboCedente()));

             string dataVencimento = Boleto.DataVencimento.ToString("dd/MM/yyyy");


Revamp the return logic to close a privilege escalation loophole. Estate owner / Master avatar returns would place the item in the returner's inventory rather than the owner's if the owner was not in sim.

--- OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -1765,6 +1765,26 @@
             }
         }

+        private bool WaitForInventory(CachedUserInfo info)
+        {
+            // 200 Seconds wait. This is called in the context of the
+            // background delete thread, so we can afford to waste time
+            // here.
+            //
+            int count = 200;
+
+            while (count > 0)
+            {
+                System.Threading.Thread.Sleep(100);
+                count--;
+                if (info.HasReceivedInventory)
+                    return true;
+            }
+            m_log.DebugFormat("Timed out waiting for inventory of user {0}",
+                    info.UserProfile.ID.ToString());
+            return false;
+        }
+
         /// <summary>
         /// Delete a scene object from a scene and place in the given avatar's inventory.
         /// Returns the UUID of the newly created asset.
@@ -1780,55 +1800,66 @@

             string sceneObjectXml = objectGroup.ToXmlString();

+            bool useOwner = false;
+
+            // Get the user info of the item destination
+            //
             CachedUserInfo userInfo;

-            if (remoteClient == null)
-            {
-                userInfo = CommsManager.UserProfileCacheService.GetUserDetails(objectGroup.RootPart.OwnerID);
+            if (action == DeRezAction.Take || action == DeRezAction.TakeCopy ||
+                action == DeRezAction.SaveToExistingUserInventoryItem)
+            {
+                // Take or take copy require a taker
+                // Saving changes requires a local user
+                //
+                if (remoteClient == null)
+                    return UUID.Zero;
+
+                userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
+                        remoteClient.AgentId);
             }
             else
             {
-                userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+                // All returns / deletes go to the object owner
+                //
+                userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
+                        objectGroup.RootPart.OwnerID);
+            }
+
+            if (userInfo == null) // Can't proceed
+            {
+                return UUID.Zero;
+            }
+
+            if (!userInfo.HasReceivedInventory)
+            {
+                // Async inventory requests will queue, but they will never
+                // execute unless inventory is actually fetched
+                //
+                CommsManager.UserProfileCacheService.RequestInventoryForUser(
+                        userInfo.UserProfile.ID);
             }

             if (userInfo != null)
             {
-                // If we're deleting someone else's item, it goes back to
-                // their deleted items folder
                 // If we're returning someone's item, it goes back to the
                 // owner's Lost And Found folder.
-
-                if (folderID == UUID.Zero
-                    || (action == DeRezAction.Delete && objectGroup.OwnerID != remoteClient.AgentId))
-                {
-                    InventoryFolderBase folder =
-                            userInfo.FindFolderForType(
-                            (int)AssetType.LostAndFoundFolder);
-
-                    if (folder != null)
-                    {
-                        folderID = folder.ID;
-                    }
-                    else
-                    {
-                        if (userInfo.RootFolder != null)
-                        {
-                            folderID = userInfo.RootFolder.ID;
-                        }
-                        else
-                        {
-                            CommsManager.UserProfileCacheService.RequestInventoryForUser(objectGroup.RootPart.OwnerID);
-                            m_log.WarnFormat("[SCENE] Can't find root folder for user, requesting inventory");
-                            return assetID;
-                        }
-                    }
-                }
-
+                // Delete is treated like return in this case
+                // Deleting your own items makes them go to trash
+                //
+
+                InventoryFolderBase folder = null;
                 InventoryItemBase item = null;

+
+                // No folder type needed
+                // We don't go here unless we have a user logged in
+                // so the skeleton is loaded
+                //
                 if (DeRezAction.SaveToExistingUserInventoryItem == action)
                 {
-                    item = userInfo.RootFolder.FindItem(objectGroup.RootPart.FromUserInventoryItemID);
+                    item = userInfo.RootFolder.FindItem(
+                            objectGroup.RootPart.FromUserInventoryItemID);

                     if (null == item)
                     {
@@ -1837,6 +1868,83 @@
                             objectGroup.Name, objectGroup.UUID);
                         return UUID.Zero;
                     }
+                }
+                else
+                {
+                    // Folder magic
+                    //
+                    if (action == DeRezAction.Delete)
+                    {
+                        // Deleting someone else's item
+                        //
+                        if (remoteClient == null ||
+                            objectGroup.OwnerID != remoteClient.AgentId)
+                        {
+                            // Folder skeleton may not be loaded and we
+                            // have to wait for the inventory to find
+                            // the destination folder
+                            //
+                            if (!WaitForInventory(userInfo))
+                                return UUID.Zero;
+                            folder = userInfo.FindFolderForType(
+                                    (int)AssetType.LostAndFoundFolder);
+                        }
+                        else
+                        {
+                            // Assume inventory skeleton was loaded during login
+                            // and all folders can be found
+                            //
+                            folder = userInfo.FindFolderForType(
+                                    (int)AssetType.TrashFolder);
+                        }
+                    }
+                    else if (action == DeRezAction.Return)
+                    {
+                        // Wait if needed
+                        //
+                        if (!userInfo.HasReceivedInventory)
+                        {
+                            if (!WaitForInventory(userInfo))
+                                return UUID.Zero;
+                        }
+
+                        // Dump to lost + found unconditionally
+                        //
+                        folder = userInfo.FindFolderForType(
+                                (int)AssetType.LostAndFoundFolder);
+                    }
+
+                    if (folderID == UUID.Zero && folder == null)
+                    {
+                        // Catch all. Use lost & found
+                        //
+                        if (!userInfo.HasReceivedInventory)
+                        {
+                            if (!WaitForInventory(userInfo))
+                                return UUID.Zero;
+                        }
+
+                        folder = userInfo.FindFolderForType(
+                                (int)AssetType.LostAndFoundFolder);
+                    }
+
+                    if (folder == null) // None of the above
+                    {
+                        folder = userInfo.RootFolder.FindFolder(folderID);
+
+                        if (folder == null) // Nowhere to put it
+                        {
+                            return UUID.Zero;
+                        }
+                    }
+
+                    item = new InventoryItemBase();
+                    item.Creator = objectGroup.RootPart.CreatorID;
+                    item.ID = UUID.Random();
+                    item.InvType = (int)InventoryType.Object;
+                    item.Folder = folder.ID;
+                    item.Owner = userInfo.UserProfile.ID;
+
                 }

                 AssetBase asset = CreateAsset(
@@ -1854,22 +1962,8 @@
                 }
                 else
                 {
-                    item = new InventoryItemBase();
-                    item.Creator = objectGroup.RootPart.CreatorID;
-
-                    if (action == DeRezAction.TakeCopy || action == DeRezAction.Take)
-                        item.Owner = remoteClient.AgentId;
-                    else // Delete / Return
-                        item.Owner = objectGroup.OwnerID;
-
-                    item.ID = UUID.Random();
                     item.AssetID = asset.FullID;
-                    item.Description = asset.Description;
-                    item.Name = asset.Name;
-                    item.AssetType = asset.Type;
-                    item.InvType = (int)InventoryType.Object;
-                    item.Folder = folderID;
-
+
                     if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions())
                     {
                         uint perms=objectGroup.GetEffectivePermissions();
@@ -1899,6 +1993,9 @@

                     // TODO: add the new fields (Flags, Sale info, etc)
                     item.CreationDate = Util.UnixTimeSinceEpoch();
+                    item.Description = asset.Description;
+                    item.Name = asset.Name;
+                    item.AssetType = asset.Type;

                     userInfo.AddItem(item);


fixed the S-Expression parser

fixed the S-Expression parser

--- src/Canto34/Canto34.Tests/Parsing/ParserTests.cs
+++ src/Canto34/Canto34.Tests/Parsing/ParserTests.cs
@@ -51,15 +51,32 @@
             var sexpr2 = this.GetSExprParser("(a b c)").SExpression();
             var sexpr3 = this.GetSExprParser("(a (b c d) c)").SExpression();
         }
+
+        [TestMethod, ExpectedException(typeof(ParseException))]
+        public void ThrowsOnUnclosedSExpressions()
+        {
+            this.GetSExprParser("(a").SExpression();
+        }
+
+        [TestMethod, ExpectedException(typeof(ParseException))]
+        public void ThrowsOnJustACloseSExpressions()
+        {
+            this.GetSExprParser(")").SExpression();
+        }
+
     }

     public class SExpressionLexer : LexerBase
     {
+        public const int OP = 1;
+        public const int CL = 2;
+        public const int ATOM = 3;
+
         public SExpressionLexer(string input): base(input)
         {
-            this.AddLiteral(1, "(");
-            this.AddLiteral(2, ")");
-            this.AddPattern(3, "[a-z]+", "atom");
+            this.AddLiteral(OP, "(");
+            this.AddLiteral(CL, ")");
+            this.AddPattern(ATOM, "[a-z]+", "atom");
             this.StandardTokens.AddWhitespace();
         }
     }
@@ -73,23 +90,23 @@

         internal dynamic SExpression()
         {
-            if (LA1.Is("("))
+            if (LA1.Is(SExpressionLexer.OP))
             {
-                Match("(");
+                Match(SExpressionLexer.OP);
             }
             else
             {
-                var atom = MatchAny().Content;
+                var atom = Match(SExpressionLexer.ATOM).Content;
                 return atom;
             }

             var array = new List<dynamic>();
-            while (!LA1.Is(")"))
+            while (!EOF && !LA1.Is(SExpressionLexer.CL))
             {
                 array.Add(SExpression());
             }

-            Match(")");
+            Match(SExpressionLexer.CL);
             return array;
         }
     }


* Patch by Melanie to fix CreateSelected

--- OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -1453,9 +1453,15 @@
         {
             LLQuaternion lRot;
             lRot = RotationOffset;
+            clientFlags &= ~(uint)LLObject.ObjectFlags.CreateSelected;
+
             if (remoteClient.AgentId == OwnerID)
             {
-                clientFlags &= ~(uint)LLObject.ObjectFlags.CreateSelected;
+                if ((uint)(m_flags & LLObject.ObjectFlags.CreateSelected) != 0)
+                {
+                    clientFlags |= (uint)LLObject.ObjectFlags.CreateSelected;
+                    m_flags &= ~LLObject.ObjectFlags.CreateSelected;
+                }
             }


代码简单调整。 :watch:

代码简单调整。 :watch:

--- src/Common/Expressions/InsertStatementBuilder.cs
+++ src/Common/Expressions/InsertStatementBuilder.cs
@@ -103,6 +103,7 @@
 			}
 		}

+		[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 		private bool IsLinked(SchemaMember owner, IEntitySimplexPropertyMetadata property)
 		{
 			if(owner == null || owner.Token.Property.IsSimplex)


BulletSim: fix error messages created while an avatar has no initial collisions. Usually happens when logging in an avatar that had been previously flying. Uninitialized variable.

--- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -97,6 +97,9 @@

         CollisionCollection = new CollisionEventUpdate();
         CollisionsLastReported = CollisionCollection;
+        CollisionsLastTick = new CollisionEventUpdate();
+        CollisionsLastTickStep = -1;
+
         SubscribedEventsMs = 0;
         CollidingStep = 0;
         CollidingGroundStep = 0;


Fix Timer argument exception parameter names (dotnet/coreclr#25617)

Signed-off-by: dotnet-bot <03c4cb6107ae99956a7681f2c97ff7104809a2bd@microsoft.com>

--- src/Common/src/CoreLib/System/Threading/Timer.cs
+++ src/Common/src/CoreLib/System/Threading/Timer.cs
@@ -735,15 +735,15 @@
         {
             long dueTm = (long)dueTime.TotalMilliseconds;
             if (dueTm < -1)
-                throw new ArgumentOutOfRangeException(nameof(dueTm), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
+                throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
             if (dueTm > MAX_SUPPORTED_TIMEOUT)
-                throw new ArgumentOutOfRangeException(nameof(dueTm), SR.ArgumentOutOfRange_TimeoutTooLarge);
+                throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_TimeoutTooLarge);

             long periodTm = (long)period.TotalMilliseconds;
             if (periodTm < -1)
-                throw new ArgumentOutOfRangeException(nameof(periodTm), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
+                throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
             if (periodTm > MAX_SUPPORTED_TIMEOUT)
-                throw new ArgumentOutOfRangeException(nameof(periodTm), SR.ArgumentOutOfRange_PeriodTooLarge);
+                throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_PeriodTooLarge);

             TimerSetup(callback, state, (uint)dueTm, (uint)periodTm);
         }
@@ -790,7 +790,7 @@
                                 bool flowExecutionContext = true)
         {
             if (callback == null)
-                throw new ArgumentNullException(nameof(TimerCallback));
+                throw new ArgumentNullException(nameof(callback));

             _timer = new TimerHolder(new TimerQueueTimer(callback, state, dueTime, period, flowExecutionContext));
         }


ubitODE - again avatar/terrain collision. Reduce new viewers interpolators efects reporting null velocity and aceleration when stopped near the right position, where they can still have instantanius large values that can get magnified by interpolators, specially using diferent timing estimation.

--- OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -862,12 +862,12 @@
                 float depth = terrainheight - chrminZ;
                 if (!flying)
                 {
-                    vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 60;
+                    vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 50;
                 }
                 else
-                    vec.Z = depth * PID_P * 60;
-
-                if (depth < 0.2f)
+                    vec.Z = depth * PID_P * 50;
+
+                if (depth < 0.1f)
                 {
                     m_iscolliding = true;
                     m_colliderfilter = 2;
@@ -1009,9 +1009,17 @@

             // update our local ideia of position velocity and aceleration
             _position = localpos;
-            _acceleration = _velocity; // previus velocity
-            _velocity = vel;
-            _acceleration = (vel - _acceleration) / timeStep;
+            if (_zeroFlag)
+            {
+                _velocity = Vector3.Zero;
+                _acceleration = Vector3.Zero;
+            }
+            else
+            {
+                _acceleration = _velocity; // previus velocity
+                _velocity = vel;
+                _acceleration = (vel - _acceleration) / timeStep;
+            }

         }


i try to fix avatar orientation in some cases..

--- OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
+++ OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
@@ -233,8 +233,8 @@
                         norm = rayResults[0].Normal;
                         edgeNormalX = norm.X;
                         edgeNormalY = norm.Y;
-                        edgeDirX = rayDir.X;
-                        edgeDirY = rayDir.Y;
+                        edgeDirX = -rayDir.X;
+                        edgeDirY = -rayDir.Y;
                     }
                     else
                     {


Added console output for validation errors

--- src/CorpAxe.Examples/Examples.Console/Program.cs
+++ src/CorpAxe.Examples/Examples.Console/Program.cs
@@ -13,6 +13,8 @@
     {
         private const string BaseApiUrl = "https://sandboxcorpaxeapi.azurewebsites.net/";
         private const string ApiVersion = "1";
+
+        private const int UnprocessibleEntityStatusCode = 422;

         public static void Main(string[] args)
         {
@@ -114,12 +116,13 @@
             }";

             var eventId = CreateEventAndReturnId(accessToken, eventAsJsonString);
-
-            var dynamicEvent = GetEventById(accessToken, eventId);
-
-            Console.WriteLine("Id created: {0}", eventId);
-            Console.WriteLine("Id retrieved: {0}", dynamicEvent.id.ToString());
-
+            if (eventId > 0)
+            {
+                Console.WriteLine("Id created: {0}", eventId);
+                var dynamicEvent = GetEventById(accessToken, eventId);
+                Console.WriteLine("Id retrieved: {0}", dynamicEvent.id.ToString());
+            }
+
             Console.ReadLine();
         }

@@ -172,26 +175,63 @@

         private static dynamic GetResponseAsDynamicObject(HttpWebRequest request)
         {
-            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
-            {
-                if (response != null)
+            try
+            {
+                using (var response = request.GetResponse() as HttpWebResponse)
                 {
-                    if (response.StatusCode == HttpStatusCode.OK)
+                    if (response != null)
                     {
-                        using (var stream = response.GetResponseStream())
+                        if (response.StatusCode == HttpStatusCode.OK)
                         {
-                            if (stream != null)
+                            using (var stream = response.GetResponseStream())
                             {
-                                using (var reader = new StreamReader(stream))
+                                return GetDynamicObjectFromStream(stream);
+                            }
+                        }
+                    }
+                }
+            }
+            catch (WebException ex)
+            {
+                using (var response = ex.Response as HttpWebResponse)
+                {
+                    if (response != null)
+                    {
+                        if (response.StatusCode == (HttpStatusCode)UnprocessibleEntityStatusCode)
+                        {
+                            using (var stream = response.GetResponseStream())
+                            {
+                                dynamic validationErrors = GetDynamicObjectFromStream(stream);
+                                if (validationErrors != null)
                                 {
-                                    var converter = new ExpandoObjectConverter();
-                                    return JsonConvert.DeserializeObject<ExpandoObject>(reader.ReadToEnd(), converter);
+                                    Console.WriteLine("Event failed validation due to the following issues:");
+                                    foreach (var validationError in validationErrors.Errors)
+                                    {
+                                        Console.WriteLine(validationError.RawErrorMessage);
+                                    }
+                                    return null;
                                 }
                             }
                         }
                     }
                 }
-            }
+
+                throw;
+            }
+            return null;
+        }
+
+        private static dynamic GetDynamicObjectFromStream(Stream stream)
+        {
+            if (stream != null)
+            {
+                using (var reader = new StreamReader(stream))
+                {
+                    var converter = new ExpandoObjectConverter();
+                    return JsonConvert.DeserializeObject<ExpandoObject>(reader.ReadToEnd(), converter);
+                }
+            }
+
             return null;
         }
     }


* Fixed an issue whereby extremely tall terrains would be unable to output a gradient map. * Renamed several terrain variable names for clarity.

--- OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs
+++ OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs
@@ -578,7 +578,7 @@
         {
             FileInfo file = new FileInfo(filename);
             FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write);
-            BinaryWriter bs = new BinaryWriter(s);
+            BinaryWriter binStream = new BinaryWriter(s);

             int x, y;

@@ -615,22 +615,22 @@
                     byte alpha9 = (byte)(revertmap.get(x, y) / ((double)backupMultiplier / 128.0));
                     byte alpha10 = backupMultiplier;

-                    bs.Write(red);
-                    bs.Write(green);
-                    bs.Write(blue);
-                    bs.Write(alpha1);
-                    bs.Write(alpha2);
-                    bs.Write(alpha3);
-                    bs.Write(alpha4);
-                    bs.Write(alpha5);
-                    bs.Write(alpha6);
-                    bs.Write(alpha7);
-                    bs.Write(alpha8);
-                    bs.Write(alpha9);
-                    bs.Write(alpha10);
-                }
-            }
-            bs.Close();
+                    binStream.Write(red);
+                    binStream.Write(green);
+                    binStream.Write(blue);
+                    binStream.Write(alpha1);
+                    binStream.Write(alpha2);
+                    binStream.Write(alpha3);
+                    binStream.Write(alpha4);
+                    binStream.Write(alpha5);
+                    binStream.Write(alpha6);
+                    binStream.Write(alpha7);
+                    binStream.Write(alpha8);
+                    binStream.Write(alpha9);
+                    binStream.Write(alpha10);
+                }
+            }
+            binStream.Close();
             s.Close();
         }

@@ -643,16 +643,16 @@
         {
             FileInfo file = new FileInfo(filename);
             FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write);
-            BinaryWriter bs = new BinaryWriter(s);
+            BinaryWriter binStream = new BinaryWriter(s);

             // Generate a smegging big lookup table to speed the operation up (it needs it)
-            double[] lookupTable = new double[65536];
+            double[] lookupHeightTable = new double[65536];
             int i, j, x, y;
             for (i = 0; i < 256; i++)
             {
                 for (j = 0; j < 256; j++)
                 {
-                    lookupTable[i + (j * 256)] = ((double)i * ((double)j / 127.0));
+                    lookupHeightTable[i + (j * 256)] = ((double)i * ((double)j / 127.0));
                 }
             }

@@ -667,9 +667,9 @@

                     for (i = 0; i < 65536; i++)
                     {
-                        if (Math.Abs(t - lookupTable[i]) < min)
+                        if (Math.Abs(t - lookupHeightTable[i]) < min)
                         {
-                            min = Math.Abs(t - lookupTable[i]);
+                            min = Math.Abs(t - lookupHeightTable[i]);
                             index = i;
                         }
                     }
@@ -688,23 +688,23 @@
                     byte alpha9 = red;
                     byte alpha10 = green;

-                    bs.Write(red);
-                    bs.Write(green);
-                    bs.Write(blue);
-                    bs.Write(alpha1);
-                    bs.Write(alpha2);
-                    bs.Write(alpha3);
-                    bs.Write(alpha4);
-                    bs.Write(alpha5);
-                    bs.Write(alpha6);
-                    bs.Write(alpha7);
-                    bs.Write(alpha8);
-                    bs.Write(alpha9);
-                    bs.Write(alpha10);
-                }
-            }
-
-            bs.Close();
+                    binStream.Write(red);
+                    binStream.Write(green);
+                    binStream.Write(blue);
+                    binStream.Write(alpha1);
+                    binStream.Write(alpha2);
+                    binStream.Write(alpha3);
+                    binStream.Write(alpha4);
+                    binStream.Write(alpha5);
+                    binStream.Write(alpha6);
+                    binStream.Write(alpha7);
+                    binStream.Write(alpha8);
+                    binStream.Write(alpha9);
+                    binStream.Write(alpha10);
+                }
+            }
+
+            binStream.Close();
             s.Close();
         }

@@ -900,7 +900,7 @@
                     for (int y = 0; y < copy.h; y++)
                     {
                         // 512 is the largest possible height before colours clamp
-                        int colorindex = (int)(Math.Max(Math.Min(1.0, copy.get(x, y) / 512.0), 0.0) * pallete);
+                        int colorindex = (int)(Math.Max(Math.Min(1.0, copy.get(x, y) / 512.0), 0.0) * (pallete - 1));
                         bmp.SetPixel(x, y, colours[colorindex]);
                     }
                 }


Fix bug : LogEvent not released when there is no appenders to log to

--- src/ZeroLog/LogManager.cs
+++ src/ZeroLog/LogManager.cs
@@ -197,25 +197,31 @@
         {
             if (!_queue.TryDequeue(out var logEvent))
                 return false;
-            if ((logEvent.Appenders?.Count ?? 0) <= 0)
-                return true;

             try
             {
-                FormatLogMessage(stringBuffer, logEvent);
-            }
-            catch (Exception)
-            {
-                FormatErrorMessage(stringBuffer, logEvent);
-            }
-
-            var bytesWritten = CopyStringBufferToByteArray(stringBuffer, destination);
-
-            WriteMessageLogToAppenders(destination, logEvent, bytesWritten);
-
-            if (logEvent.IsPooled)
-                _pool.Release(logEvent);
-
+                if ((logEvent.Appenders?.Count ?? 0) <= 0)
+                    return true;
+
+                try
+                {
+                    FormatLogMessage(stringBuffer, logEvent);
+                }
+                catch (Exception)
+                {
+                    FormatErrorMessage(stringBuffer, logEvent);
+                }
+
+                var bytesWritten = CopyStringBufferToByteArray(stringBuffer, destination);
+
+                WriteMessageLogToAppenders(destination, logEvent, bytesWritten);
+
+            }
+            finally
+            {
+                if (logEvent.IsPooled)
+                    _pool.Release(logEvent);
+            }
             return true;
         }


Add test for returning empty list from script

--- Rant.Tests/Richard/Lists.cs
+++ Rant.Tests/Richard/Lists.cs
@@ -39,5 +39,11 @@
         {
             Assert.AreEqual("12", rant.Do("[@ x = list 12; x.length ]").Main);
         }
+
+        [Test]
+        public void ListEmptyAsBlock()
+        {
+            Assert.AreEqual("", rant.Do(@"[@ [] ]"));
+        }
     }
 }


Avoid code duplication by calling SetVote...

in the Upvote and Downvote methods of VotableThing.

--- RedditSharp/VotableThing.cs
+++ RedditSharp/VotableThing.cs
@@ -65,42 +65,12 @@

         public void Upvote()
         {
-            if (this.Liked == true) return;
-            else if (this.Liked == false) Downvotes--;
-
-            var request = WebAgent.CreatePost(VoteUrl);
-            var stream = request.GetRequestStream();
-            WebAgent.WritePostBody(stream, new
-            {
-                dir = 1,
-                id = FullName,
-                uh = Reddit.User.Modhash
-            });
-            stream.Close();
-            var response = request.GetResponse();
-            var data = WebAgent.GetResponseString(response.GetResponseStream());
-            Liked = true;
-            Upvotes++;
+            this.SetVote(VoteType.Upvote);
         }

         public void Downvote()
         {
-            if (this.Liked == false) return;
-            else if (this.Liked == true) Upvotes--;
-
-            var request = WebAgent.CreatePost(VoteUrl);
-            var stream = request.GetRequestStream();
-            WebAgent.WritePostBody(stream, new
-            {
-                dir = -1,
-                id = FullName,
-                uh = Reddit.User.Modhash
-            });
-            stream.Close();
-            var response = request.GetResponse();
-            var data = WebAgent.GetResponseString(response.GetResponseStream());
-            Liked = false;
-            Downvotes++;
+            this.SetVote(VoteType.Downvote);
         }

         public void SetVote(VoteType type)


Reset a tuple for tp_bases

Reset a tuple for tp_bases

--- src/runtime/typemanager.cs
+++ src/runtime/typemanager.cs
@@ -1103,7 +1103,8 @@

             IntPtr tp_bases = Marshal.ReadIntPtr(_type, TypeOffset.tp_bases);
             Runtime.XDecref(tp_bases);
-            Marshal.WriteIntPtr(_type, TypeOffset.tp_bases, IntPtr.Zero);
+            tp_bases = Runtime.PyTuple_New(0);
+            Marshal.WriteIntPtr(_type, TypeOffset.tp_bases, tp_bases);
         }

         private static void OnDestruct(IntPtr ob)


include ⏬ in title update links as well

include ⏬ in title update links as well

--- CompatBot/Utils/ResultFormatters/TitlePatchFormatter.cs
+++ CompatBot/Utils/ResultFormatters/TitlePatchFormatter.cs
@@ -38,7 +38,7 @@
                 do
                 {
                     var pkg = pkgs[i++];
-                    embedBuilder.AddField($"Update v{pkg.Version} ({pkg.Size.AsStorageUnit()})", $"⏬ [{GetLinkName(pkg.Url)}]({pkg.Url})");
+                    embedBuilder.AddField($"Update v{pkg.Version} ({pkg.Size.AsStorageUnit()})", $"[⏬ {GetLinkName(pkg.Url)}]({pkg.Url})");
                     if (i % EmbedPager.MaxFields == 0)
                     {
                         result.Add(embedBuilder);
@@ -54,7 +54,7 @@
             else if (pkgs?.Length == 1)
             {
                 embedBuilder.Title = $"{title} update v{pkgs[0].Version} ({pkgs[0].Size.AsStorageUnit()})";
-                embedBuilder.Description = $"⏬ [{Path.GetFileName(GetLinkName(pkgs[0].Url))}]({pkgs[0].Url})";
+                embedBuilder.Description = $"[⏬ {Path.GetFileName(GetLinkName(pkgs[0].Url))}]({pkgs[0].Url})";
             }
             else if (patch != null)
                 embedBuilder.Description = "No updates available";


Fix gas analyser error. (#11386)

Fix gas analyser error. (#11386)

--- Content.Server/Atmos/EntitySystems/GasAnalyzerSystem.cs
+++ Content.Server/Atmos/EntitySystems/GasAnalyzerSystem.cs
@@ -1,4 +1,4 @@
-using Content.Server.Atmos;
+using Content.Server.Atmos;
 using Content.Server.Atmos.Components;
 using Content.Server.NodeContainer;
 using Content.Server.NodeContainer.Nodes;
@@ -87,7 +87,7 @@
             UpdateAppearance(component);
             if(!HasComp<ActiveGasAnalyzerComponent>(uid))
                 AddComp<ActiveGasAnalyzerComponent>(uid);
-            UpdateAnalyzer(uid);
+            UpdateAnalyzer(uid, component);
         }

         /// <summary>
@@ -143,8 +143,14 @@
             if (!Resolve(uid, ref component))
                 return false;

+            if (!TryComp(component.User, out TransformComponent? xform))
+            {
+                DisableAnalyzer(uid, component);
+                return false;
+            }
+
             // check if the user has walked away from what they scanned
-            var userPos = Transform(component.User).Coordinates;
+            var userPos = xform.Coordinates;
             if (component.LastPosition.HasValue)
             {
                 // Check if position is out of range => don't update and disable
@@ -175,6 +181,13 @@
             var deviceFlipped = false;
             if (component.Target != null)
             {
+                if (Deleted(component.Target))
+                {
+                    component.Target = null;
+                    DisableAnalyzer(uid, component, component.User);
+                    return false;
+                }
+
                 // gas analyzed was used on an entity, try to request gas data via event for override
                 var ev = new GasAnalyzerScanEvent();
                 RaiseLocalEvent(component.Target.Value, ev, false);


Don't use Group field.

Don't use Group field.

--- DevAudit.AuditLibrary/Applications/DrupalApplication.cs
+++ DevAudit.AuditLibrary/Applications/DrupalApplication.cs
@@ -73,7 +73,7 @@
                     {
                         DrupalModuleInfo m = yaml_deserializer.Deserialize<DrupalModuleInfo>(r);
                         m.ShortName = f.Name.Split('.')[0];
-                        core_modules.Add(new OSSIndexQueryObject("drupal", m.ShortName, m.Version, "", m.Package));
+                        core_modules.Add(new OSSIndexQueryObject("drupal", m.ShortName, m.Version, "", ""));
                     }
                 }
             }


Correctly using ShimBehaviors.Current.

Correctly using ShimBehaviors.Current.

--- FilesystemSearchExtensions.Tests/DirectoryExtensions.cs
+++ FilesystemSearchExtensions.Tests/DirectoryExtensions.cs
@@ -10,63 +10,63 @@
     [TestFixture]
     public class DirectoryExtensions
     {
-        [TestFixtureSetUp]
-        public static void FixtureSetup()
+        private IDisposable _shimsContext;
+
+        [SetUp]
+        public void TestSetup()
         {
+            _shimsContext = ShimsContext.Create();
             ShimBehaviors.Current = ShimBehaviors.DefaultValue;
+        }
+
+        [TearDown]
+        public void TestTearDown()
+        {
+            _shimsContext.Dispose();
         }

         [Test]
         public void GetDirectoriesRecursively_FindCurrentDirectorySibling()
         {
-            using (ShimsContext.Create())
+            var targetDirectory = new ShimDirectoryInfo { NameGet = () => "sibling" }.Instance;
+            var currentDirectory = new ShimDirectoryInfo
             {
-                var targetDirectory = new ShimDirectoryInfo { NameGet = () => "sibling" }.Instance;
-                var currentDirectory = new ShimDirectoryInfo
-                {
-                    GetDirectoriesString = s => new[] { targetDirectory }
-                }.Instance;
+                GetDirectoriesString = s => new[] { targetDirectory }
+            }.Instance;

-                var result = currentDirectory.GetDirectoriesRecursively("sibling");
-                Assert.That(result, Has.Length.EqualTo(1));
-                Assert.That(result, Has.Member(targetDirectory));
-            }
+            var result = currentDirectory.GetDirectoriesRecursively("sibling");
+            Assert.That(result, Has.Length.EqualTo(1));
+            Assert.That(result, Has.Member(targetDirectory));
         }

         [Test]
         public void GetDirectoriesRecursively_FindParentSibling()
         {
-            using (ShimsContext.Create())
+            var targetDirectory = new ShimDirectoryInfo {NameGet = () => "sibling"}.Instance;
+            var currentDirectory = new ShimDirectoryInfo
             {
-                var targetDirectory = new ShimDirectoryInfo {NameGet = () => "sibling"}.Instance;
-                var currentDirectory = new ShimDirectoryInfo
+                GetDirectoriesString = s => new DirectoryInfo[0],
+                ParentGet = () => new ShimDirectoryInfo
                 {
-                    GetDirectoriesString = s => new DirectoryInfo[0],
-                    ParentGet = () => new ShimDirectoryInfo
-                    {
-                        GetDirectoriesString = s => new[] { targetDirectory },
-                    }.Instance
-                }.Instance;
+                    GetDirectoriesString = s => new[] { targetDirectory },
+                }.Instance
+            }.Instance;

-                var result = currentDirectory.GetDirectoriesRecursively("aunt/uncle");
-                Assert.That(result, Has.Length.EqualTo(1));
-                Assert.That(result, Has.Member(targetDirectory));
-            }
+            var result = currentDirectory.GetDirectoriesRecursively("aunt/uncle");
+            Assert.That(result, Has.Length.EqualTo(1));
+            Assert.That(result, Has.Member(targetDirectory));
         }

         [Test]
         public void GetDirectoriesRecursively_HandlesFailedSearch()
         {
-            using (ShimsContext.Create())
+            var currentDirectory = new ShimDirectoryInfo
             {
-                var currentDirectory = new ShimDirectoryInfo
-                {
-                    GetDirectoriesString = s => new DirectoryInfo[0]
-                }.Instance;
+                GetDirectoriesString = s => new DirectoryInfo[0]
+            }.Instance;

-                var result = currentDirectory.GetDirectoriesRecursively("sibling");
-                Assert.That(result, Has.Length.EqualTo(0));
-            }
+            var result = currentDirectory.GetDirectoriesRecursively("sibling");
+            Assert.That(result, Has.Length.EqualTo(0));
         }
     }
 }


Make FirebaseUserManager constructor internal to be able to use it in tests and add error handling if the response of the update API contains incorrect data

--- FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs
+++ FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs
@@ -36,7 +36,7 @@
         private readonly ConfigurableHttpClient _httpClient;
         private readonly string _baseUrl;

-        private FirebaseUserManager(FirebaseUserManagerArgs args)
+        internal FirebaseUserManager(FirebaseUserManagerArgs args)
         {
             _httpClient = args.ClientFactory.CreateAuthorizedHttpClient(args.Credential);
             _baseUrl = string.Format(ID_TOOLKIT_URL, args.ProjectId);
@@ -52,8 +52,15 @@
             var updatePath = "/accounts:update";
             var resopnse = await PostAsync(updatePath, user);

-            var userResponse = resopnse.ToObject<UserRecord>();
-            if (userResponse == null || userResponse.Uid != user.Uid)
+            try
+            {
+                var userResponse = resopnse.ToObject<UserRecord>();
+                if (userResponse.Uid != user.Uid)
+                {
+                    throw new FirebaseException(INTERNAL_ERROR);
+                }
+            }
+            catch (Exception)
             {
                 throw new FirebaseException(INTERNAL_ERROR);
             }


fix 1

fix 1

--- TestClient.cs
+++ TestClient.cs
@@ -487,7 +487,7 @@
             xf.Win = win? 1:2;
             xf.Half = half;
             var respdd = makeReq(REQ.SETTLEREQUEST, JsonConvert.SerializeObject(xf));
-            if (respdd == null) return false;
+            if (respdd == null || !respdd.Contains("settled")) return false;
             return true;
         }


add redirect rule: root URL to swagger

add redirect rule: root URL to swagger

--- src/Experimentarium.AspNetCore.WebApi/Startup.cs
+++ src/Experimentarium.AspNetCore.WebApi/Startup.cs
@@ -10,6 +10,7 @@
 using Microsoft.AspNetCore.Mvc.ApiExplorer;
 using Microsoft.AspNetCore.Mvc;
 using Experimentarium.AspNetCore.WebApi.Controllers;
+using Microsoft.AspNetCore.Rewrite;

 namespace Experimentarium.AspNetCore.WebApi
 {
@@ -86,6 +87,11 @@
             {
                 app.UseDeveloperExceptionPage();
             }
+
+            var option = new RewriteOptions();
+            option.AddRedirect("^$", "swagger");
+
+            app.UseRewriter(option);

             app.UseAuthentication();


Switching support to support actual TMPro <link> tags, as opposed to the hacky method used before

--- PUTMPro.cs
+++ PUTMPro.cs
@@ -25,125 +25,117 @@

 	public PUTMPro entity;

+	private void IsCloserToPoint(Vector3 mousePoint, Vector3 testPoint, TMP_LinkInfo testLink, ref float minDistance, ref TMP_LinkInfo minLinkInfo) {
+		float testDistance = Vector3.SqrMagnitude (mousePoint - testPoint);
+		if (testDistance < minDistance) {
+			minDistance = testDistance;
+			minLinkInfo = testLink;
+		}
+	}

 	public bool TestForHit(Vector2 screenPoint, Camera eventCamera, Action<string, int> block) {

-		RectTransform rectTransform = gameObject.transform as RectTransform;
-
-		Vector2 touchPos;
-		RectTransformUtility.ScreenPointToLocalPointInRectangle (rectTransform, screenPoint, eventCamera, out touchPos);
-
-
-		string value = null;
-
-		if (entity == null) {
-			return false;
-		}
-		if(entity.text != null)
-			value = entity.text.text;
-		if(entity.textGUI != null)
-			value = entity.textGUI.text;
-
-		float minDistance = 999999;
-		int minChar = -1;
-		int linkID = 0;
-		int clickedLinkID = -1;
-
-
 		TMP_TextInfo textInfo = null;
-
-		if(entity.text != null)
+		TMP_Text text = null;
+
+		if (entity.text != null) {
+			text = entity.text;
 			textInfo = entity.text.textInfo;
-		if(entity.textGUI != null)
+		}
+		if (entity.textGUI != null) {
+			text = entity.textGUI;
 			textInfo = entity.textGUI.textInfo;
-
-		foreach (TMP_MeshInfo meshInfo in textInfo.meshInfo) {
-			Vector3[] vertices = meshInfo.vertices;
-			UIVertex[] uiVertices = null; //textInfo.meshInfo.uiVertices;
-
-			if (vertices != null || uiVertices != null) {
-				for (int i = 0; i < textInfo.wordCount; i++) {
-
-					TMP_WordInfo wordInfo = textInfo.wordInfo [i];
-					int charCount = wordInfo.characterCount;
-
-					TMP_CharacterInfo startCharInfo = textInfo.characterInfo [wordInfo.firstCharacterIndex];
-					for (int j = 0; j < charCount; j++) {
-
-						TMP_CharacterInfo charInfo = textInfo.characterInfo [wordInfo.firstCharacterIndex + j];
-						int vertIndex = startCharInfo.vertexIndex;
-						int index_X4 = j * 4;
-
-						if (vertices != null && (vertIndex + 3 + index_X4) >= vertices.Length) {
-							break;
-						}
-						if (uiVertices != null && (vertIndex + 3 + index_X4) >= uiVertices.Length) {
-							break;
-						}
-						Vector3 a = (vertices != null ? vertices [vertIndex + 0 + index_X4] : uiVertices [vertIndex + 0 + index_X4].position);
-						Vector3 b = (vertices != null ? vertices [vertIndex + 1 + index_X4] : uiVertices [vertIndex + 1 + index_X4].position);
-						Vector3 c = (vertices != null ? vertices [vertIndex + 2 + index_X4] : uiVertices [vertIndex + 2 + index_X4].position);
-						Vector3 d = (vertices != null ? vertices [vertIndex + 3 + index_X4] : uiVertices [vertIndex + 3 + index_X4].position);
-
-						a = (a + b + c + d) / 4;
-
-						if (charInfo.character == '\x0b') {
-							linkID++;
-						}
-
-						float distance = Vector2.Distance (touchPos, a);
-						if (distance < minDistance) {
-							minDistance = distance;
-							minChar = charInfo.index;
+		}
+
+		if (textInfo != null) {
+
+
+
+			// find the closest link to our touch point
+			float minDistance = 999999;
+			TMP_LinkInfo minLinkInfo = new TMP_LinkInfo ();
+
+			Transform rectTransform = text.transform;
+			Vector3 position = screenPoint;
+
+			// Convert position into Worldspace coordinates
+			TMP_TextUtilities.ScreenPointToWorldPointInRectangle (rectTransform, position, eventCamera, out position);
+
+			for (int i = 0; i < text.textInfo.linkCount; i++) {
+				TMP_LinkInfo linkInfo = text.textInfo.linkInfo [i];
+
+				bool isBeginRegion = false;
+
+				Vector3 bl = Vector3.zero;
+				Vector3 tl = Vector3.zero;
+				Vector3 br = Vector3.zero;
+				Vector3 tr = Vector3.zero;
+
+				// Iterate through each character of the word
+				for (int j = 0; j < linkInfo.linkTextLength; j++) {
+					int characterIndex = linkInfo.linkTextfirstCharacterIndex + j;
+					TMP_CharacterInfo currentCharInfo = text.textInfo.characterInfo [characterIndex];
+					int currentLine = currentCharInfo.lineNumber;
+
+					// Check if Link characters are on the current page
+					if (text.OverflowMode == TextOverflowModes.Page && currentCharInfo.pageNumber + 1 != text.pageToDisplay)
+						continue;
+
+					if (isBeginRegion == false) {
+						isBeginRegion = true;
+
+						bl = rectTransform.TransformPoint (new Vector3 (currentCharInfo.bottomLeft.x, currentCharInfo.descender, 0));
+						tl = rectTransform.TransformPoint (new Vector3 (currentCharInfo.bottomLeft.x, currentCharInfo.ascender, 0));
+
+						// If Word is one character
+						if (linkInfo.linkTextLength == 1) {
+							isBeginRegion = false;
+
+							br = rectTransform.TransformPoint (new Vector3 (currentCharInfo.topRight.x, currentCharInfo.descender, 0));
+							tr = rectTransform.TransformPoint (new Vector3 (currentCharInfo.topRight.x, currentCharInfo.ascender, 0));
+
+							// Check for Intersection
+							IsCloserToPoint (position, bl, linkInfo, ref minDistance, ref minLinkInfo);
+							IsCloserToPoint (position, tl, linkInfo, ref minDistance, ref minLinkInfo);
+							IsCloserToPoint (position, tr, linkInfo, ref minDistance, ref minLinkInfo);
+							IsCloserToPoint (position, br, linkInfo, ref minDistance, ref minLinkInfo);
+							IsCloserToPoint (position, (bl + br + tl + tr) * 0.25f, linkInfo, ref minDistance, ref minLinkInfo);
 						}
 					}
+
+					// Last Character of Word
+					if (isBeginRegion && j == linkInfo.linkTextLength - 1) {
+						isBeginRegion = false;
+
+						br = rectTransform.TransformPoint (new Vector3 (currentCharInfo.topRight.x, currentCharInfo.descender, 0));
+						tr = rectTransform.TransformPoint (new Vector3 (currentCharInfo.topRight.x, currentCharInfo.ascender, 0));
+
+						IsCloserToPoint (position, bl, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, tl, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, tr, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, br, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, (bl + br + tl + tr) * 0.25f, linkInfo, ref minDistance, ref minLinkInfo);
+					}
+					// If Word is split on more than one line.
+					else if (isBeginRegion && currentLine != text.textInfo.characterInfo [characterIndex + 1].lineNumber) {
+						isBeginRegion = false;
+
+						br = rectTransform.TransformPoint (new Vector3 (currentCharInfo.topRight.x, currentCharInfo.descender, 0));
+						tr = rectTransform.TransformPoint (new Vector3 (currentCharInfo.topRight.x, currentCharInfo.ascender, 0));
+
+						IsCloserToPoint (position, bl, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, tl, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, tr, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, br, linkInfo, ref minDistance, ref minLinkInfo);
+						IsCloserToPoint (position, (bl + br + tl + tr) * 0.25f, linkInfo, ref minDistance, ref minLinkInfo);
+					}
 				}
 			}
-		}
-
-		if (minChar >= 0 && minDistance < 20 && minChar < value.Length) {
-			// i is the index into the string which we clicked.  Determine a "link" by finding the previous '['
-			// and the ending ']'
-
-			// run backwards from here to find the link idex...
-			clickedLinkID = -1;
-			for (int k = minChar; k >= 0; k--) {
-				if (value [k] == '\x0b') {
-					clickedLinkID++;
-				}
-			}
-
-			if(clickedLinkID == -1){
-				return false;
-			}
-
-			int startIndex = -1;
-			int endIndex = -1;
-			for (int k = minChar; k >= 0; k--) {
-				if (value [k] == '\x0b') {
-					startIndex = k;
-					break;
-				}
-				if (value [k] == '\x0c') {
-					endIndex = -1;
-					break;
-				}
-			}
-			for (int k = minChar; k < value.Length; k++) {
-				if (value [k] == '\x0c') {
-					endIndex = k;
-					break;
-				}
-				if (value [k] == '\x0b') {
-					endIndex = -1;
-					break;
-				}
-			}
-
-			if (startIndex >= 0 && endIndex >= 0) {
+
+			int linkIdx = Array.IndexOf (text.textInfo.linkInfo, minLinkInfo);
+			if (linkIdx >= 0) {
 				if (block != null) {
-					string linkText = value.Substring (startIndex + 1, endIndex - startIndex - 1).Trim ();
-					block (linkText, clickedLinkID);
+					block (minLinkInfo.GetLinkText (), linkIdx);
 				}
 				return true;
 			}


Cleaned SystemProductNameFetcher and adde support for Server 2016

--- src/FlaUI.Core/Tools/SystemProductNameFetcher.cs
+++ src/FlaUI.Core/Tools/SystemProductNameFetcher.cs
@@ -5,7 +5,34 @@
 {
     public static class SystemProductNameFetcher
     {
-        public static bool CurrentOsContains(string name)
+        private static readonly string CurrentProductName;
+
+        static SystemProductNameFetcher()
+        {
+            CurrentProductName = GetCurrentProductName();
+        }
+
+        public static bool CurrentProductContains(string name)
+        {
+            return CurrentProductName.Contains(name);
+        }
+
+        public static bool IsWindows8_1()
+        {
+            return CurrentProductContains("Windows 8.1");
+        }
+
+        public static bool IsWindows10()
+        {
+            return CurrentProductContains("Windows 10");
+        }
+
+        public static bool IsWindowsServer2016()
+        {
+            return CurrentProductContains("Windows Server 2016");
+        }
+
+        private static string GetCurrentProductName()
         {
             var reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
             if (reg == null)
@@ -17,17 +44,7 @@
             {
                 throw new Exception("Could not find the registry key needed for determining the OS version.");
             }
-            return productName.Contains(name);
-        }
-
-        public static bool IsWindows8_1()
-        {
-            return CurrentOsContains("Windows 8.1");
-        }
-
-        public static bool IsWindows10()
-        {
-            return CurrentOsContains("Windows 10");
+            return productName;
         }
     }
 }


Use explicit type printer when printing types in C# GenerateMethodSpecifier.

--- src/Generator/Generators/CSharp/CSharpSources.cs
+++ src/Generator/Generators/CSharp/CSharpSources.cs
@@ -2363,20 +2363,20 @@

             var functionName = GetMethodIdentifier(method);

+            var printedType = method.OriginalReturnType.Visit(TypePrinter);
+
             if (method.IsConstructor || method.IsDestructor)
                 Write("{0}(", functionName);
             else if (method.ExplicitInterfaceImpl != null)
-                Write("{0} {1}.{2}(", method.OriginalReturnType,
+                Write("{0} {1}.{2}(", printedType,
                     method.ExplicitInterfaceImpl.Name, functionName);
             else if (method.OperatorKind == CXXOperatorKind.Conversion ||
                      method.OperatorKind == CXXOperatorKind.ExplicitConversion)
             {
-                var printedType = method.OriginalReturnType.Visit(TypePrinter);
                 Write($"{functionName} {printedType}(");
             }
             else
-                Write("{0} {1}(", method.OriginalReturnType, functionName);
-
+                Write("{0} {1}(", printedType, functionName);

             Write(FormatMethodParameters(method.Parameters));


v1.5 bug fix before nuget publish

v1.5 bug fix before nuget publish

--- src/JeffWilcox.PhoneThemeManager/ThemeManager.cs
+++ src/JeffWilcox.PhoneThemeManager/ThemeManager.cs
@@ -679,7 +679,7 @@
                         var asControl = frame as Control;
                         if (asControl != null)
                         {
-                            asControl.Background = _background != null ? _backgroundBrush : new SolidColorBrush(background);
+                            asControl.Background = _backgroundBrush != null ? _backgroundBrush : new SolidColorBrush(background);
                         }

                         // Hook up to the navigation events for the tray.


minor

minor

--- Plugin.BluetoothLE/Platforms/Apple/GattDescriptor.cs
+++ Plugin.BluetoothLE/Platforms/Apple/GattDescriptor.cs
@@ -28,52 +28,46 @@
         public override byte[] Value => (this.native.Value as NSData)?.ToArray();

-        public override IObservable<DescriptorGattResult> Read()
+        public override IObservable<DescriptorGattResult> Read() => Observable.Create<DescriptorGattResult>(ob =>
         {
-            return Observable.Create<DescriptorGattResult>(ob =>
+            var handler = new EventHandler<CBDescriptorEventArgs>((sender, args) =>
             {
-                var handler = new EventHandler<CBDescriptorEventArgs>((sender, args) =>
-                {
-                    if (!this.Equals(args.Descriptor))
-                        return;
+                if (!this.Equals(args.Descriptor))
+                    return;

-                    var result = args.Error == null
-                        ? this.ToResult(GattEvent.Read, this.Value)
-                        : this.ToResult(GattEvent.ReadError, args.Error.ToString());
+                var result = args.Error == null
+                    ? this.ToResult(GattEvent.Read, this.Value)
+                    : this.ToResult(GattEvent.ReadError, args.Error.ToString());

-                    ob.Respond(result);
-                });
-                this.Peripheral.UpdatedValue += handler;
-                this.Peripheral.ReadValue(this.native);
+                ob.Respond(result);
+            });
+            this.Peripheral.UpdatedValue += handler;
+            this.Peripheral.ReadValue(this.native);

-                return () => this.Peripheral.UpdatedValue -= handler;
-            });
-        }
+            return () => this.Peripheral.UpdatedValue -= handler;
+        });

-        public override IObservable<DescriptorGattResult> Write(byte[] data)
+        public override IObservable<DescriptorGattResult> Write(byte[] data) => Observable.Create<DescriptorGattResult>(ob =>
         {
-            return Observable.Create<DescriptorGattResult>(ob =>
+            var handler = new EventHandler<CBDescriptorEventArgs>((sender, args) =>
             {
-                var handler = new EventHandler<CBDescriptorEventArgs>((sender, args) =>
-                {
-                    if (!this.Equals(args.Descriptor))
-                        return;
+                if (!this.Equals(args.Descriptor))
+                    return;

-                    var result = args.Error == null
-                        ? this.ToResult(GattEvent.Write, this.Value)
-                        : this.ToResult(GattEvent.WriteError, args.Error.ToString());
+                var result = args.Error == null
+                    ? this.ToResult(GattEvent.Write, this.Value)
+                    : this.ToResult(GattEvent.WriteError, args.Error.ToString());

-                    ob.Respond(result);
-                });
+                ob.Respond(result);
+            });

-                var nsdata = NSData.FromArray(data);
-                this.Peripheral.WroteDescriptorValue += handler;
-                this.Peripheral.WriteValue(nsdata, this.native);
+            var nsdata = NSData.FromArray(data);
+            this.Peripheral.WroteDescriptorValue += handler;
+            this.Peripheral.WriteValue(nsdata, this.native);

-                return () => this.Peripheral.WroteDescriptorValue -= handler;
-            });
-        }
+            return () => this.Peripheral.WroteDescriptorValue -= handler;
+        });

         bool Equals(CBDescriptor descriptor)