From b19f08d0b98bece2436d977c36349beb3a8fe905 Mon Sep 17 00:00:00 2001 From: GyGerg Date: Tue, 5 Sep 2023 10:45:01 +0200 Subject: [PATCH] #1 - Update binding to version 11.7 and convert to be npm based (#2) * #1 Initial update to WS7 (beta) - Uses npm package instead of concrete cdn link - Upgrade to SweetAlert2 (https://sweetalert2.github.io/), version 11.7+ * Moved helper pattern into its own sub-module * meta/info changes * typo fix in paket template + removed AssemblyTitle/Desc attributes --- WebSharper.SweetAlert Sample Page/Client.fs | 77 +++-- .../WebSharper.SweetAlert Sample Page.fsproj | 9 +- WebSharper.SweetAlert Sample Page/index.html | 6 +- .../package-lock.json | 25 ++ .../package.json | 14 + WebSharper.SweetAlert/Main.fs | 323 ++++++++++++------ .../WebSharper.SweetAlert.fsproj | 11 +- WebSharper.SweetAlert/wsconfig.json | 4 + nuget/WebSharper.SweetAlert.paket.template | 2 +- paket.dependencies | 3 +- paket.lock | 20 +- 11 files changed, 343 insertions(+), 151 deletions(-) create mode 100644 WebSharper.SweetAlert Sample Page/package-lock.json create mode 100644 WebSharper.SweetAlert Sample Page/package.json create mode 100644 WebSharper.SweetAlert/wsconfig.json diff --git a/WebSharper.SweetAlert Sample Page/Client.fs b/WebSharper.SweetAlert Sample Page/Client.fs index 6154811..bd10e49 100644 --- a/WebSharper.SweetAlert Sample Page/Client.fs +++ b/WebSharper.SweetAlert Sample Page/Client.fs @@ -24,73 +24,82 @@ open WebSharper.JavaScript open WebSharper.UI open WebSharper.UI.Html open WebSharper.UI.Client -open WebSharper.UI.Notation -open WebSharper.UI.Templating open WebSharper.SweetAlert [] module Client = + module Helpers = + let (|IsConfirmed|IsDenied|IsDismissed|) (res: SweetAlertResult<'T>) = + if res.IsConfirmed then IsConfirmed(res.Value) + else if res.IsDismissed then IsDismissed(res.Dismiss) + else if res.IsDenied then IsDenied + else failwith "SweetAlert JS failure: Result not set as confirmed, dimissed or denied" + + open Helpers [] let Main () = - let Alert0= - SweetAlert.Box( + let Alert0 () = + Swal.Fire(SweetAlertOptions( TitleText = "Information", Text = "It works!", - Type = "info", + Icon = SweetAlertIcon.Info, AllowOutsideClick = true, ShowCancelButton = true - ) - let Alert1 = - SweetAlert.Box( + )) + let Alert1 () = + Swal.Fire(SweetAlertOptions( TitleText = "Click", Text = "You have clicked on the button!", - Type = "success", + Icon = SweetAlertIcon.Success, ConfirmButtonText = "Cool", ConfirmButtonColor = "#000000" - ) - - let Alert2 = - SweetAlert.Box( + )) + let InputAlert () = + Swal.Fire(SweetAlertOptions( TitleText = "Input", Text = "Hello! Please say something", - Type = "info", - Input = "text" - ) - SweetAlert.SetDefaults Alert0 - SweetAlert.ShowBox Alert0 |> ignore + Icon = SweetAlertIcon.Info, + Input = SweetAlertInput.Text + )) + + Alert0() |> ignore let btn1 = Doc.Button "Click me!" [] (fun () -> - SweetAlert.ShowBox Alert1 |> ignore + Alert1() |> ignore ) let rResult = Var.Create "" let btn2 = + Doc.Button "Input" [] (fun () -> - // (SweetAlert.ShowBox Alert2).Then(fun r -> - // let Alert = Box(Text = "You have wrote: "+string(r), TitleText = "Result") - // Console.Log r - // SweetAlert.ShowBox(Alert)|>ignore) |> ignore - - SweetAlert.ShowBox(Alert2).Then(fun x -> rResult := x)|> ignore - // SweetAlert.Close() - // SweetAlert.ShowBox(Alert2).State() |> Console.Log - // SweetAlert.ShowBox(Alert2).Then (fun result -> Console.Log result) |> ignore - // SweetAlert.Then(SweetAlert(Alert2)) |> Console.Log - // rValue.Value <- SweetAlert.Then(SweetAlert.ShowBox(Alert2)) - // SweetAlert.GetInput |> Console.Log + promise { + let! result = InputAlert() + Console.Log result + return! + match result with + | IsConfirmed v -> + rResult.Set v + ("Result", $"You have wrote: {v}") + | IsDismissed reason -> + ("Dismissed", $"Dismissed with reason: {reason}") + | IsDenied -> + ("Denied", "Dialog denied.") + |> Swal.Fire + } |> ignore + () ) Doc.Concat[ btn1 - br[][] + br [] [] btn2 - h2[][text "The last input was: "] - p[][textView rResult.View] + h2 [] [text "The last input was: "] + p [] [textView rResult.View] ] |> Doc.RunById "main" diff --git a/WebSharper.SweetAlert Sample Page/WebSharper.SweetAlert Sample Page.fsproj b/WebSharper.SweetAlert Sample Page/WebSharper.SweetAlert Sample Page.fsproj index e013065..a69d7a7 100644 --- a/WebSharper.SweetAlert Sample Page/WebSharper.SweetAlert Sample Page.fsproj +++ b/WebSharper.SweetAlert Sample Page/WebSharper.SweetAlert Sample Page.fsproj @@ -9,9 +9,14 @@ - + + + + ..\WebSharper.SweetAlert\bin\Debug\netstandard2.0\WebSharper.SweetAlert.dll + + \ No newline at end of file diff --git a/WebSharper.SweetAlert Sample Page/index.html b/WebSharper.SweetAlert Sample Page/index.html index dad977a..1090ae6 100644 --- a/WebSharper.SweetAlert Sample Page/index.html +++ b/WebSharper.SweetAlert Sample Page/index.html @@ -4,17 +4,17 @@ WebSharper.SweetAlert_Sample_Page - + - +

