Explorar o código

Refacture trigger code with support for weekday+weekOfMonth (Windows)

Sebastián Katzer %!s(int64=8) %!d(string=hai) anos
pai
achega
8bbeabf008
Modificáronse 23 ficheiros con 1094 adicións e 592 borrados
  1. 4 4
      README.md
  2. 2 1
      plugin.xml
  3. 6 6
      src/windows/LocalNotificationProxy.js
  4. 11 21
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Builder.cs
  5. 3 3
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Manager.cs
  6. 1 11
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Notification.cs
  7. 3 2
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Options.cs
  8. 255 0
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Request.cs
  9. 1 1
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Button.cs
  10. 19 31
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Every.cs
  11. 1 1
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/IAction.cs
  12. 1 1
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Input.cs
  13. 1 1
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/ProgressBar.cs
  14. 137 0
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Trigger.cs
  15. 0 397
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger.cs
  16. 48 0
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger/DateTrigger.cs
  17. 90 0
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger/IntervalTrigger.cs
  18. 389 0
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger/MatchTrigger.cs
  19. 12 7
      src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotificationProxy.csproj
  20. 4 4
      src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/Microsoft.Toolkit.Uwp.Notifications.UWP.nuget.props
  21. 1 1
      src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/Microsoft.Toolkit.Uwp.Notifications.UWP.nuget.targets
  22. 1 1
      src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/project.json
  23. 104 99
      src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/project.lock.json

+ 4 - 4
README.md

@@ -290,15 +290,15 @@ The properties depend on the trigger type. Not all of them are supported across
 |              | every         | Object  | `minute`         | x       | x   | x       |
 |              | every         | Object  | `hour`           | x       | x   | x       |
 |              | every         | Object  | `day`            | x       | x   | x       |
-|              | every         | Object  | `weekday`        | x       | x   |
+|              | every         | Object  | `weekday`        | x       | x   | x       |
 |              | every         | Object  | `weekdayOrdinal` |         | x   |
-|              | every         | Object  | `week`           | x       | x   | x       |
-|              | every         | Object  | `weekOfMonth`    | x       | x   |
+|              | every         | Object  | `week`           |         | x   |
+|              | every         | Object  | `weekOfMonth`    | x       | x   | x       |
 |              | every         | Object  | `month`          | x       | x   | x       |
 |              | every         | Object  | `quarter`        |         | x   |
 |              | every         | Object  | `year`           | x       | x   | x       |
 |              | before        | Date    |                  |
-|              | after         | Date    |                  | x       | x   |
+|              | after         | Date    |                  | x       | x   | x       |
 | Location     |
 |              | center        | Array   | `[lat, long]`    |         | x   |
 |              | radius        | Int     |                  |         | x   |

+ 2 - 1
plugin.xml

@@ -234,10 +234,11 @@
 
     <!-- windows -->
     <platform name="windows">
+<!--
         <framework src="src/windows/lib.UW/x86/LocalNotificationProxy.winmd" target-dir="x86" arch="x86" custom="true"/>
         <framework src="src/windows/lib.UW/x64/LocalNotificationProxy.winmd" target-dir="x64" arch="x64" custom="true"/>
         <framework src="src/windows/lib.UW/ARM/LocalNotificationProxy.winmd" target-dir="ARM" arch="ARM" custom="true"/>
-
+ -->
         <js-module src="src/windows/LocalNotificationProxy.js" name="LocalNotification.Proxy" >
             <merges target="" />
         </js-module>

+ 6 - 6
src/windows/LocalNotificationProxy.js