WebSharper.SweetAlert sample page

- + diff --git a/WebSharper.SweetAlert Sample Page/package-lock.json b/WebSharper.SweetAlert Sample Page/package-lock.json new file mode 100644 index 0000000..ce2bff7 --- /dev/null +++ b/WebSharper.SweetAlert Sample Page/package-lock.json @@ -0,0 +1,25 @@ +{ + "name": "websharper.sweetalert-sample-page", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "websharper.sweetalert-sample-page", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "sweetalert2": "^11.7.27" + } + }, + "node_modules/sweetalert2": { + "version": "11.7.27", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.7.27.tgz", + "integrity": "sha512-QbRXGQn1sb7HEhzA/K2xtWIwQHh/qkSbb1w6jYcTql2xy17876lTREEt1D4X6Q0x2wHtfUjKJ+Cb8IVkRoq7DQ==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + } + } +} diff --git a/WebSharper.SweetAlert Sample Page/package.json b/WebSharper.SweetAlert Sample Page/package.json new file mode 100644 index 0000000..59b7e4c --- /dev/null +++ b/WebSharper.SweetAlert Sample Page/package.json @@ -0,0 +1,14 @@ +{ + "name": "websharper.sweetalert-sample-page", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "sweetalert2": "^11.7.27" + } +} diff --git a/WebSharper.SweetAlert/Main.fs b/WebSharper.SweetAlert/Main.fs index 84f9d22..1d02ffa 100644 --- a/WebSharper.SweetAlert/Main.fs +++ b/WebSharper.SweetAlert/Main.fs @@ -19,126 +19,257 @@ // $end{copyright} namespace WebSharper.SweetAlert +open System open WebSharper open WebSharper.JavaScript open WebSharper.InterfaceGenerator -open WebSharper.JQuery module Definition = - let SweetAlert = Class "sweetAlert" + + let DismissReason = Pattern.EnumStrings "DismissReason" [ + "cancel" + "backdrop" + "close" + "esc" + "timer" + ] - let SweetAlertProm = - Class "SweetAlertPromise" - |=> Inherits T - |+> Instance [ - "then" => T unit> ^-> T + let SweetAlertResult = Generic - fun t -> + Pattern.Config "SweetAlertResult" { + Required = [ + "isConfirmed", T + "isDenied", T + "isDismissed", T + ] + Optional = [ + "value", t.Type + "dismiss", DismissReason.Type // todo Swal.DismissReason + ] + } + let SweetAlertIcon = Pattern.EnumStrings "SweetAlertIcon" [ + "success" + "error" + "warning" + "info" + ] + + let SweetAlertInput = Pattern.EnumStrings "SweetAlertInput" [ + "text"; "email"; "password"; "number"; "tel"; "range"; + "textarea"; "select"; "radio"; "checkbox"; "file"; "url"; + ] + + let SweetAlertPosition = Pattern.EnumStrings "SweetAlertPosition" [ + "top"; "top-start"; "top-end"; "top-left"; "top-right" + "center"; "center-start"; "center-end"; "center-left"; "center-right" + "bottom"; "bottom-start"; "bottom-end"; "bottom-left"; "bottom-right" + ] + + + let SweetAlertCustomClass = Pattern.Config "SweetAlertCustomClass" { + Required = [] + Optional = [] + } + + + let SweetAlertHideShowClass = Pattern.Config "SweetAlertHideShowClass" { + Required = [] + Optional = [ + "backdrop", T + T + "icon", T + T + "popup", T + T ] + } + let ValueOrThunk (t:Type.Type) = t + (T ^-> t) + let SyncOrAsync (t:Type.Type) = t + T>[t] - let Box = - Pattern.Config "Box"{ + let updatableParameters = [ + "allowEscapeKey", ValueOrThunk T + "allowOutsideClick", ValueOrThunk T + "background", T + "buttonsStyling", T + "cancelButtonAriaLabel", T + "cancelButtonColor", T + "cancelButtonText", T + "closeButtonAriaLabel", T + "closeButtonHtml", T + "confirmButtonAriaLabel", T + "confirmButtonColor", T + "confirmButtonText", T + "currentProgressStep", !? T + "customClass", SweetAlertCustomClass.Type + T + "denyButtonAriaLabel", T + "denyButtonColor", T + "denyButtonText", T + "didClose", T ^-> T + "didDestroy", T ^-> T + "footer", T + T + "hideClass", SweetAlertHideShowClass.Type + "html", T + T + "icon", SweetAlertIcon.Type + "iconColor", T + "imageAlt", T + "imageHeight", T + T + "imageUrl", T + "imageWidth", T + T + "preConfirm", T?inputValue ^-> SyncOrAsync T + "preDeny", T?value ^-> SyncOrAsync (T + T) + "progressSteps", Type.ArrayOf T + "reverseButtons", T + "showCancelButton", T + "showCloseButton", T + "showConfirmButton", T + "showDenyButton", T + "text", T + "title", T + T + "titleText", T + "willClose", T?popup ^-> T + ] + + let SweetAlertUpdatableParameters = Pattern.Config "SweetAlertUpdatableParameters" { + Required = [] + Optional = updatableParameters + } + + + + let SweetAlertGrow = (Pattern.EnumStrings "SweetAlertGrow" [ + "row"; "column"; "fullscreen"; false.ToString() + ]) + + let inputType = T + T + T + T + let SweetAlertOptions = + Pattern.Config "SweetAlertOptions" { Required = [] - Optional = - [ - "title", T - "titleText", T - "text", T - "html", T - "type", T - "target", T - "input", T - "width", T - "padding", T - "background", T - "customClass", T + Optional = [ + "iconHtml", T + "template", T + T // is this good + "backdrop", T + T + "toast", T + "target", T + T + "input", SweetAlertInput.Type + "width", T + T + "padding", T + T + "color", T + "position", SweetAlertPosition.Type + // "grow", SweetAlertGrow.Type + "showClass", SweetAlertHideShowClass.Type "timer", T - "animation", T - "allowOutsideClick", T - "allowEscapeKey", T - "allowEnterKey", T - "showConfirmButton", T - "showCancelButton", T - "confirmButtonText", T - "cancelButtonText", T - "confirmButtonColor", T - "cancleButtonColor", T - "confirmButtonClass", T - "cancelButtonClass", T - "buttonsStyling", T - "reverseButtons", T + "timerProgressBar", T + "heightAuto", T + "allowEnterKey", SyncOrAsync T // TODO generic SyncOrAsync + "stopKeydownPropagation", T + "keydownListenerCapture", T + "focusConfirm", T + "focusDeny", T "focusCancel", T - "showCloseButton", T + "returnFocus", T + "loaderHtml", T "showLoaderOnConfirm", T - "preConfirm", T ^-> SweetAlertProm - "imageUrl", T - "imageWidth", T - "imageHeight", T - "imageClass", T + "showLoaderOnDeny", T + "inputLabel", T "inputPlaceholder", T - "inputValue", T - "inputOptions", T + + "inputValue", SyncOrAsync inputType // TODO: wrap in SyncOrAsync + "inputOptions", T // TODO SyncOrAsync | record> + "inputAutoFocus", T "inputAutoTrim", T - "inputAttributes", T>.[T, T] - "inputValidator", T ^-> SweetAlertProm - "inputClass", T - "progressSteps", T - "currentProgressStep", T ^-> T - "progressStepDistance", T - "onOpen", T ^-> T - "onClose", T ^-> T - "useRejections", T - ] + "inputAttributes", T // Record + "inputValidator", T ^-> (T + T) // TODO string,string -> string | null | void + "returnInputValueOnDeny", T + "validationMessage", T + "progressStepsDistance", (!? T) + T // default undef + "willOpen", T ^-> T + "didOpen", T ^-> T + "didRender", T ^-> T + "scrollbarPadding", T + + yield! updatableParameters + + ] } - SweetAlert - |+> Static[ - "showBox" => Box?box ^-> SweetAlertProm - |> WithInline ("return Sweetalert2($box);") + let Swal = + Class "Swal" + |+> Static [ + //Generic - fun t -> + // Method "fire" (SweetAlertOptions.Type ^-> t) + + Generic - fun t -> + "fire" => SweetAlertOptions.Type ^-> T>[SweetAlertResult[t]] // TODO: class as input + Generic - fun t -> + "fire" => !? T?title * !? T?html * !? SweetAlertIcon.Type?icon ^-> T>[SweetAlertResult[t]] + + "mixin" => SweetAlertOptions.Type?options ^-> TSelf "isVisible" => T ^-> T - "setDefaults" => Box ^-> T - "resetDefaults" => T ^-> T - "close" => T ^-> T - "enableButtons" => T ^-> T - "getTitle" =? T - "getContent" =? T - "getImage" =? T - "getConfirmButton" =? T - "getCancelButton" =? T - "disableButtons" => T ^-> T - "enableConfirmButton" => T ^-> T - "disableConfirmButton" => T ^-> T - "showLoading" => T ^-> T - "hideLoading" => T ^-> T - "clickConfirm" => T ^-> T - "clickCancel" => T ^-> T - "showValidationErrorMessage" => T ^-> T - "resetValidationError" => T ^-> T - "getInput" =? T - "disableInput" => T ^-> T - "enableInput" => T ^-> T - "queue" => Type.ArrayOf Box ^-> T - "getQueueStep" =? T - "insertQueueStep" => (Box * !? T) ^-> T - "deleteQueueStep" => T ^-> T - "getProgressSteps" =? T - "setProgressSteps" => T ^-> T - "showProgressSteps" => T ^-> T - "hideProgressSteps" => T ^-> T - ]|>ignore + "update" => SweetAlertUpdatableParameters.Type?options ^-> T + Generic - fun t -> + "close" => SweetAlertResult[t] ^-> T + + let get (name:string) (t:Type.Type) = + $"get{name}" => T ^-> t + + for n in [ + "Container";"Popup";"Title";"ProgressSteps";"HtmlContainer";"Image" + "CloseButton";"Icon";"IconContent";"ConfirmButton";"DenyButton";"CancelButton" + "Actions";"Footer";"TimerProgressBar";"ValidationMessage" + ] do + (get n !? T) :> CodeModel.IClassMember + + get"FocusableElements" !| T + + for n in [ + "hideLoading" + "isLoading" + "clickConfirm" + "clickDeny" + "clickCancel" + "disableInput" + "enableInput" + "resetValidationMessage" + ] do + (n => T ^-> T) :> CodeModel.IClassMember + + get"Input" !? T + + for n in [ + "getTimerLeft" + "stopTimer" + "resumeTimer" + "toggleTimer" + ] do + (n => T ^-> !| T) :> CodeModel.IClassMember + + "increaseTimer" => T?n ^-> !| T + "isTimerRunning" => T ^-> !| T + + "version" =? T + + ] |> ImportDefault "sweetalert2" + + let Assembly = Assembly [ Namespace "WebSharper.SweetAlert.Resources" [ - Resource "Css" "https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.6/sweetalert2.min.css" - |> AssemblyWide - Resource "Js" "https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.6/sweetalert2.min.js" - |> AssemblyWide + // Resource "Css" "https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.6.6/sweetalert2.min.css" + // |> AssemblyWide + //Resource "Js" "sweetalert2" + //|> AssemblyWide ] - Namespace "WebSharper.SweetAlert"[ - Box - SweetAlert - SweetAlertProm + + Namespace "WebSharper.SweetAlert" [ + SweetAlertIcon + SweetAlertInput + SweetAlertPosition + SweetAlertCustomClass + SweetAlertHideShowClass + SweetAlertUpdatableParameters + DismissReason + SweetAlertResult + SweetAlertOptions + Swal ] ] diff --git a/WebSharper.SweetAlert/WebSharper.SweetAlert.fsproj b/WebSharper.SweetAlert/WebSharper.SweetAlert.fsproj index 08369e4..d92d932 100644 --- a/WebSharper.SweetAlert/WebSharper.SweetAlert.fsproj +++ b/WebSharper.SweetAlert/WebSharper.SweetAlert.fsproj @@ -1,13 +1,22 @@ netstandard2.0 - Extension + binding false true + WebSharper.SweetAlert 11.7+ + https://github.com/dotnet-websharper/sweetalert/ + IntelliFactory + (c) 2023 IntelliFactory + + + + + \ No newline at end of file diff --git a/WebSharper.SweetAlert/wsconfig.json b/WebSharper.SweetAlert/wsconfig.json new file mode 100644 index 0000000..dfcba5e --- /dev/null +++ b/WebSharper.SweetAlert/wsconfig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://websharper.com/wsconfig.schema.json", + "project": "binding" +} \ No newline at end of file diff --git a/nuget/WebSharper.SweetAlert.paket.template b/nuget/WebSharper.SweetAlert.paket.template index e09b92a..3bcfa0e 100644 --- a/nuget/WebSharper.SweetAlert.paket.template +++ b/nuget/WebSharper.SweetAlert.paket.template @@ -10,7 +10,7 @@ licenseUrl https://github.com/dotnet-websharper/sweetalert/blob/master/LICENSE.m iconUrl https://github.com/dotnet-websharper/core/raw/websharper50/tools/WebSharper.png projectUrl https://github.com/dotnet-websharper/sweetalert description - WebSharper extension for SweetALert + WebSharper bindings for SweetAlert2 11.7 tags Web JavaScript F# C# files diff --git a/paket.dependencies b/paket.dependencies index 80d00cb..ab42b85 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -1,8 +1,7 @@ source https://api.nuget.org/v3/index.json source https://nuget.pkg.github.com/dotnet-websharper/index.json -source ../localnuget -framework: netstandard2.0, net6.0 +framework: netstandard2.0 strategy: min storage: none diff --git a/paket.lock b/paket.lock index 44e9f54..f625a73 100644 --- a/paket.lock +++ b/paket.lock @@ -1,6 +1,6 @@ STORAGE: NONE STRATEGY: MIN -RESTRICTION: || (== net50) (== netcoreapp2.1) (== netcoreapp3.1) (== netstandard2.0) +RESTRICTION: == netstandard2.0 NUGET remote: https://api.nuget.org/v3/index.json FSharp.Core (6.0) @@ -147,9 +147,9 @@ NUGET System.IO (>= 4.3) System.Reflection.Primitives (>= 4.3) System.Runtime (>= 4.3) - System.Reflection.Emit.ILGeneration (4.7) - restriction: || (&& (== net50) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net50) (< netstandard2.0)) (&& (== net50) (< portable-net45+wp8)) (&& (== net50) (>= uap10.1)) (&& (== netcoreapp2.1) (< netcoreapp2.0)) (&& (== netcoreapp2.1) (< netstandard2.0)) (&& (== netcoreapp2.1) (< portable-net45+wp8)) (&& (== netcoreapp2.1) (>= uap10.1)) (&& (== netcoreapp3.1) (< netcoreapp2.0) (< netstandard2.1)) (&& (== netcoreapp3.1) (< netstandard2.0)) (&& (== netcoreapp3.1) (< portable-net45+wp8)) (&& (== netcoreapp3.1) (>= uap10.1)) (== netstandard2.0) + System.Reflection.Emit.ILGeneration (4.7) System.Reflection.Emit.Lightweight (4.7) - System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (== net50) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net50) (< netstandard2.0)) (&& (== net50) (< portable-net45+wp8)) (&& (== net50) (>= uap10.1)) (&& (== netcoreapp2.1) (< netcoreapp2.0)) (&& (== netcoreapp2.1) (< netstandard2.0)) (&& (== netcoreapp2.1) (< portable-net45+wp8)) (&& (== netcoreapp2.1) (>= uap10.1)) (&& (== netcoreapp3.1) (< netcoreapp2.0) (< netstandard2.1)) (&& (== netcoreapp3.1) (< netstandard2.0)) (&& (== netcoreapp3.1) (< portable-net45+wp8)) (&& (== netcoreapp3.1) (>= uap10.1)) (== netstandard2.0) + System.Reflection.Emit.ILGeneration (>= 4.7) System.Reflection.Primitives (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -295,12 +295,12 @@ NUGET System.Runtime (>= 4.3) System.Text.Encoding (>= 4.3) System.Text.RegularExpressions (4.3) - System.Collections (>= 4.3) - restriction: || (&& (== net50) (< netcoreapp1.1)) (&& (== netcoreapp2.1) (< netcoreapp1.1)) (&& (== netcoreapp3.1) (< netcoreapp1.1)) (== netstandard2.0) - System.Globalization (>= 4.3) - restriction: || (&& (== net50) (< netcoreapp1.1)) (&& (== netcoreapp2.1) (< netcoreapp1.1)) (&& (== netcoreapp3.1) (< netcoreapp1.1)) (== netstandard2.0) - System.Resources.ResourceManager (>= 4.3) - restriction: || (&& (== net50) (< netcoreapp1.1)) (&& (== netcoreapp2.1) (< netcoreapp1.1)) (&& (== netcoreapp3.1) (< netcoreapp1.1)) (== netstandard2.0) + System.Collections (>= 4.3) + System.Globalization (>= 4.3) + System.Resources.ResourceManager (>= 4.3) System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - restriction: || (&& (== net50) (< netcoreapp1.1)) (&& (== netcoreapp2.1) (< netcoreapp1.1)) (&& (== netcoreapp3.1) (< netcoreapp1.1)) (== netstandard2.0) - System.Threading (>= 4.3) - restriction: || (&& (== net50) (< netcoreapp1.1)) (&& (== netcoreapp2.1) (< netcoreapp1.1)) (&& (== netcoreapp3.1) (< netcoreapp1.1)) (== netstandard2.0) + System.Runtime.Extensions (>= 4.3) + System.Threading (>= 4.3) System.Threading (4.3) System.Runtime (>= 4.3) System.Threading.Tasks (>= 4.3) @@ -366,12 +366,8 @@ NUGET System.Reflection.Emit.Lightweight (>= 4.7) WebSharper.FSharp (7.0.1.324-beta2) WebSharper (7.0.1.324-beta2) - WebSharper.JQuery (7.0.0.321-beta2) - WebSharper (>= 7.0 < 7.1) WebSharper.MathJS (7.0.1.324-beta2) WebSharper (7.0.1.324-beta2) - WebSharper.Testing (7.0.1.324-beta2) - WebSharper (7.0.1.324-beta2) WebSharper.UI (7.0.0.321-beta2) HtmlAgilityPack (>= 1.11) WebSharper (>= 7.0 < 7.1)