@@ -447,7 +447,7 @@ exports.parseOptions = function (obj) {
  * @return [ LocalNotification.Trigger ]
  */
 exports.parseTrigger = function (obj) {
-    var trigger = new LocalNotification.Trigger(),
+    var trigger = new LocalNotification.Toast.Trigger(),
         spec    = obj.trigger, val;
 
     if (!spec) return trigger;
@@ -469,12 +469,12 @@ exports.parseTrigger = function (obj) {
  * @return [ LocalNotification.Every|String ]
  */
 exports.parseEvery = function (spec) {
-    var every = new LocalNotification.Every();
+    var every = new LocalNotification.Toast.Every();
 
     if (typeof spec !== 'object') return spec;
 
     for (var prop in every) {
-        if (spec[prop]) every[prop] = parseInt(spec[prop]);
+        if (spec.hasOwnProperty(prop)) every[prop] = parseInt(spec[prop]);
     }
 
     return every;
@@ -494,10 +494,10 @@ exports.parseActions = function (obj) {
 
     for (var action of obj.actions) {
         if (!action.type || action.type == 'button') {
-            btn = new LocalNotification.Button();
+            btn = new LocalNotification.Toast.Button();
         } else
         if (action.type == 'input') {
-            btn = new LocalNotification.Input();
+            btn = new LocalNotification.Toast.Input();
         }
 
         for (var prop in btn) {
@@ -518,7 +518,7 @@ exports.parseActions = function (obj) {
  * @return [ LocalNotification.ProgressBar ]
  */
 exports.parseProgressBar = function (obj) {
-    var bar  = new LocalNotification.ProgressBar(),
+    var bar  = new LocalNotification.Toast.ProgressBar(),
         spec = obj.progressBar;
 
     if (!spec) return bar;

+ 11 - 21
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Builder.cs

@@ -26,13 +26,19 @@ namespace LocalNotificationProxy.LocalNotification
 
     internal class Builder
     {
+        /// <summary>
+        /// The provided trigger request.
+        /// </summary>
+        private readonly Request request;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="Builder"/> class.
         /// </summary>
-        /// <param name="options">Notification properties to set.</param>
-        public Builder(Options options)
+        /// <param name="request">Trigger request.</param>
+        public Builder(Request request)
         {
-            this.Content = new Notification(options);
+            this.request = request;
+            this.Content = new Notification(request.Options);
         }
 
         /// <summary>
@@ -45,11 +51,6 @@ namespace LocalNotificationProxy.LocalNotification
         /// </summary>
         private Options Options { get => this.Content.Options; }
 
-        /// <summary>
-        /// Gets the trigger.
-        /// </summary>
-        private Trigger Trigger { get => this.Options.Trigger; }
-
         /// <summary>
         /// Build a toast notification specified by the options.
         /// </summary>
@@ -65,17 +66,6 @@ namespace LocalNotificationProxy.LocalNotification
             return this.ConvertToastToNotification(toast);
         }
 
-        /// <summary>
-        /// If there is at least one more toast variant to build.
-        /// </summary>
-        /// <returns>True if there are more toasts to build.</returns>
-        public bool HasNext() => this.Trigger.Count >= this.Trigger.Occurrence;
-
-        /// <summary>
-        /// Moves the flag to the next toast variant.
-        /// </summary>
-        public void MoveNext() => this.Trigger.Occurrence += this.HasNext() ? 1 : 0;
-
         /// <summary>
         /// Gets the initialize skeleton for a toast notification.
         /// </summary>
@@ -167,7 +157,7 @@ namespace LocalNotificationProxy.LocalNotification
         private ScheduledToastNotification ConvertToastToNotification(ToastContent toast)
         {
             var xml = toast.GetXml();
-            var at = this.Content.Date;
+            var at = this.request.TriggerDate;
             ScheduledToastNotification notification;
 
             if (!at.HasValue)
@@ -188,7 +178,7 @@ namespace LocalNotificationProxy.LocalNotification
             notification.Tag = this.Options.Id.ToString();
             notification.SuppressPopup = this.Options.Silent;
 
-            if (this.Trigger.Occurrence > 1)
+            if (this.request.Occurrence > 1)
             {
                 notification.Group = notification.Tag;
             }

+ 3 - 3
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Manager.cs

@@ -46,7 +46,8 @@ namespace LocalNotificationProxy.LocalNotification
         {
             foreach (Options options in notifications)
             {
-                var builder = new Builder(options);
+                var request = new Request(options);
+                var builder = new Builder(request);
 
                 do
                 {
@@ -58,9 +59,8 @@ namespace LocalNotificationProxy.LocalNotification
                     }
 
                     ToastNotifier.AddToSchedule(toast);
-                    builder.MoveNext();
                 }
-                while (builder.HasNext());
+                while (request.MoveNext());
             }
         }
 

+ 1 - 11
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Notification.cs

@@ -2,6 +2,7 @@
 {
     using System;
     using System.Collections.Generic;
+    using global::LocalNotificationProxy.LocalNotification.Toast;
     using Microsoft.Toolkit.Uwp.Notifications;
     using Windows.UI.Notifications;
 
@@ -285,17 +286,6 @@
             }
         }
 
-        /// <summary>
-        /// Gets the date when to trigger the notification.
-        /// </summary>
-        public DateTime? Date
-        {
-            get
-            {
-                return this.Options.Trigger.Date;
-            }
-        }
-
         /// <summary>
         /// Gets the instance as an serialized xml element.
         /// </summary>

+ 3 - 2
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Options.cs

@@ -21,6 +21,7 @@
 
 namespace LocalNotificationProxy.LocalNotification
 {
+    using global::LocalNotificationProxy.LocalNotification.Toast;
     using Windows.Data.Xml.Dom;
 
     public sealed class Options
@@ -68,7 +69,7 @@ namespace LocalNotificationProxy.LocalNotification
         /// <summary>
         /// Gets or sets the notification trigger.
         /// </summary>
-        public Trigger Trigger { get; set; }
+        public Toast.Trigger Trigger { get; set; }
 
         /// <summary>
         /// Gets or sets the notification user data.
@@ -105,7 +106,7 @@ namespace LocalNotificationProxy.LocalNotification
 
             options.Id = int.Parse(node.GetAttribute("id"));
             options.Badge = int.Parse(node.GetAttribute("badge"));
-            options.Trigger = Trigger.Parse(node.GetAttribute("trigger"));
+            options.Trigger = Toast.Trigger.Parse(node.GetAttribute("trigger"));
 
             if (node.GetAttributeNode("text") != null)
             {

+ 255 - 0
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Request.cs

@@ -0,0 +1,255 @@
+/*
+ * Apache 2.0 License
+ *
+ * Copyright (c) Sebastian Katzer 2017
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apache License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+namespace LocalNotificationProxy.LocalNotification
+{
+    using System;
+
+    internal class Request
+    {
+        /// <summary>
+        /// The right trigger for the options
+        /// </summary>
+        private readonly Trigger.DateTrigger trigger;
+
+        /// <summary>
+        /// How often the trigger shall occur.
+        /// </summary>
+        private readonly int count;
+
+        /// <summary>
+        /// The trigger spec.
+        /// </summary>
+        private readonly Toast.Trigger spec;
+
+        /// <summary>
+        /// The current trigger date.
+        /// </summary>
+        private DateTime? triggerDate;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Request"/> class.
+        /// </summary>
+        /// <param name="options">The options spec.</param>
+        public Request(Options options)
+        {
+            this.Options = options;
+            this.spec = options.Trigger;
+            this.count = Math.Max(this.spec.Count, 1);
+            this.trigger = this.BuildTrigger();
+            this.triggerDate = this.trigger.GetNextTriggerDate(this.GetBaseDate());
+        }
+
+        /// <summary>
+        /// Gets the options spec.
+        /// </summary>
+        public Options Options { get; private set; }
+
+        /// <summary>
+        /// Gets the value of the internal occurrence counter.
+        /// </summary>
+        public int Occurrence { get => this.trigger.Occurrence; }
+
+        /// <summary>
+        /// Gets a value indicating whether there's one more trigger date to calculate.
+        /// </summary>
+        public bool HasNext { get => this.triggerDate.HasValue && this.Occurrence <= this.count; }
+
+        /// <summary>
+        /// Gets the current trigger date.
+        /// </summary>
+        public DateTime? TriggerDate
+        {
+            get
+            {
+                if (!this.triggerDate.HasValue)
+                {
+                    return null;
+                }
+
+                var minDate = DateTime.Now.AddSeconds(0.2);
+
+                if (this.triggerDate >= minDate)
+                {
+                    return this.triggerDate;
+                }
+
+                if ((minDate - this.triggerDate).Value.TotalMinutes <= 1)
+                {
+                    return minDate;
+                }
+
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// Moves the internal occurrence counter by one.
+        /// </summary>
+        /// <returns>false if it wasnt possible anymore to move ahead.</returns>
+        public bool MoveNext()
+        {
+            if (this.HasNext)
+            {
+                this.triggerDate = this.GetNextTriggerDate();
+            }
+            else
+            {
+                this.triggerDate = null;
+            }
+
+            return this.triggerDate.HasValue;
+        }
+
+        /// <summary>
+        /// Gets the next trigger date based on the current trigger date.
+        /// </summary>
+        /// <returns>null if there's no next one.</returns>
+        private DateTime? GetNextTriggerDate()
+        {
+            if (this.triggerDate.HasValue)
+            {
+                return this.trigger.GetNextTriggerDate(this.triggerDate.Value);
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// Build the trigger specified in options.
+        /// </summary>
+        /// <returns>Configured trigger instance</returns>
+        private Trigger.DateTrigger BuildTrigger()
+        {
+            if (this.spec.Every is Toast.Every)
+            {
+                var matchers = this.GetMatchers();
+                var specials = this.GetSpecials();
+
+                return new Trigger.MatchTrigger(matchers, specials);
+            }
+
+            var unit = this.GetUnit();
+            var ticks = this.GetTicks();
+
+            return new Trigger.IntervalTrigger(ticks, unit);
+        }
+
+        /// <summary>
+        /// Gets the unit value.
+        /// </summary>
+        /// <returns>SECOND by default.</returns>
+        private Trigger.DateTrigger.Unit GetUnit()
+        {
+            var unit = "SECOND";
+
+            if (!string.IsNullOrEmpty(this.spec.Unit))
+            {
+                unit = this.spec.Unit;
+            }
+            else if (this.spec.Every is string)
+            {
+                unit = this.spec.Every as string;
+            }
+
+            return (Trigger.DateTrigger.Unit)Enum.Parse(
+                typeof(Trigger.DateTrigger.Unit), unit.ToUpper());
+        }
+
+        /// <summary>
+        /// Gets the tick value.
+        /// </summary>
+        /// <returns>Defaults to 0</returns>
+        private int GetTicks()
+        {
+            if (this.spec.At != 0)
+            {
+                return 0;
+            }
+            else if (this.spec.In != 0)
+            {
+                return this.spec.In;
+            }
+            else if (this.spec.Every is string)
+            {
+                return 1;
+            }
+            else if (this.spec.Every is double)
+            {
+                return Convert.ToInt32(this.spec.Every);
+            }
+
+            return 0;
+        }
+
+        /// <summary>
+        /// Gets an array of all date parts to construct a datetime instance.
+        /// </summary>
+        /// <returns>[min, hour, day, month, year]</returns>
+        private int?[] GetMatchers()
+        {
+            var every = this.spec.Every as Toast.Every;
+
+            return new int?[]
+            {
+                every.Minute, every.Hour, every.Day, every.Month, every.Year
+            };
+        }
+
+        /// <summary>
+        /// Gets an array of all date parts to construct a datetime instance.
+        /// </summary>
+        /// <returns>[weekday, weekdayOrdinal, weekOfMonth, quarter]</returns>
+        private int?[] GetSpecials()
+        {
+            var every = this.spec.Every as Toast.Every;
+
+            return new int?[]
+            {
+                every.Weekday, every.WeekdayOrdinal, every.WeekOfMonth, every.Quarter
+            };
+        }
+
+        /// <summary>
+        /// Gets the base date from where to calculate the next trigger date.
+        /// </summary>
+        /// <returns>Usually points to now</returns>
+        private DateTime GetBaseDate()
+        {
+            if (this.spec.At != 0)
+            {
+                return DateTimeOffset.FromUnixTimeMilliseconds(this.spec.At).LocalDateTime;
+            }
+            else if (this.spec.FirstAt != 0)
+            {
+                return DateTimeOffset.FromUnixTimeMilliseconds(this.spec.At).LocalDateTime;
+            }
+            else if (this.spec.After != 0)
+            {
+                return DateTimeOffset.FromUnixTimeMilliseconds(this.spec.After).LocalDateTime;
+            }
+
+            return DateTime.Now;
+        }
+    }
+}

+ 1 - 1
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Button.cs → src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Button.cs

@@ -19,7 +19,7 @@
  * limitations under the License.
  */
 
-namespace LocalNotificationProxy.LocalNotification
+namespace LocalNotificationProxy.LocalNotification.Toast
 {
     public sealed class Button : IAction
     {

+ 19 - 31
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Every.cs → src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Every.cs

@@ -19,14 +19,10 @@
  * limitations under the License.
  */
 
-namespace LocalNotificationProxy.LocalNotification
+namespace LocalNotificationProxy.LocalNotification.Toast
 {
-    using System;
-
     public sealed class Every
     {
-        private static readonly string[] Intervals = { null, "minute", "hour", "day", "month", "year" };
-
         /// <summary>
         /// Gets or sets the minute.
         /// </summary>
@@ -43,46 +39,38 @@ namespace LocalNotificationProxy.LocalNotification
         public int? Day { get; set; }
 
         /// <summary>
-        /// Gets or sets the month.
+        /// Gets or sets the day of week.
         /// </summary>
-        public int? Month { get; set; }
+        public int? Weekday { get; set; }
 
         /// <summary>
-        /// Gets or sets the year.
+        /// Gets or sets the week of year.
         /// </summary>
-        public int? Year { get; set; }
+        public int? Week { get; set; }
 
         /// <summary>
-        /// Gets the interval as a string representation.
+        /// Gets or sets the day of ordinal week.
         /// </summary>
-        /// <returns>year, month, ...</returns>
-        internal string Interval { get => Intervals[Array.IndexOf(this.ToArray(), null) + 1]; }
+        public int? WeekdayOrdinal { get; set; }
 
         /// <summary>
-        /// Converts the date time components into a datetime object.
+        /// Gets or sets the week of month.
         /// </summary>
-        /// <param name="now">The relative date to calculate the date from.</param>
-        /// <returns>A datetime object</returns>
-        internal DateTime ToDateTime(DateTime now)
-        {
-            var p = this.ToArray();
+        public int? WeekOfMonth { get; set; }
 
-            p[0] = this.Minute.GetValueOrDefault();
-            p[1] = this.Hour.GetValueOrDefault();
-            p[2] = this.Day.GetValueOrDefault(now.Day);
-            p[3] = this.Month.GetValueOrDefault(now.Month);
-            p[4] = this.Year.GetValueOrDefault(now.Year);
+        /// <summary>
+        /// Gets or sets the month.
+        /// </summary>
+        public int? Month { get; set; }
 
-            return new DateTime(p[4].Value, p[3].Value, p[2].Value, p[1].Value, p[0].Value, 0);
-        }
+        /// <summary>
+        /// Gets or sets the quarter.
+        /// </summary>
+        public int? Quarter { get; set; }
 
         /// <summary>
-        /// Gets an array of all date parts to construct a datetime instance.
+        /// Gets or sets the year.
         /// </summary>
-        /// <returns>[min, hour, day, month, year]</returns>
-        private int?[] ToArray()
-        {
-            return new int?[] { this.Minute, this.Hour, this.Day, this.Month, this.Year };
-        }
+        public int? Year { get; set; }
     }
 }

+ 1 - 1
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/IAction.cs → src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/IAction.cs

@@ -19,7 +19,7 @@
  * limitations under the License.
  */
 
-namespace LocalNotificationProxy.LocalNotification
+namespace LocalNotificationProxy.LocalNotification.Toast
 {
     public interface IAction
     {

+ 1 - 1
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Input.cs → src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Input.cs

@@ -19,7 +19,7 @@
  * limitations under the License.
  */
 
-namespace LocalNotificationProxy.LocalNotification
+namespace LocalNotificationProxy.LocalNotification.Toast
 {
     public sealed class Input : IAction
     {

+ 1 - 1
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/ProgressBar.cs → src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/ProgressBar.cs

@@ -19,7 +19,7 @@
  * limitations under the License.
  */
 
-namespace LocalNotificationProxy.LocalNotification
+namespace LocalNotificationProxy.LocalNotification.Toast
 {
     public sealed class ProgressBar
     {

+ 137 - 0
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Toast/Trigger.cs

@@ -0,0 +1,137 @@
+/*
+ * Apache 2.0 License
+ *
+ * Copyright (c) Sebastian Katzer 2017
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apache License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+namespace LocalNotificationProxy.LocalNotification.Toast
+{
+    using Windows.Data.Xml.Dom;
+
+    public sealed class Trigger
+    {
+        // private DateTime? triggerDate;
+
+        /// <summary>
+        /// Gets the trigger type.
+        /// </summary>
+        public string Type { get; } = "calendar";
+
+        /// <summary>
+        /// Gets or sets the fix trigger date.
+        /// </summary>
+        public long At { get; set; } = 0;
+
+        /// <summary>
+        /// Gets or sets the first trigger date.
+        /// </summary>
+        public long FirstAt { get; set; } = 0;
+
+        /// <summary>
+        /// Gets or sets the after trigger date.
+        /// </summary>
+        public long After { get; set; } = 0;
+
+        /// <summary>
+        /// Gets or sets the relative trigger date from now.
+        /// </summary>
+        public int In { get; set; } = 0;
+
+        /// <summary>
+        /// Gets or sets the trigger count.
+        /// </summary>
+        public int Count { get; set; } = 1;
+
+        /// <summary>
+        /// Gets the trigger occurrence.
+        /// </summary>
+        public int Occurrence { get; internal set; } = 1;
+
+        /// <summary>
+        /// Gets or sets the trigger interval.
+        /// </summary>
+        public object Every { get; set; }
+
+        /// <summary>
+        /// Gets or sets the trigger unit.
+        /// </summary>
+        public string Unit { get; set; }
+
+        /// <summary>
+        /// Deserializes the XML string into an instance of Trigger.
+        /// </summary>
+        /// <param name="xml">The serialized instance of Options as an xml string.</param>
+        /// <returns>An instance where all properties have been assigned.</returns>
+        internal static Trigger Parse(string xml)
+        {
+            var doc = new XmlDocument();
+            doc.LoadXml(xml);
+
+            var trigger = new Trigger();
+            var node = doc.DocumentElement;
+
+            trigger.At = int.Parse(node.GetAttribute("at"));
+            trigger.FirstAt = int.Parse(node.GetAttribute("firstAt"));
+            trigger.After = int.Parse(node.GetAttribute("after"));
+            trigger.In = int.Parse(node.GetAttribute("in"));
+            trigger.Count = int.Parse(node.GetAttribute("count"));
+            trigger.Occurrence = int.Parse(node.GetAttribute("occurrence"));
+
+            if (node.GetAttributeNode("unit") != null)
+            {
+                trigger.Unit = node.GetAttribute("unit");
+            }
+
+            if (node.GetAttributeNode("every") != null)
+            {
+                trigger.Every = node.GetAttribute("every");
+            }
+
+            return trigger;
+        }
+
+        /// <summary>
+        /// Gets the instance as an serialized xml element.
+        /// </summary>
+        /// <returns>Element with all property values set as attributes.</returns>
+        internal string GetXml()
+        {
+            var node = new XmlDocument().CreateElement("trigger");
+
+            node.SetAttribute("at", this.At.ToString());
+            node.SetAttribute("firstAt", this.FirstAt.ToString());
+            node.SetAttribute("after", this.After.ToString());
+            node.SetAttribute("in", this.In.ToString());
+            node.SetAttribute("count", this.Count.ToString());
+            node.SetAttribute("occurrence", this.Occurrence.ToString());
+
+            if (!string.IsNullOrEmpty(this.Unit))
+            {
+                node.SetAttribute("unit", this.Unit);
+            }
+
+            if (this.Every != null && !(this.Every is Every))
+            {
+                node.SetAttribute("every", this.Every.ToString());
+            }
+
+            return node.GetXml();
+        }
+    }
+
+}

+ 0 - 397
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger.cs

@@ -1,397 +0,0 @@
-/*
- * Apache 2.0 License
- *
- * Copyright (c) Sebastian Katzer 2017
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apache License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://opensource.org/licenses/Apache-2.0/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- */
-
-namespace LocalNotificationProxy.LocalNotification
-{
-    using System;
-    using Windows.Data.Xml.Dom;
-
-    public sealed class Trigger
-    {
-        private DateTime? triggerDate;
-
-        /// <summary>
-        /// Gets the trigger type.
-        /// </summary>
-        public string Type { get; } = "calendar";
-
-        /// <summary>
-        /// Gets or sets the fix trigger date.
-        /// </summary>
-        public long At { get; set; } = 0;
-
-        /// <summary>
-        /// Gets or sets the first trigger date.
-        /// </summary>
-        public long FirstAt { get; set; } = 0;
-
-        /// <summary>
-        /// Gets or sets the after trigger date.
-        /// </summary>
-        public long After { get; set; } = 0;
-
-        /// <summary>
-        /// Gets or sets the relative trigger date from now.
-        /// </summary>
-        public int In { get; set; } = 0;
-
-        /// <summary>
-        /// Gets or sets the trigger count.
-        /// </summary>
-        public int Count { get; set; } = 1;
-
-        /// <summary>
-        /// Gets the trigger occurrence.
-        /// </summary>
-        public int Occurrence { get; internal set; } = 1;
-
-        /// <summary>
-        /// Gets or sets the trigger interval.
-        /// </summary>
-        public object Every { get; set; }
-
-        /// <summary>
-        /// Gets or sets the trigger unit.
-        /// </summary>
-        public string Unit { get; set; } = "second";
-
-        /// <summary>
-        /// Gets the date when to trigger the notification.
-        /// </summary>
-        internal DateTime? Date
-        {
-            get
-            {
-                if (!this.triggerDate.HasValue)
-                {
-                    this.triggerDate = this.Every is Every ? this.GetRelDate() : this.GetFixDate();
-                }
-
-                if (!this.triggerDate.HasValue)
-                {
-                    return null;
-                }
-
-                var date = this.GetNextTriggerDate();
-                var minDate = DateTime.Now.AddSeconds(0.2);
-
-                if (!date.HasValue)
-                {
-                    return null;
-                }
-
-                if (date >= minDate)
-                {
-                    return date;
-                }
-
-                if ((minDate - date).Value.TotalMinutes <= 1)
-                {
-                    return minDate;
-                }
-
-                return null;
-            }
-        }
-
-        /// <summary>
-        /// Deserializes the XML string into an instance of Trigger.
-        /// </summary>
-        /// <param name="xml">The serialized instance of Options as an xml string.</param>
-        /// <returns>An instance where all properties have been assigned.</returns>
-        internal static Trigger Parse(string xml)
-        {
-            var doc = new XmlDocument();
-            doc.LoadXml(xml);
-
-            var trigger = new Trigger();
-            var node = doc.DocumentElement;
-
-            trigger.At = int.Parse(node.GetAttribute("at"));
-            trigger.FirstAt = int.Parse(node.GetAttribute("firstAt"));
-            trigger.After = int.Parse(node.GetAttribute("after"));
-            trigger.In = int.Parse(node.GetAttribute("in"));
-            trigger.Unit = node.GetAttribute("unit");
-            trigger.Count = int.Parse(node.GetAttribute("count"));
-            trigger.Occurrence = int.Parse(node.GetAttribute("occurrence"));
-
-            if (node.GetAttributeNode("every") != null)
-            {
-                trigger.Every = node.GetAttribute("every");
-            }
-
-            return trigger;
-        }
-
-        /// <summary>
-        /// Gets the instance as an serialized xml element.
-        /// </summary>
-        /// <returns>Element with all property values set as attributes.</returns>
-        internal string GetXml()
-        {
-            var node = new XmlDocument().CreateElement("trigger");
-
-            node.SetAttribute("at", this.At.ToString());
-            node.SetAttribute("firstAt", this.FirstAt.ToString());
-            node.SetAttribute("after", this.After.ToString());
-            node.SetAttribute("in", this.In.ToString());
-            node.SetAttribute("unit", this.Unit);
-            node.SetAttribute("count", this.Count.ToString());
-            node.SetAttribute("occurrence", this.Occurrence.ToString());
-
-            if (this.Every != null && !(this.Every is Every))
-            {
-                node.SetAttribute("every", this.Every.ToString());
-            }
-
-            return node.GetXml();
-        }
-
-        /// <summary>
-        /// Adds the interval to the specified date.
-        /// </summary>
-        /// <param name="date">The date where to add the interval of ticks</param>
-        /// <param name="interval">minute, hour, day, ...</param>
-        /// <param name="ticks">The number of minutes, hours, days, ...</param>
-        /// <returns>A new datetime instance</returns>
-        private DateTime? AddInterval(DateTime date, string interval, int ticks)
-        {
-            switch (interval)
-            {
-                case null:
-                case "":
-                    return null;
-                case "second":
-                    return date.AddSeconds(ticks);
-                case "minute":
-                    return date.AddMinutes(ticks);
-                case "hour":
-                    return date.AddHours(ticks);
-                case "day":
-                    return date.AddDays(ticks);
-                case "week":
-                    return date.AddDays(ticks * 7);
-                case "month":
-                    return date.AddMonths(ticks);
-                case "quarter":
-                    return date.AddMonths(ticks * 3);
-                case "year":
-                    return date.AddYears(ticks);
-                default:
-                    return null;
-            }
-        }
-
-        /// <summary>
-        /// Gets the date when to trigger the notification.
-        /// </summary>
-        /// <returns>The fix date specified by trigger.at or trigger.in</returns>
-        private DateTime? GetFixDate()
-        {
-            if (this.At != 0)
-            {
-                return this.GetDateTime(this.At);
-            }
-
-            if (this.FirstAt != 0)
-            {
-                return this.GetDateTime(this.FirstAt);
-            }
-
-            return this.AddInterval(DateTime.Now, this.Unit, this.In);
-        }
-
-        /// <summary>
-        /// Gets the date when to trigger the notification.
-        /// </summary>
-        /// <returns>The first matching date specified by trigger.every</returns>
-        private DateTime? GetRelDate()
-        {
-            if (this.After != 0)
-            {
-                return this.GetDateTime(this.After);
-            }
-
-            return this.GetRelDate(DateTime.Now);
-        }
-
-        /// <summary>
-        /// Gets the date when to trigger the notification.
-        /// </summary>
-        /// <param name="now">The relative date to calculate the date from.</param>
-        /// <returns>The first matching date specified by trigger.every</returns>
-        private DateTime? GetRelDate(DateTime now)
-        {
-            var every = this.Every as Every;
-            var date = every.ToDateTime(now);
-
-            if (date >= now)
-            {
-                return date;
-            }
-
-            if (every.Interval == null || date.Year < now.Year)
-            {
-                return null;
-            }
-
-            if (date.Month < now.Month)
-            {
-                switch (every.Interval)
-                {
-                    case "minute":
-                    case "hour":
-                    case "day":
-                        if (!every.Year.HasValue)
-                        {
-                            return date.AddYears(now.Year - date.Year + 1);
-                        }
-
-                        break;
-                    case "year":
-                        return date.AddYears(now.Year - date.Year + 1);
-                }
-            }
-            else if (date.Day < now.Day)
-            {
-                switch (every.Interval)
-                {
-                    case "minute":
-                    case "hour":
-                        if (!every.Month.HasValue)
-                        {
-                            return date.AddMonths(now.Month - date.Month + 1);
-                        }
-                        else if (!every.Year.HasValue)
-                        {
-                            return date.AddYears(now.Year - date.Year + 1);
-                        }
-
-                        break;
-                    case "month":
-                        return date.AddMonths(now.Month - date.Month + 1);
-                    case "year":
-                        return date.AddYears(now.Year - date.Year + 1);
-                }
-            }
-            else if (date.Hour < now.Hour)
-            {
-                switch (every.Interval)
-                {
-                    case "minute":
-                        if (!every.Day.HasValue)
-                        {
-                            return date.AddDays(now.Day - date.Day + 1);
-                        }
-                        else if (!every.Month.HasValue)
-                        {
-                            return date.AddMonths(now.Month - date.Month + 1);
-                        }
-
-                        break;
-                    case "hour":
-                        return date.AddHours(now.Hour - date.Hour);
-                    case "day":
-                        return date.AddDays(now.Day - date.Day + 1);
-                    case "month":
-                        return date.AddMonths(now.Month - date.Month + 1);
-                    case "year":
-                        return date.AddYears(now.Year - date.Year + 1);
-                }
-            }
-            else if (date.Minute < now.Minute)
-            {
-                switch (every.Interval)
-                {
-                    case "minute":
-                        return date.AddMinutes(now.Minute - date.Minute + 1);
-                    case "hour":
-                        return date.AddHours(now.Hour - date.Hour + 1);
-                    case "day":
-                        return date.AddDays(now.Day - date.Day + 1);
-                    case "month":
-                        return date.AddMonths(now.Month - date.Month + 1);
-                    case "year":
-                        return date.AddYears(now.Year - date.Year + 1);
-                }
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Calculates the next trigger date by adding (interval * occurence)
-        /// </summary>
-        /// <returns>The next valid trigger date</returns>
-        private DateTime? GetNextTriggerDate()
-        {
-            var every = this.Every;
-            var multiple = this.Occurrence;
-            var date = this.triggerDate.Value;
-            DateTime? nextDate;
-
-            if (this.Every is Every)
-            {
-                every = (this.Every as Every).Interval;
-                multiple -= 1;
-            }
-
-            if (every == null)
-            {
-                return date;
-            }
-
-            if (every is double)
-            {
-                var ticks = Convert.ToInt32(every);
-
-                if (ticks == 0)
-                {
-                    return null;
-                }
-
-                nextDate = this.AddInterval(date, this.Unit, multiple * ticks);
-            }
-            else
-            {
-                nextDate = this.AddInterval(date, every as string, multiple);
-
-                if (nextDate.HasValue && this.Every is Every)
-                {
-                    nextDate = this.GetRelDate(nextDate.Value);
-                }
-            }
-
-            return nextDate;
-        }
-
-        /// <summary>
-        /// Convert the milliseconds into a date time object.
-        /// </summary>
-        /// <param name="time">The milli seconds since unix zero.</param>
-        /// <returns>The date time</returns>
-        private DateTime GetDateTime(long time)
-        {
-            return DateTimeOffset.FromUnixTimeMilliseconds(time).LocalDateTime;
-        }
-    }
-
-}

+ 48 - 0
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger/DateTrigger.cs

@@ -0,0 +1,48 @@
+/*
+ * Apache 2.0 License
+ *
+ * Copyright (c) Sebastian Katzer 2017
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apache License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+namespace LocalNotificationProxy.LocalNotification.Trigger
+{
+    using System;
+
+    internal abstract class DateTrigger
+    {
+        /// <summary>
+        /// Default unit is SECOND
+        /// </summary>
+        public enum Unit : byte
+        {
+            NULL, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR
+        }
+
+        /// <summary>
+        /// Gets or sets the occurrence counter.
+        /// </summary>
+        public int Occurrence { get; protected set; } = 1;
+
+        /// <summary>
+        /// Gets the next trigger date.
+        /// </summary>
+        /// <param name="date">The date from where to calculate the next one.</param>
+        /// <returns>Null if there is no next trigger date.</returns>
+        public abstract DateTime? GetNextTriggerDate(DateTime date);
+    }
+}

+ 90 - 0
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger/IntervalTrigger.cs

@@ -0,0 +1,90 @@
+/*
+ * Apache 2.0 License
+ *
+ * Copyright (c) Sebastian Katzer 2017
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apache License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+namespace LocalNotificationProxy.LocalNotification.Trigger
+{
+    using System;
+
+    internal class IntervalTrigger : DateTrigger
+    {
+        /// <summary>
+        /// The number of ticks per interval.
+        /// </summary>
+        private readonly int ticks;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="IntervalTrigger"/> class.
+        /// </summary>
+        /// <param name="ticks">The number of ticks per interval.</param>
+        /// <param name="unit">The unit of the ticks.</param>
+        public IntervalTrigger(int ticks, Unit unit)
+        {
+            this.ticks = ticks;
+            this.Unit = unit;
+        }
+
+        /// <summary>
+        /// Gets the unit of the ticks
+        /// </summary>
+        internal new Unit Unit { get; private set; }
+
+        /// <summary>
+        /// Gets the next trigger date.
+        /// </summary>
+        /// <param name="date">The date from where to calculate the next one.</param>
+        /// <returns>Null if there is no next trigger date.</returns>
+        public override DateTime? GetNextTriggerDate(DateTime date)
+        {
+            this.Occurrence += 1;
+            return this.AddInterval(date);
+        }
+
+        /// <summary>
+        /// Adds the interval to the specified date.
+        /// </summary>
+        /// <param name="date">The date where to add the interval of ticks</param>
+        /// <returns>A new datetime instance</returns>
+        protected DateTime AddInterval(DateTime date)
+        {
+            switch (this.Unit)
+            {
+                case Unit.SECOND:
+                    return date.AddSeconds(this.ticks);
+                case Unit.MINUTE:
+                    return date.AddMinutes(this.ticks);
+                case Unit.HOUR:
+                    return date.AddHours(this.ticks);
+                case Unit.DAY:
+                    return date.AddDays(this.ticks);
+                case Unit.WEEK:
+                    return date.AddDays(this.ticks * 7);
+                case Unit.MONTH:
+                    return date.AddMonths(this.ticks);
+                case Unit.QUARTER:
+                    return date.AddMonths(this.ticks * 3);
+                case Unit.YEAR:
+                    return date.AddYears(this.ticks);
+                default:
+                    return date;
+            }
+        }
+    }
+}

+ 389 - 0
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotification/Trigger/MatchTrigger.cs

@@ -0,0 +1,389 @@
+/*
+ * Apache 2.0 License
+ *
+ * Copyright (c) Sebastian Katzer 2017
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apache License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+namespace LocalNotificationProxy.LocalNotification.Trigger
+{
+    using System;
+    using System.Globalization;
+
+    internal class MatchTrigger : IntervalTrigger
+    {
+        /// <summary>
+        /// Used to determine the interval
+        /// </summary>
+        private static readonly Unit?[] INTERVALS = { null, Unit.MINUTE, Unit.HOUR, Unit.DAY, Unit.MONTH, Unit.YEAR };
+
+        /// <summary>
+        /// Maps these crap where Sunday is the 1st day of the week.
+        /// </summary>
+        private static readonly int[] WEEKDAYS = { 7, 1, 2, 3, 4, 5, 6 };
+
+        /// <summary>
+        /// The matching components.
+        /// </summary>
+        private readonly int?[] matchers;
+
+        /// <summary>
+        /// The special matching components.
+        /// </summary>
+        private readonly int?[] specials;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MatchTrigger"/> class.
+        /// </summary>
+        /// <param name="matchers">The matching components.</param>
+        /// <param name="specials">The special matching components.</param>
+        public MatchTrigger(int?[] matchers, int?[] specials)
+            : base(1, GetUnit(matchers, specials))
+        {
+            this.matchers = matchers;
+            this.specials = specials;
+        }
+
+        /// <summary>
+        /// Gets the next trigger date.
+        /// </summary>
+        /// <param name="baseDate">The date from where to calculate the next one.</param>
+        /// <returns>Null if there is no next trigger date.</returns>
+        public override DateTime? GetNextTriggerDate(DateTime baseDate)
+        {
+            DateTime date = baseDate;
+
+            if (this.Occurrence > 1)
+            {
+                date = this.AddInterval(baseDate);
+            }
+
+            this.Occurrence += 1;
+
+            return this.GetTriggerDate(date);
+        }
+
+        /// <summary>
+        /// Gets the unit interval specified by the matching components.
+        /// </summary>
+        /// <param name="matchers">The matching components.</param>
+        /// <param name="specials">The special matching components.</param>
+        /// <returns>The interval unit.</returns>
+        private static Unit GetUnit(int?[] matchers, int?[] specials)
+        {
+            Unit unit1 = INTERVALS[1 + Array.IndexOf(matchers, null)].GetValueOrDefault(Unit.NULL),
+                 unit2 = Unit.NULL;
+
+            if (specials[0].HasValue)
+            {
+                unit2 = Unit.WEEK;
+            }
+
+            if (unit2 == Unit.NULL)
+            {
+                return unit1;
+            }
+
+            return (unit1.CompareTo(unit2) < 0) ? unit2 : unit1;
+        }
+
+        /// <summary>
+        /// Gets the date from where to start calculating the initial trigger date.
+        /// </summary>
+        /// <param name="date">Usually now.</param>
+        /// <returns>The initial trigger date.</returns>
+        private DateTime GetBaseTriggerDate(DateTime date)
+        {
+            return new DateTime(
+                this.matchers[4].GetValueOrDefault(date.Year),
+                this.matchers[3].GetValueOrDefault(date.Month),
+                this.matchers[2].GetValueOrDefault(date.Day),
+                this.matchers[1].GetValueOrDefault(0),
+                this.matchers[0].GetValueOrDefault(0),
+                0);
+        }
+
+        /// <summary>
+        /// Gets the date when to trigger the notification.
+        /// </summary>
+        /// <param name="now">The date from where to calculate the trigger date.</param>
+        /// <returns>null if there's none trigger date.</returns>
+        private DateTime? GetTriggerDate(DateTime now)
+        {
+            var date = this.GetBaseTriggerDate(now);
+
+            if (date >= now)
+            {
+                return this.ApplySpecials(date);
+            }
+
+            if (this.Unit == Unit.NULL || date.Year < now.Year)
+            {
+                return null;
+            }
+
+            if (date.Month < now.Month)
+            {
+                switch (this.Unit)
+                {
+                    case Unit.MINUTE:
+                    case Unit.HOUR:
+                    case Unit.DAY:
+                    case Unit.WEEK:
+                        if (!this.matchers[4].HasValue)
+                        {
+                            date = date.AddYears(now.Year - date.Year + 1);
+                            break;
+                        }
+                        else
+                        {
+                            return null;
+                        }
+
+                    case Unit.YEAR:
+                        date = date.AddYears(now.Year - date.Year + 1);
+                        break;
+                }
+            }
+            else if (date.DayOfYear < now.DayOfYear)
+            {
+                switch (this.Unit)
+                {
+                    case Unit.MINUTE:
+                    case Unit.HOUR:
+                        if (!this.matchers[3].HasValue)
+                        {
+                            date = date.AddMonths(now.Month - date.Month + 1);
+                        }
+                        else if (!this.matchers[4].HasValue)
+                        {
+                            date = date.AddYears(now.Year - date.Year + 1);
+                        }
+                        else
+                        {
+                            return null;
+                        }
+
+                        break;
+                    case Unit.MONTH:
+                        date = date.AddMonths(now.Month - date.Month + 1);
+                        break;
+                    case Unit.YEAR:
+                        date = date.AddYears(now.Year - date.Year + 1);
+                        break;
+                }
+            }
+            else if (date.Hour < now.Hour)
+            {
+                switch (this.Unit)
+                {
+                    case Unit.MINUTE:
+                        if (!this.matchers[2].HasValue)
+                        {
+                            date = date.AddDays(now.DayOfYear - date.DayOfYear + 1);
+                        }
+                        else if (!this.matchers[3].HasValue)
+                        {
+                            date = date.AddMonths(now.Month - date.Month + 1);
+                        }
+                        else
+                        {
+                            return null;
+                        }
+
+                        break;
+                    case Unit.HOUR:
+                        date = date.AddHours(now.Hour - date.Hour);
+                        break;
+                    case Unit.DAY:
+                    case Unit.WEEK:
+                        date = date.AddDays(now.Day - date.Day + 1);
+                        break;
+                    case Unit.MONTH:
+                        date = date.AddMonths(now.Month - date.Month + 1);
+                        break;
+                    case Unit.YEAR:
+                        date.AddYears(now.Year - date.Year + 1);
+                        break;
+                }
+            }
+            else if (date.Minute < now.Minute)
+            {
+                switch (this.Unit)
+                {
+                    case Unit.MINUTE:
+                        date = date.AddMinutes(now.Minute - date.Minute + 1);
+                        break;
+                    case Unit.HOUR:
+                        date = date.AddHours(now.Hour - date.Hour + 1);
+                        break;
+                    case Unit.DAY:
+                    case Unit.WEEK:
+                        date = date.AddDays(now.DayOfYear - date.DayOfYear + 1);
+                        break;
+                    case Unit.MONTH:
+                        date = date.AddMonths(now.Month - date.Month + 1);
+                        break;
+                    case Unit.YEAR:
+                        date = date.AddYears(now.Year - date.Year + 1);
+                        break;
+                }
+            }
+
+            return this.ApplySpecials(date);
+        }
+
+        /// <summary>
+        /// Applies the special matching components.
+        /// </summary>
+        /// <param name="date">The date to manipulate</param>
+        /// <returns>The manipulated date.</returns>
+        private DateTime? ApplySpecials(DateTime date)
+        {
+            DateTime? cal = date;
+
+            if (this.specials[2].HasValue)
+            {
+                cal = this.SetWeekOfMonth(date);
+            }
+
+            if (this.specials[0].HasValue && cal.HasValue)
+            {
+                cal = this.SetDayOfWeek(cal.Value);
+            }
+
+            return cal;
+        }
+
+        /// <summary>
+        /// Set the day of the year but ensure that the calendar does point to a
+        /// date in future.
+        /// </summary>
+        /// <param name="date">The date to manipulate</param>
+        /// <returns>The calculatred date or null if not possible</returns>
+        private DateTime? SetDayOfWeek(DateTime date)
+        {
+            var day = WEEKDAYS[(int)date.DayOfWeek];
+            var month = date.Month;
+            var year = date.Year;
+            var dayToSet = this.specials[0].Value;
+
+            if (this.matchers[2].HasValue)
+            {
+                return null;
+            }
+
+            if (day > dayToSet)
+            {
+                if (!this.specials[2].HasValue)
+                {
+                    date = date.AddDays(7);
+                }
+                else if (!this.matchers[3].HasValue)
+                {
+                    date = date.AddMonths(1);
+                }
+                else if (!this.matchers[4].HasValue)
+                {
+                    date = date.AddYears(1);
+                }
+                else
+                {
+                    return null;
+                }
+            }
+
+            date = date.AddDays(dayToSet - day);
+
+            if (this.matchers[3].HasValue && date.Month != month)
+            {
+                return null;
+            }
+
+            if (this.matchers[4].HasValue && date.Year != year)
+            {
+                return null;
+            }
+
+            return date;
+        }
+
+        /// <summary>
+        /// Set the day of the year but ensure that the calendar does point to a
+        /// date in future.
+        /// </summary>
+        /// <param name="date">The date to manipulate</param>
+        /// <returns>The calculatred date or null if not possible</returns>
+        private DateTime? SetWeekOfMonth(DateTime date)
+        {
+            var week = this.GetWeekOFMonth(date);
+            var year = date.Year;
+            var weekToSet = this.specials[2].Value;
+
+            if (week > weekToSet)
+            {
+                if (!this.matchers[3].HasValue)
+                {
+                    date = date.AddMonths(1);
+                }
+                else if (!this.matchers[4].HasValue)
+                {
+                    date = date.AddYears(1);
+                }
+                else
+                {
+                    return null;
+                }
+
+                if (this.matchers[4].HasValue && date.Year != year)
+                {
+                    return null;
+                }
+            }
+
+            int month = date.Month;
+
+            date = date.AddDays((weekToSet - week) * 7);
+
+            if (date.Month != month)
+            {
+                date = new DateTime(date.Year, month, 1, date.Hour, date.Minute, 0);
+            }
+            else if (!this.matchers[2].HasValue && week != weekToSet)
+            {
+                date = date.AddDays(1 - WEEKDAYS[(int)date.DayOfWeek]);
+            }
+
+            return date;
+        }
+
+        /// <summary>
+        /// Calculates the week of month for the given date.
+        /// </summary>
+        /// <param name="date">The date to calculate the week number</param>
+        /// <returns>1..5</returns>
+        private int GetWeekOFMonth(DateTime date)
+        {
+            var cal = CultureInfo.CurrentCulture.Calendar;
+            var firstDay = new DateTime(date.Year, date.Month, 1);
+            var weekOfDate = cal.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
+            var weekOfFirstDay = cal.GetWeekOfYear(firstDay, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
+
+            return weekOfDate - weekOfFirstDay + 1;
+        }
+    }
+}

+ 12 - 7
src/windows/LocalNotificationProxy/LocalNotificationProxy/LocalNotificationProxy.csproj

@@ -12,7 +12,7 @@
     <DefaultLanguage>de-DE</DefaultLanguage>
     <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
     <TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.16299.0</TargetPlatformVersion>
-    <TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
+    <TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>
     <MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
     <FileAlignment>512</FileAlignment>
     <ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
@@ -112,15 +112,19 @@
   <ItemGroup>
     <Compile Include="LocalNotificationProxy.cs" />
     <Compile Include="LocalNotification\Builder.cs" />
-    <Compile Include="LocalNotification\Button.cs" />
-    <Compile Include="LocalNotification\Every.cs" />
+    <Compile Include="LocalNotification\Request.cs" />
+    <Compile Include="LocalNotification\Toast\Button.cs" />
+    <Compile Include="LocalNotification\Toast\Every.cs" />
     <Compile Include="LocalNotification\Notification.cs" />
-    <Compile Include="LocalNotification\IAction.cs" />
-    <Compile Include="LocalNotification\Input.cs" />
+    <Compile Include="LocalNotification\Toast\IAction.cs" />
+    <Compile Include="LocalNotification\Toast\Input.cs" />
     <Compile Include="LocalNotification\Manager.cs" />
     <Compile Include="LocalNotification\Options.cs" />
-    <Compile Include="LocalNotification\ProgressBar.cs" />
-    <Compile Include="LocalNotification\Trigger.cs" />
+    <Compile Include="LocalNotification\Toast\ProgressBar.cs" />
+    <Compile Include="LocalNotification\Toast\Trigger.cs" />
+    <Compile Include="LocalNotification\Trigger\DateTrigger.cs" />
+    <Compile Include="LocalNotification\Trigger\IntervalTrigger.cs" />
+    <Compile Include="LocalNotification\Trigger\MatchTrigger.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -137,6 +141,7 @@
       <Name>Microsoft.Toolkit.Uwp.Notifications.UWP</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
     <VisualStudioVersion>14.0</VisualStudioVersion>
   </PropertyGroup>

+ 4 - 4
src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/Microsoft.Toolkit.Uwp.Notifications.UWP.nuget.props

@@ -3,11 +3,11 @@
   <PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
     <RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
     <RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
-    <ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">Z:\Documents\github\cordova-plugin-local-notifications\src\windows\Microsoft.Toolkit.Uwp.Notifications.UWP\project.lock.json</ProjectAssetsFile>
+    <ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">Z:\Documents\github\cordova-plugin-local-notification\src\windows\Microsoft.Toolkit.Uwp.Notifications.UWP\project.lock.json</ProjectAssetsFile>
     <NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
-    <NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\katze\.nuget\packages\</NuGetPackageFolders>
+    <NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\katze\.nuget\packages\;C:\Program Files (x86)\Microsoft SDKs\NuGetPackagesFallback\</NuGetPackageFolders>
     <NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">ProjectJson</NuGetProjectStyle>
-    <NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">4.4.1</NuGetToolVersion>
+    <NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">4.5.0</NuGetToolVersion>
   </PropertyGroup>
   <PropertyGroup>
     <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
@@ -16,6 +16,6 @@
     <Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.props')" />
     <Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.props')" />
     <Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.props')" />
-    <Import Project="$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.1\build\Microsoft.Net.Native.Compiler.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.1\build\Microsoft.Net.Native.Compiler.props')" />
+    <Import Project="$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.3\build\Microsoft.Net.Native.Compiler.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.3\build\Microsoft.Net.Native.Compiler.props')" />
   </ImportGroup>
 </Project>

+ 1 - 1
src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/Microsoft.Toolkit.Uwp.Notifications.UWP.nuget.targets

@@ -7,6 +7,6 @@
     <Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.targets')" />
     <Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.targets')" />
     <Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.targets')" />
-    <Import Project="$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.1\build\Microsoft.Net.Native.Compiler.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.1\build\Microsoft.Net.Native.Compiler.targets')" />
+    <Import Project="$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.3\build\Microsoft.Net.Native.Compiler.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.3\build\Microsoft.Net.Native.Compiler.targets')" />
   </ImportGroup>
 </Project>

+ 1 - 1
src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/project.json

@@ -1,6 +1,6 @@
 {
   "dependencies": {
-    "Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2",
+    "Microsoft.NETCore.UniversalWindowsPlatform": "6.0.5",
     "StyleCop.Analyzers": "1.0.2"
   },
   "frameworks": {

+ 104 - 99
src/windows/Microsoft.Toolkit.Uwp.Notifications.UWP/project.lock.json

@@ -29,7 +29,7 @@
           "lib/netcore50/Microsoft.CSharp.dll": {}
         }
       },
-      "Microsoft.Net.Native.Compiler/1.7.1": {
+      "Microsoft.Net.Native.Compiler/1.7.3": {
         "type": "package",
         "dependencies": {
           "Microsoft.Net.Native.SharedLibrary-arm": "1.7.0",
@@ -239,14 +239,14 @@
           "lib/netstandard1.0/_._": {}
         }
       },
-      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "dependencies": {
           "Microsoft.NETCore": "5.0.2",
           "Microsoft.NETCore.Portable.Compatibility": "1.0.2",
           "Microsoft.NETCore.Runtime.CoreCLR": "1.0.3",
           "Microsoft.NETCore.Targets": "1.0.2",
-          "Microsoft.Net.Native.Compiler": "1.7.1",
+          "Microsoft.Net.Native.Compiler": "1.7.3",
           "Microsoft.Win32.Primitives": "4.0.1",
           "System.Collections.NonGeneric": "4.0.1",
           "System.Collections.Specialized": "4.0.1",
@@ -261,7 +261,7 @@
           "System.Net.Sockets": "4.1.0",
           "System.Net.WebHeaderCollection": "4.0.1",
           "System.Net.WebSockets": "4.0.0",
-          "System.Net.WebSockets.Client": "4.0.0",
+          "System.Net.WebSockets.Client": "4.0.2",
           "System.Numerics.Vectors.WindowsRuntime": "4.0.1",
           "System.Reflection.Context": "4.0.1",
           "System.Runtime.InteropServices.WindowsRuntime": "4.0.1",
@@ -1117,10 +1117,10 @@
           "lib/netstandard1.3/System.Net.WebSockets.dll": {}
         }
       },
-      "System.Net.WebSockets.Client/4.0.0": {
+      "System.Net.WebSockets.Client/4.0.2": {
         "type": "package",
         "dependencies": {
-          "Microsoft.NETCore.Platforms": "1.0.1",
+          "Microsoft.NETCore.Platforms": "1.0.2",
           "System.Collections": "4.0.11",
           "System.Diagnostics.Debug": "4.0.11",
           "System.Diagnostics.Tracing": "4.1.0",
@@ -2238,7 +2238,7 @@
           "lib/netcore50/Microsoft.CSharp.dll": {}
         }
       },
-      "Microsoft.Net.Native.Compiler/1.7.1": {
+      "Microsoft.Net.Native.Compiler/1.7.3": {
         "type": "package",
         "dependencies": {
           "Microsoft.Net.Native.SharedLibrary-arm": "1.7.0",
@@ -2395,14 +2395,14 @@
           "lib/netstandard1.0/_._": {}
         }
       },
-      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "dependencies": {
           "Microsoft.NETCore": "5.0.2",
           "Microsoft.NETCore.Portable.Compatibility": "1.0.2",
           "Microsoft.NETCore.Runtime.CoreCLR": "1.0.3",
           "Microsoft.NETCore.Targets": "1.0.2",
-          "Microsoft.Net.Native.Compiler": "1.7.1",
+          "Microsoft.Net.Native.Compiler": "1.7.3",
           "Microsoft.Win32.Primitives": "4.0.1",
           "System.Collections.NonGeneric": "4.0.1",
           "System.Collections.Specialized": "4.0.1",
@@ -2417,7 +2417,7 @@
           "System.Net.Sockets": "4.1.0",
           "System.Net.WebHeaderCollection": "4.0.1",
           "System.Net.WebSockets": "4.0.0",
-          "System.Net.WebSockets.Client": "4.0.0",
+          "System.Net.WebSockets.Client": "4.0.2",
           "System.Numerics.Vectors.WindowsRuntime": "4.0.1",
           "System.Reflection.Context": "4.0.1",
           "System.Runtime.InteropServices.WindowsRuntime": "4.0.1",
@@ -2435,7 +2435,7 @@
           "System.Threading.Overlapped": "4.0.1",
           "System.Xml.XmlDocument": "4.0.1",
           "System.Xml.XmlSerializer": "4.0.11",
-          "runtime.win10-arm.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2"
+          "runtime.win10-arm.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.5"
         },
         "compile": {
           "ref/netcore50/_._": {}
@@ -2778,7 +2778,7 @@
           "runtimes/win/lib/netcore50/System.Runtime.Extensions.dll": {}
         }
       },
-      "runtime.win10-arm.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "runtime.win10-arm.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "compile": {
           "ref/netstandard/_._": {}
@@ -3507,10 +3507,10 @@
           "lib/netstandard1.3/System.Net.WebSockets.dll": {}
         }
       },
-      "System.Net.WebSockets.Client/4.0.0": {
+      "System.Net.WebSockets.Client/4.0.2": {
         "type": "package",
         "dependencies": {
-          "Microsoft.NETCore.Platforms": "1.0.1",
+          "Microsoft.NETCore.Platforms": "1.0.2",
           "System.Collections": "4.0.11",
           "System.Diagnostics.Debug": "4.0.11",
           "System.Diagnostics.Tracing": "4.1.0",
@@ -4537,7 +4537,7 @@
           "lib/netcore50/Microsoft.CSharp.dll": {}
         }
       },
-      "Microsoft.Net.Native.Compiler/1.7.1": {
+      "Microsoft.Net.Native.Compiler/1.7.3": {
         "type": "package",
         "dependencies": {
           "Microsoft.Net.Native.SharedLibrary-arm": "1.7.0",
@@ -4695,14 +4695,14 @@
           "lib/netstandard1.0/_._": {}
         }
       },
-      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "dependencies": {
           "Microsoft.NETCore": "5.0.2",
           "Microsoft.NETCore.Portable.Compatibility": "1.0.2",
           "Microsoft.NETCore.Runtime.CoreCLR": "1.0.3",
           "Microsoft.NETCore.Targets": "1.0.2",
-          "Microsoft.Net.Native.Compiler": "1.7.1",
+          "Microsoft.Net.Native.Compiler": "1.7.3",
           "Microsoft.Win32.Primitives": "4.0.1",
           "System.Collections.NonGeneric": "4.0.1",
           "System.Collections.Specialized": "4.0.1",
@@ -4717,7 +4717,7 @@
           "System.Net.Sockets": "4.1.0",
           "System.Net.WebHeaderCollection": "4.0.1",
           "System.Net.WebSockets": "4.0.0",
-          "System.Net.WebSockets.Client": "4.0.0",
+          "System.Net.WebSockets.Client": "4.0.2",
           "System.Numerics.Vectors.WindowsRuntime": "4.0.1",
           "System.Reflection.Context": "4.0.1",
           "System.Runtime.InteropServices.WindowsRuntime": "4.0.1",
@@ -4735,7 +4735,7 @@
           "System.Threading.Overlapped": "4.0.1",
           "System.Xml.XmlDocument": "4.0.1",
           "System.Xml.XmlSerializer": "4.0.11",
-          "runtime.win10-arm-aot.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2"
+          "runtime.win10-arm-aot.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.5"
         },
         "compile": {
           "ref/netcore50/_._": {}
@@ -5123,7 +5123,7 @@
           "runtimes/aot/lib/netcore50/System.Runtime.Extensions.dll": {}
         }
       },
-      "runtime.win10-arm-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "runtime.win10-arm-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "compile": {
           "ref/netstandard/_._": {}
@@ -5842,10 +5842,10 @@
           "lib/netstandard1.3/System.Net.WebSockets.dll": {}
         }
       },
-      "System.Net.WebSockets.Client/4.0.0": {
+      "System.Net.WebSockets.Client/4.0.2": {
         "type": "package",
         "dependencies": {
-          "Microsoft.NETCore.Platforms": "1.0.1",
+          "Microsoft.NETCore.Platforms": "1.0.2",
           "System.Collections": "4.0.11",
           "System.Diagnostics.Debug": "4.0.11",
           "System.Diagnostics.Tracing": "4.1.0",
@@ -6872,7 +6872,7 @@
           "lib/netcore50/Microsoft.CSharp.dll": {}
         }
       },
-      "Microsoft.Net.Native.Compiler/1.7.1": {
+      "Microsoft.Net.Native.Compiler/1.7.3": {
         "type": "package",
         "dependencies": {
           "Microsoft.Net.Native.SharedLibrary-arm": "1.7.0",
@@ -7032,14 +7032,14 @@
           "lib/netstandard1.0/_._": {}
         }
       },
-      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "dependencies": {
           "Microsoft.NETCore": "5.0.2",
           "Microsoft.NETCore.Portable.Compatibility": "1.0.2",
           "Microsoft.NETCore.Runtime.CoreCLR": "1.0.3",
           "Microsoft.NETCore.Targets": "1.0.2",
-          "Microsoft.Net.Native.Compiler": "1.7.1",
+          "Microsoft.Net.Native.Compiler": "1.7.3",
           "Microsoft.Win32.Primitives": "4.0.1",
           "System.Collections.NonGeneric": "4.0.1",
           "System.Collections.Specialized": "4.0.1",
@@ -7054,7 +7054,7 @@
           "System.Net.Sockets": "4.1.0",
           "System.Net.WebHeaderCollection": "4.0.1",
           "System.Net.WebSockets": "4.0.0",
-          "System.Net.WebSockets.Client": "4.0.0",
+          "System.Net.WebSockets.Client": "4.0.2",
           "System.Numerics.Vectors.WindowsRuntime": "4.0.1",
           "System.Reflection.Context": "4.0.1",
           "System.Runtime.InteropServices.WindowsRuntime": "4.0.1",
@@ -7072,7 +7072,7 @@
           "System.Threading.Overlapped": "4.0.1",
           "System.Xml.XmlDocument": "4.0.1",
           "System.Xml.XmlSerializer": "4.0.11",
-          "runtime.win10-x64.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2"
+          "runtime.win10-x64.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.5"
         },
         "compile": {
           "ref/netcore50/_._": {}
@@ -7415,7 +7415,7 @@
           "runtimes/win/lib/netcore50/System.Runtime.Extensions.dll": {}
         }
       },
-      "runtime.win10-x64.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "runtime.win10-x64.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "compile": {
           "ref/netstandard/_._": {}
@@ -8150,10 +8150,10 @@
           "lib/netstandard1.3/System.Net.WebSockets.dll": {}
         }
       },
-      "System.Net.WebSockets.Client/4.0.0": {
+      "System.Net.WebSockets.Client/4.0.2": {
         "type": "package",
         "dependencies": {
-          "Microsoft.NETCore.Platforms": "1.0.1",
+          "Microsoft.NETCore.Platforms": "1.0.2",
           "System.Collections": "4.0.11",
           "System.Diagnostics.Debug": "4.0.11",
           "System.Diagnostics.Tracing": "4.1.0",
@@ -9180,7 +9180,7 @@
           "lib/netcore50/Microsoft.CSharp.dll": {}
         }
       },
-      "Microsoft.Net.Native.Compiler/1.7.1": {
+      "Microsoft.Net.Native.Compiler/1.7.3": {
         "type": "package",
         "dependencies": {
           "Microsoft.Net.Native.SharedLibrary-arm": "1.7.0",
@@ -9341,14 +9341,14 @@
           "lib/netstandard1.0/_._": {}
         }
       },
-      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "dependencies": {
           "Microsoft.NETCore": "5.0.2",
           "Microsoft.NETCore.Portable.Compatibility": "1.0.2",
           "Microsoft.NETCore.Runtime.CoreCLR": "1.0.3",
           "Microsoft.NETCore.Targets": "1.0.2",
-          "Microsoft.Net.Native.Compiler": "1.7.1",
+          "Microsoft.Net.Native.Compiler": "1.7.3",
           "Microsoft.Win32.Primitives": "4.0.1",
           "System.Collections.NonGeneric": "4.0.1",
           "System.Collections.Specialized": "4.0.1",
@@ -9363,7 +9363,7 @@
           "System.Net.Sockets": "4.1.0",
           "System.Net.WebHeaderCollection": "4.0.1",
           "System.Net.WebSockets": "4.0.0",
-          "System.Net.WebSockets.Client": "4.0.0",
+          "System.Net.WebSockets.Client": "4.0.2",
           "System.Numerics.Vectors.WindowsRuntime": "4.0.1",
           "System.Reflection.Context": "4.0.1",
           "System.Runtime.InteropServices.WindowsRuntime": "4.0.1",
@@ -9381,7 +9381,7 @@
           "System.Threading.Overlapped": "4.0.1",
           "System.Xml.XmlDocument": "4.0.1",
           "System.Xml.XmlSerializer": "4.0.11",
-          "runtime.win10-x64-aot.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2"
+          "runtime.win10-x64-aot.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.5"
         },
         "compile": {
           "ref/netcore50/_._": {}
@@ -9769,7 +9769,7 @@
           "runtimes/aot/lib/netcore50/System.Runtime.Extensions.dll": {}
         }
       },
-      "runtime.win10-x64-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "runtime.win10-x64-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "compile": {
           "ref/netstandard/_._": {}
@@ -10494,10 +10494,10 @@
           "lib/netstandard1.3/System.Net.WebSockets.dll": {}
         }
       },
-      "System.Net.WebSockets.Client/4.0.0": {
+      "System.Net.WebSockets.Client/4.0.2": {
         "type": "package",
         "dependencies": {
-          "Microsoft.NETCore.Platforms": "1.0.1",
+          "Microsoft.NETCore.Platforms": "1.0.2",
           "System.Collections": "4.0.11",
           "System.Diagnostics.Debug": "4.0.11",
           "System.Diagnostics.Tracing": "4.1.0",
@@ -11524,7 +11524,7 @@
           "lib/netcore50/Microsoft.CSharp.dll": {}
         }
       },
-      "Microsoft.Net.Native.Compiler/1.7.1": {
+      "Microsoft.Net.Native.Compiler/1.7.3": {
         "type": "package",
         "dependencies": {
           "Microsoft.Net.Native.SharedLibrary-arm": "1.7.0",
@@ -11684,14 +11684,14 @@
           "lib/netstandard1.0/_._": {}
         }
       },
-      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "dependencies": {
           "Microsoft.NETCore": "5.0.2",
           "Microsoft.NETCore.Portable.Compatibility": "1.0.2",
           "Microsoft.NETCore.Runtime.CoreCLR": "1.0.3",
           "Microsoft.NETCore.Targets": "1.0.2",
-          "Microsoft.Net.Native.Compiler": "1.7.1",
+          "Microsoft.Net.Native.Compiler": "1.7.3",
           "Microsoft.Win32.Primitives": "4.0.1",
           "System.Collections.NonGeneric": "4.0.1",
           "System.Collections.Specialized": "4.0.1",
@@ -11706,7 +11706,7 @@
           "System.Net.Sockets": "4.1.0",
           "System.Net.WebHeaderCollection": "4.0.1",
           "System.Net.WebSockets": "4.0.0",
-          "System.Net.WebSockets.Client": "4.0.0",
+          "System.Net.WebSockets.Client": "4.0.2",
           "System.Numerics.Vectors.WindowsRuntime": "4.0.1",
           "System.Reflection.Context": "4.0.1",
           "System.Runtime.InteropServices.WindowsRuntime": "4.0.1",
@@ -11724,7 +11724,7 @@
           "System.Threading.Overlapped": "4.0.1",
           "System.Xml.XmlDocument": "4.0.1",
           "System.Xml.XmlSerializer": "4.0.11",
-          "runtime.win10-x86.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2"
+          "runtime.win10-x86.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.5"
         },
         "compile": {
           "ref/netcore50/_._": {}
@@ -12067,7 +12067,7 @@
           "runtimes/win/lib/netcore50/System.Runtime.Extensions.dll": {}
         }
       },
-      "runtime.win10-x86.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "runtime.win10-x86.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "compile": {
           "ref/netstandard/_._": {}
@@ -12802,10 +12802,10 @@
           "lib/netstandard1.3/System.Net.WebSockets.dll": {}
         }
       },
-      "System.Net.WebSockets.Client/4.0.0": {
+      "System.Net.WebSockets.Client/4.0.2": {
         "type": "package",
         "dependencies": {
-          "Microsoft.NETCore.Platforms": "1.0.1",
+          "Microsoft.NETCore.Platforms": "1.0.2",
           "System.Collections": "4.0.11",
           "System.Diagnostics.Debug": "4.0.11",
           "System.Diagnostics.Tracing": "4.1.0",
@@ -13832,7 +13832,7 @@
           "lib/netcore50/Microsoft.CSharp.dll": {}
         }
       },
-      "Microsoft.Net.Native.Compiler/1.7.1": {
+      "Microsoft.Net.Native.Compiler/1.7.3": {
         "type": "package",
         "dependencies": {
           "Microsoft.Net.Native.SharedLibrary-arm": "1.7.0",
@@ -13993,14 +13993,14 @@
           "lib/netstandard1.0/_._": {}
         }
       },
-      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "dependencies": {
           "Microsoft.NETCore": "5.0.2",
           "Microsoft.NETCore.Portable.Compatibility": "1.0.2",
           "Microsoft.NETCore.Runtime.CoreCLR": "1.0.3",
           "Microsoft.NETCore.Targets": "1.0.2",
-          "Microsoft.Net.Native.Compiler": "1.7.1",
+          "Microsoft.Net.Native.Compiler": "1.7.3",
           "Microsoft.Win32.Primitives": "4.0.1",
           "System.Collections.NonGeneric": "4.0.1",
           "System.Collections.Specialized": "4.0.1",
@@ -14015,7 +14015,7 @@
           "System.Net.Sockets": "4.1.0",
           "System.Net.WebHeaderCollection": "4.0.1",
           "System.Net.WebSockets": "4.0.0",
-          "System.Net.WebSockets.Client": "4.0.0",
+          "System.Net.WebSockets.Client": "4.0.2",
           "System.Numerics.Vectors.WindowsRuntime": "4.0.1",
           "System.Reflection.Context": "4.0.1",
           "System.Runtime.InteropServices.WindowsRuntime": "4.0.1",
@@ -14033,7 +14033,7 @@
           "System.Threading.Overlapped": "4.0.1",
           "System.Xml.XmlDocument": "4.0.1",
           "System.Xml.XmlSerializer": "4.0.11",
-          "runtime.win10-x86-aot.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2"
+          "runtime.win10-x86-aot.Microsoft.NETCore.UniversalWindowsPlatform": "6.0.5"
         },
         "compile": {
           "ref/netcore50/_._": {}
@@ -14421,7 +14421,7 @@
           "runtimes/aot/lib/netcore50/System.Runtime.Extensions.dll": {}
         }
       },
-      "runtime.win10-x86-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
+      "runtime.win10-x86-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
         "type": "package",
         "compile": {
           "ref/netstandard/_._": {}
@@ -15146,10 +15146,10 @@
           "lib/netstandard1.3/System.Net.WebSockets.dll": {}
         }
       },
-      "System.Net.WebSockets.Client/4.0.0": {
+      "System.Net.WebSockets.Client/4.0.2": {
         "type": "package",
         "dependencies": {
-          "Microsoft.NETCore.Platforms": "1.0.1",
+          "Microsoft.NETCore.Platforms": "1.0.2",
           "System.Collections": "4.0.11",
           "System.Diagnostics.Debug": "4.0.11",
           "System.Diagnostics.Tracing": "4.1.0",
@@ -16207,14 +16207,14 @@
         "ref/xamarinwatchos10/_._"
       ]
     },
-    "Microsoft.Net.Native.Compiler/1.7.1": {
-      "sha512": "P55mWSgc8zLrk2eoRxd3T3QPVXXKrqD/DypC+It8wSgZfaUl2/o31bCOR+aWq1NtxDwDnCPGNVsmo/bmgIeJtA==",
+    "Microsoft.Net.Native.Compiler/1.7.3": {
+      "sha512": "ed0kCs6Gxfw2ZGf34eqO8cwaD16Ll1FKw+jBfGevdiHqc2kTwux9yqkHwhe9WP8jzSbuZX3o4y3wMUUkz5gSeg==",
       "type": "package",
-      "path": "microsoft.net.native.compiler/1.7.1",
+      "path": "microsoft.net.native.compiler/1.7.3",
       "files": [
         "build/Microsoft.Net.Native.Compiler.props",
         "build/Microsoft.Net.Native.Compiler.targets",
-        "microsoft.net.native.compiler.1.7.1.nupkg.sha512",
+        "microsoft.net.native.compiler.1.7.3.nupkg.sha512",
         "microsoft.net.native.compiler.nuspec",
         "tools/LibraryXML/Callisto.rd.xml",
         "tools/LibraryXML/GalaSoft.MvvmLight.Extras.Win8.rd.xml",
@@ -18442,14 +18442,14 @@
         "runtime.json"
       ]
     },
-    "Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
-      "sha512": "1x37WPEc/7G4BedFtmSKCK9E1wVWm0BTgTBe7lv/LuN/5a48H8KpGLO5I0fmX51y5r/BXJNaLjpfDkH1i1j0rQ==",
+    "Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
+      "sha512": "suR2zL+dQAcOxs2rokFV8KGbECXLDhB8U333NMYNtftqLFnfTMVX0qFVG8f34q3dALEuq/vlrZ/RCCL3NOEApg==",
       "type": "package",
-      "path": "microsoft.netcore.universalwindowsplatform/6.0.2",
+      "path": "microsoft.netcore.universalwindowsplatform/6.0.5",
       "files": [
         "LICENSE.TXT",
         "THIRD-PARTY-NOTICES.TXT",
-        "microsoft.netcore.universalwindowsplatform.6.0.2.nupkg.sha512",
+        "microsoft.netcore.universalwindowsplatform.6.0.5.nupkg.sha512",
         "microsoft.netcore.universalwindowsplatform.nuspec",
         "ref/netcore50/_._",
         "ref/uap10.0.15138/Microsoft.CSharp.dll",
@@ -19587,15 +19587,15 @@
         "runtimes/win/lib/netstandard1.5/System.Runtime.Extensions.dll"
       ]
     },
-    "runtime.win10-arm-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
-      "sha512": "zz8GaaUGJIFUsJPY0g0ToBrCv3kXbdwDXbd2Tr+HXvJXFD9HrHQHEue4ZVcZpc82mUfdXyRzO4+t6hY64Q4dTQ==",
+    "runtime.win10-arm-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
+      "sha512": "QM1Mq6C4V3ycqf0/8NLXJ9CjUu3jRGtf76tPOcdEjARDW8zDVyynOYiV5x5deuZS/nHaKHe51lsZGuqdqMohBQ==",
       "type": "package",
-      "path": "runtime.win10-arm-aot.microsoft.netcore.universalwindowsplatform/6.0.2",
+      "path": "runtime.win10-arm-aot.microsoft.netcore.universalwindowsplatform/6.0.5",
       "files": [
         "LICENSE.TXT",
         "THIRD-PARTY-NOTICES.TXT",
         "ref/netstandard/_._",
-        "runtime.win10-arm-aot.microsoft.netcore.universalwindowsplatform.6.0.2.nupkg.sha512",
+        "runtime.win10-arm-aot.microsoft.netcore.universalwindowsplatform.6.0.5.nupkg.sha512",
         "runtime.win10-arm-aot.microsoft.netcore.universalwindowsplatform.nuspec",
         "runtimes/win10-arm-aot/lib/uap10.0.15138/Microsoft.CSharp.dll",
         "runtimes/win10-arm-aot/lib/uap10.0.15138/Microsoft.VisualBasic.dll",
@@ -19776,15 +19776,15 @@
         "runtimes/win10-arm-aot/lib/netcore50/clrcompression.dll"
       ]
     },
-    "runtime.win10-arm.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
-      "sha512": "TDXnAPztcmMBpQomeGbo0gk/6WCrQUc5DL1HJcxcefNCRUlqAbUdsUz8sEGaJQ9NUbSshnEeY4wrVgyOonAf+Q==",
+    "runtime.win10-arm.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
+      "sha512": "dTPIIlo1DK2iJ5dDUO3m/xHa4FhDD0zFyVvj2IaDEUa33QwNN59Bavg2snmIlLZZaFxTP7tl284bgJ5cGSLt9A==",
       "type": "package",
-      "path": "runtime.win10-arm.microsoft.netcore.universalwindowsplatform/6.0.2",
+      "path": "runtime.win10-arm.microsoft.netcore.universalwindowsplatform/6.0.5",
       "files": [
         "LICENSE.TXT",
         "THIRD-PARTY-NOTICES.TXT",
         "ref/netstandard/_._",
-        "runtime.win10-arm.microsoft.netcore.universalwindowsplatform.6.0.2.nupkg.sha512",
+        "runtime.win10-arm.microsoft.netcore.universalwindowsplatform.6.0.5.nupkg.sha512",
         "runtime.win10-arm.microsoft.netcore.universalwindowsplatform.nuspec",
         "runtimes/win10-arm/lib/uap10.0.15138/Microsoft.CSharp.dll",
         "runtimes/win10-arm/lib/uap10.0.15138/Microsoft.VisualBasic.dll",
@@ -19952,15 +19952,15 @@
         "runtimes/win10-arm/nativeassets/uap10.0.15138/clrcompression.dll"
       ]
     },
-    "runtime.win10-x64-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
-      "sha512": "zRfgkMb/yA8Ldgql4gzY5SRcXoj6KgCoKrfPVdOC7iv5PzxGNfQnHdS0WQ5sDaLB+O8BVYpyMYQ4eQ1gbRq+GA==",
+    "runtime.win10-x64-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
+      "sha512": "AWZIFcu8xoZitu3ZdEgbis5NTnXUZ0DrGlekieo9+qwjgnC1aOju6PJYPNQzaH11x6jFGCyU9DKrazu6olRu/Q==",
       "type": "package",
-      "path": "runtime.win10-x64-aot.microsoft.netcore.universalwindowsplatform/6.0.2",
+      "path": "runtime.win10-x64-aot.microsoft.netcore.universalwindowsplatform/6.0.5",
       "files": [
         "LICENSE.TXT",
         "THIRD-PARTY-NOTICES.TXT",
         "ref/netstandard/_._",
-        "runtime.win10-x64-aot.microsoft.netcore.universalwindowsplatform.6.0.2.nupkg.sha512",
+        "runtime.win10-x64-aot.microsoft.netcore.universalwindowsplatform.6.0.5.nupkg.sha512",
         "runtime.win10-x64-aot.microsoft.netcore.universalwindowsplatform.nuspec",
         "runtimes/win10-x64-aot/lib/uap10.0.15138/Microsoft.CSharp.dll",
         "runtimes/win10-x64-aot/lib/uap10.0.15138/Microsoft.VisualBasic.dll",
@@ -20141,15 +20141,15 @@
         "runtimes/win10-x64-aot/lib/netcore50/clrcompression.dll"
       ]
     },
-    "runtime.win10-x64.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
-      "sha512": "sNKsP3Fo/XKs4lzEfXzQ6p5+H+gsMVKDtLfNApeCtpsimTt+Nn9lzYggaqvv+gMRJ90j5MnnMZaUf6RwV56nfQ==",
+    "runtime.win10-x64.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
+      "sha512": "I774FxmdywBPYipSE0Og5HajYt0eBto8tw9QNlsZt0jVNShltEqBq7LC2MkRkWkf2VDrJEY0jU6I320jLTfwZA==",
       "type": "package",
-      "path": "runtime.win10-x64.microsoft.netcore.universalwindowsplatform/6.0.2",
+      "path": "runtime.win10-x64.microsoft.netcore.universalwindowsplatform/6.0.5",
       "files": [
         "LICENSE.TXT",
         "THIRD-PARTY-NOTICES.TXT",
         "ref/netstandard/_._",
-        "runtime.win10-x64.microsoft.netcore.universalwindowsplatform.6.0.2.nupkg.sha512",
+        "runtime.win10-x64.microsoft.netcore.universalwindowsplatform.6.0.5.nupkg.sha512",
         "runtime.win10-x64.microsoft.netcore.universalwindowsplatform.nuspec",
         "runtimes/win10-x64/lib/uap10.0.15138/Microsoft.CSharp.dll",
         "runtimes/win10-x64/lib/uap10.0.15138/Microsoft.VisualBasic.dll",
@@ -20317,15 +20317,15 @@
         "runtimes/win10-x64/nativeassets/uap10.0.15138/clrcompression.dll"
       ]
     },
-    "runtime.win10-x86-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
-      "sha512": "y+OndyqwIIT0EN5x5oyGaW1hRAiej6n2SCk+JZGtMSgjF9i3QQn9dmxYtxazuk+O5MtQdApHYtgK7uKW3yL2ag==",
+    "runtime.win10-x86-aot.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
+      "sha512": "TRA8QnE7CN7oVXPMybL/ZojpOzkond2euO19YYzicwZjrvRrudy3OXTAQlPbtE2xFQ0Va2U4A9gcrsiCyxXEJA==",
       "type": "package",
-      "path": "runtime.win10-x86-aot.microsoft.netcore.universalwindowsplatform/6.0.2",
+      "path": "runtime.win10-x86-aot.microsoft.netcore.universalwindowsplatform/6.0.5",
       "files": [
         "LICENSE.TXT",
         "THIRD-PARTY-NOTICES.TXT",
         "ref/netstandard/_._",
-        "runtime.win10-x86-aot.microsoft.netcore.universalwindowsplatform.6.0.2.nupkg.sha512",
+        "runtime.win10-x86-aot.microsoft.netcore.universalwindowsplatform.6.0.5.nupkg.sha512",
         "runtime.win10-x86-aot.microsoft.netcore.universalwindowsplatform.nuspec",
         "runtimes/win10-x86-aot/lib/uap10.0.15138/Microsoft.CSharp.dll",
         "runtimes/win10-x86-aot/lib/uap10.0.15138/Microsoft.VisualBasic.dll",
@@ -20506,15 +20506,15 @@
         "runtimes/win10-x86-aot/lib/netcore50/clrcompression.dll"
       ]
     },
-    "runtime.win10-x86.Microsoft.NETCore.UniversalWindowsPlatform/6.0.2": {
-      "sha512": "0cl6qKSo+w3v5Y6KrlzDm9GcsoS07OIZO/fEwDykvaJjhzsDeY8UFvLN7s3YiB7bUSAt0uWJcJi3eRBdUsiSBA==",
+    "runtime.win10-x86.Microsoft.NETCore.UniversalWindowsPlatform/6.0.5": {
+      "sha512": "wc1xGboXkp6PQpxnEtXVZEYATCU2n2Z3YoCq4Zq9QtreDF+RfO4ubFEAj/9K9agnW5CdtWr7J2nsFLk0veafgg==",
       "type": "package",
-      "path": "runtime.win10-x86.microsoft.netcore.universalwindowsplatform/6.0.2",
+      "path": "runtime.win10-x86.microsoft.netcore.universalwindowsplatform/6.0.5",
       "files": [
         "LICENSE.TXT",
         "THIRD-PARTY-NOTICES.TXT",
         "ref/netstandard/_._",
-        "runtime.win10-x86.microsoft.netcore.universalwindowsplatform.6.0.2.nupkg.sha512",
+        "runtime.win10-x86.microsoft.netcore.universalwindowsplatform.6.0.5.nupkg.sha512",
         "runtime.win10-x86.microsoft.netcore.universalwindowsplatform.nuspec",
         "runtimes/win10-x86/lib/uap10.0.15138/Microsoft.CSharp.dll",
         "runtimes/win10-x86/lib/uap10.0.15138/Microsoft.VisualBasic.dll",
@@ -23017,10 +23017,10 @@
         "system.net.websockets.nuspec"
       ]
     },
-    "System.Net.WebSockets.Client/4.0.0": {
-      "sha512": "GY5h9cn0ZVsG4ORQqMytTldrqxet2RC2CSEsgWGf4XNW5jhL5SxzcUZph03xbZsgn7K3qMr+Rq+gkbJNI+FEXg==",
+    "System.Net.WebSockets.Client/4.0.2": {
+      "sha512": "NUCcDroX4lCQXgOrzlwIZ1u9YJ0krfyF0wk0ONnyLUmcQoEiYV2/OfUPRqUwQBbpH1BlGApkLgoQUwMqb5+c1g==",
       "type": "package",
-      "path": "system.net.websockets.client/4.0.0",
+      "path": "system.net.websockets.client/4.0.2",
       "files": [
         "ThirdPartyNotices.txt",
         "dotnet_library_license.txt",
@@ -23053,7 +23053,7 @@
         "runtimes/win/lib/net46/System.Net.WebSockets.Client.dll",
         "runtimes/win/lib/netcore50/System.Net.WebSockets.Client.dll",
         "runtimes/win/lib/netstandard1.3/System.Net.WebSockets.Client.dll",
-        "system.net.websockets.client.4.0.0.nupkg.sha512",
+        "system.net.websockets.client.4.0.2.nupkg.sha512",
         "system.net.websockets.client.nuspec"
       ]
     },
@@ -25759,26 +25759,31 @@
   },
   "projectFileDependencyGroups": {
     "": [
-      "Microsoft.NETCore.UniversalWindowsPlatform >= 6.0.2",
+      "Microsoft.NETCore.UniversalWindowsPlatform >= 6.0.5",
       "StyleCop.Analyzers >= 1.0.2"
     ],
     "UAP,Version=v10.0.10240": []
   },
   "packageFolders": {
-    "C:\\Users\\katze\\.nuget\\packages\\": {}
+    "C:\\Users\\katze\\.nuget\\packages\\": {},
+    "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackagesFallback\\": {}
   },
   "project": {
     "restore": {
-      "projectUniqueName": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\Microsoft.Toolkit.Uwp.Notifications.UWP.csproj",
+      "projectUniqueName": "Z:\\Documents\\github\\cordova-plugin-local-notification\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\Microsoft.Toolkit.Uwp.Notifications.UWP.csproj",
       "projectName": "Microsoft.Toolkit.Uwp.Notifications.UWP",
-      "projectPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\Microsoft.Toolkit.Uwp.Notifications.UWP.csproj",
-      "projectJsonPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\project.json",
+      "projectPath": "Z:\\Documents\\github\\cordova-plugin-local-notification\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\Microsoft.Toolkit.Uwp.Notifications.UWP.csproj",
+      "projectJsonPath": "Z:\\Documents\\github\\cordova-plugin-local-notification\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\project.json",
       "packagesPath": "C:\\Users\\katze\\.nuget\\packages\\",
-      "outputPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\obj\\",
+      "outputPath": "Z:\\Documents\\github\\cordova-plugin-local-notification\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\obj\\",
       "projectStyle": "ProjectJson",
+      "fallbackFolders": [
+        "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackagesFallback\\"
+      ],
       "configFilePaths": [
         "C:\\Users\\katze\\AppData\\Roaming\\NuGet\\NuGet.Config",
-        "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
+        "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config",
+        "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.Fallback.config"
       ],
       "sources": {
         "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
@@ -25786,8 +25791,8 @@
       }
     },
     "dependencies": {
-      "Microsoft.NETCore.UniversalWindowsPlatform": "6.0.2",
-      "StyleCop.Analyzers": "1.0.2"
+      "Microsoft.NETCore.UniversalWindowsPlatform": "[6.0.5, )",
+      "StyleCop.Analyzers": "[1.0.2, )"
     },
     "frameworks": {
       "uap10.0.10240": {}