diff --git a/src/Components/Samples/BlazorServerApp/Startup.cs b/src/Components/Samples/BlazorServerApp/Startup.cs index c7723ac690cc..d9131d04e545 100644 --- a/src/Components/Samples/BlazorServerApp/Startup.cs +++ b/src/Components/Samples/BlazorServerApp/Startup.cs @@ -1,11 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/src/Components/Server/src/BlazorPack/BlazorPackHubProtocolWorker.cs b/src/Components/Server/src/BlazorPack/BlazorPackHubProtocolWorker.cs index 721eaedf2b4e..e0dc470a9884 100644 --- a/src/Components/Server/src/BlazorPack/BlazorPackHubProtocolWorker.cs +++ b/src/Components/Server/src/BlazorPack/BlazorPackHubProtocolWorker.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers; +using System.Collections.Generic; using System.IO; using MessagePack; using Microsoft.AspNetCore.SignalR.Protocol; @@ -34,6 +36,21 @@ protected override object DeserializeObject(ref MessagePackReader reader, Type t { return reader.ReadSingle(); } + else if (type == typeof(byte[][])) + { + if (reader.IsNil) + { + return null; + } + + var length = reader.ReadArrayHeader(); + var result = new List(); + for (var i = 0; i < length; i++) + { + result.Add(reader.ReadBytes().GetValueOrDefault().ToArray()); + } + return result.ToArray(); + } } catch (Exception ex) { @@ -75,6 +92,14 @@ protected override void Serialize(ref MessagePackWriter writer, Type type, objec writer.Write(bytes); break; + case byte[][] byteArrays: + writer.WriteArrayHeader(byteArrays.Length); + foreach (var bytes in byteArrays) + { + writer.Write(bytes); + } + break; + default: throw new FormatException($"Unsupported argument type {type}"); } diff --git a/src/Components/Server/src/Circuits/CircuitHost.cs b/src/Components/Server/src/Circuits/CircuitHost.cs index 29dc0bf2f625..1287d9a7fd97 100644 --- a/src/Components/Server/src/Circuits/CircuitHost.cs +++ b/src/Components/Server/src/Circuits/CircuitHost.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.JSInterop; using Microsoft.JSInterop.Infrastructure; namespace Microsoft.AspNetCore.Components.Server.Circuits @@ -336,7 +337,7 @@ public async Task OnRenderCompletedAsync(long renderId, string errorMessageOrNul // BeginInvokeDotNetFromJS is used in a fire-and-forget context, so it's responsible for its own // error handling. - public async Task BeginInvokeDotNetFromJS(string callId, string assemblyName, string methodIdentifier, long dotNetObjectId, string argsJson) + public async Task BeginInvokeDotNetFromJS(string callId, string assemblyName, string methodIdentifier, long dotNetObjectId, SerializedArgs serializedArgs) { AssertInitialized(); AssertNotDisposed(); @@ -347,7 +348,7 @@ await Renderer.Dispatcher.InvokeAsync(() => { Log.BeginInvokeDotNet(_logger, callId, assemblyName, methodIdentifier, dotNetObjectId); var invocationInfo = new DotNetInvocationInfo(assemblyName, methodIdentifier, dotNetObjectId, callId); - DotNetDispatcher.BeginInvokeDotNet(JSRuntime, invocationInfo, argsJson); + DotNetDispatcher.BeginInvokeDotNet(JSRuntime, invocationInfo, serializedArgs); }); } catch (Exception ex) @@ -362,7 +363,7 @@ await Renderer.Dispatcher.InvokeAsync(() => // EndInvokeJSFromDotNet is used in a fire-and-forget context, so it's responsible for its own // error handling. - public async Task EndInvokeJSFromDotNet(long asyncCall, bool succeeded, string arguments) + public async Task EndInvokeJSFromDotNet(long callId, bool succeeded, SerializedArgs serializedArgs) { AssertInitialized(); AssertNotDisposed(); @@ -374,14 +375,14 @@ await Renderer.Dispatcher.InvokeAsync(() => if (!succeeded) { // We can log the arguments here because it is simply the JS error with the call stack. - Log.EndInvokeJSFailed(_logger, asyncCall, arguments); + Log.EndInvokeJSFailed(_logger, callId, serializedArgs.ArgsJson); } else { - Log.EndInvokeJSSucceeded(_logger, asyncCall); + Log.EndInvokeJSSucceeded(_logger, callId); } - DotNetDispatcher.EndInvokeJS(JSRuntime, arguments); + DotNetDispatcher.EndInvokeJS(JSRuntime, serializedArgs); }); } catch (Exception ex) diff --git a/src/Components/Server/src/Circuits/RemoteJSRuntime.cs b/src/Components/Server/src/Circuits/RemoteJSRuntime.cs index a11ad560c057..6d81e7582419 100644 --- a/src/Components/Server/src/Circuits/RemoteJSRuntime.cs +++ b/src/Components/Server/src/Circuits/RemoteJSRuntime.cs @@ -70,11 +70,12 @@ protected override void EndInvokeDotNet(DotNetInvocationInfo invocationInfo, in _clientProxy.SendAsync("JS.EndInvokeDotNet", invocationInfo.CallId, /* success */ true, - invocationResult.ResultJson); + invocationResult.ResultJson, + invocationResult.ByteArrays); } } - protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson, JSCallResultType resultType, long targetInstanceId) + protected override void BeginInvokeJS(long asyncHandle, string identifier, SerializedArgs serializedArgs, JSCallResultType resultType, long targetInstanceId) { if (_clientProxy is null) { @@ -86,7 +87,7 @@ protected override void BeginInvokeJS(long asyncHandle, string identifier, strin Log.BeginInvokeJS(_logger, asyncHandle, identifier); - _clientProxy.SendAsync("JS.BeginInvokeJS", asyncHandle, identifier, argsJson, (int)resultType, targetInstanceId); + _clientProxy.SendAsync("JS.BeginInvokeJS", asyncHandle, identifier, serializedArgs.ArgsJson, serializedArgs.ByteArrays, (int)resultType, targetInstanceId); } public static class Log diff --git a/src/Components/Server/src/ComponentHub.cs b/src/Components/Server/src/ComponentHub.cs index a0b4db6accd5..ca8f7edbe41c 100644 --- a/src/Components/Server/src/ComponentHub.cs +++ b/src/Components/Server/src/ComponentHub.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; +using Microsoft.JSInterop; namespace Microsoft.AspNetCore.Components.Server { @@ -187,7 +188,7 @@ public async ValueTask ConnectCircuit(string circuitIdSecret) return false; } - public async ValueTask BeginInvokeDotNetFromJS(string callId, string assemblyName, string methodIdentifier, long dotNetObjectId, string argsJson) + public async ValueTask BeginInvokeDotNetFromJS(string callId, string assemblyName, string methodIdentifier, long dotNetObjectId, string argsJson, byte[][] byteArrays) { var circuitHost = await GetActiveCircuitAsync(); if (circuitHost == null) @@ -195,10 +196,11 @@ public async ValueTask BeginInvokeDotNetFromJS(string callId, string assemblyNam return; } - _ = circuitHost.BeginInvokeDotNetFromJS(callId, assemblyName, methodIdentifier, dotNetObjectId, argsJson); + var serializedArgs = new SerializedArgs(argsJson, byteArrays); + _ = circuitHost.BeginInvokeDotNetFromJS(callId, assemblyName, methodIdentifier, dotNetObjectId, serializedArgs); } - public async ValueTask EndInvokeJSFromDotNet(long asyncHandle, bool succeeded, string arguments) + public async ValueTask EndInvokeJSFromDotNet(long callId, bool succeeded, string resultOrError, byte[][] byteArrays) { var circuitHost = await GetActiveCircuitAsync(); if (circuitHost == null) @@ -206,7 +208,8 @@ public async ValueTask EndInvokeJSFromDotNet(long asyncHandle, bool succeeded, s return; } - _ = circuitHost.EndInvokeJSFromDotNet(asyncHandle, succeeded, arguments); + var serializedArgs = new SerializedArgs(resultOrError, byteArrays); + _ = circuitHost.EndInvokeJSFromDotNet(callId, succeeded, serializedArgs); } public async ValueTask DispatchBrowserEvent(string eventDescriptor, string eventArgs) diff --git a/src/Components/Shared/src/ArrayBuilder.cs b/src/Components/Shared/src/ArrayBuilder.cs index 6d578adb76d5..61bd03f5ca46 100644 --- a/src/Components/Shared/src/ArrayBuilder.cs +++ b/src/Components/Shared/src/ArrayBuilder.cs @@ -14,6 +14,8 @@ namespace Ignitor namespace Microsoft.AspNetCore.Components.WebView #elif COMPONENTS_SERVER namespace Microsoft.AspNetCore.Components.Server.Circuits +#elif JS_INTEROP +namespace Microsoft.JSInterop.Infrastructure #else namespace Microsoft.AspNetCore.Components.RenderTree #endif diff --git a/src/Components/Web.JS/dist/Release/blazor.server.js b/src/Components/Web.JS/dist/Release/blazor.server.js index b15568800906..c9c78366e799 100644 --- a/src/Components/Web.JS/dist/Release/blazor.server.js +++ b/src/Components/Web.JS/dist/Release/blazor.server.js @@ -1 +1 @@ -(()=>{"use strict";var e,t,n;!function(e){window.DotNet=e;const t=[];class n{constructor(e){this._jsObject=e,this._cachedFunctions=new Map}findFunction(e){const t=this._cachedFunctions.get(e);if(t)return t;let n,r=this._jsObject;if(e.split(".").forEach((t=>{if(!(t in r))throw new Error(`Could not find '${e}' ('${t}' was undefined).`);n=r,r=r[t]})),r instanceof Function)return r=r.bind(n),this._cachedFunctions.set(e,r),r;throw new Error(`The value '${e}' is not a function.`)}getWrappedObject(){return this._jsObject}}const r="__jsObjectId",o={},i={0:new n(window)};i[0]._cachedFunctions.set("import",(e=>("string"==typeof e&&e.startsWith("./")&&(e=document.baseURI+e.substr(2)),import(e))));let s,a=1,c=1,l=null;function h(e){t.push(e)}function u(e){if(e&&"object"==typeof e){i[c]=new n(e);const t={[r]:c};return c++,t}throw new Error(`Cannot create a JSObjectReference from the value '${e}'.`)}function d(e){return e?JSON.parse(e,((e,n)=>t.reduce(((t,n)=>n(e,t)),n))):null}function p(e,t,n,r){const o=g();if(o.invokeDotNetFromJS){const i=JSON.stringify(r,E),s=o.invokeDotNetFromJS(e,t,n,i);return s?d(s):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function f(e,t,n,r){if(e&&n)throw new Error(`For instance method calls, assemblyName should be null. Received '${e}'.`);const i=a++,s=new Promise(((e,t)=>{o[i]={resolve:e,reject:t}}));try{const o=JSON.stringify(r,E);g().beginInvokeDotNetFromJS(i,e,t,n,o)}catch(e){m(i,!1,e)}return s}function g(){if(null!==l)return l;throw new Error("No .NET call dispatcher has been set.")}function m(e,t,n){if(!o.hasOwnProperty(e))throw new Error(`There is no pending async call with ID ${e}.`);const r=o[e];delete o[e],t?r.resolve(n):r.reject(n)}function y(e){return e instanceof Error?`${e.message}\n${e.stack}`:e?e.toString():"null"}function w(e,t){let n=i[t];if(n)return n.findFunction(e);throw new Error(`JS object instance with ID ${t} does not exist (has it been disposed?).`)}function v(e){delete i[e]}e.attachDispatcher=function(e){l=e},e.attachReviver=h,e.invokeMethod=function(e,t,...n){return p(e,t,null,n)},e.invokeMethodAsync=function(e,t,...n){return f(e,t,null,n)},e.createJSObjectReference=u,e.disposeJSObjectReference=function(e){const t=e&&e.__jsObjectId;"number"==typeof t&&v(t)},function(e){e[e.Default=0]="Default",e[e.JSObjectReference=1]="JSObjectReference"}(s=e.JSCallResultType||(e.JSCallResultType={})),e.jsCallDispatcher={findJSFunction:w,disposeJSObjectReferenceById:v,invokeJSFromDotNet:(e,t,n,r)=>{const o=_(w(e,r).apply(null,d(t)),n);return null==o?null:JSON.stringify(o,E)},beginInvokeJSFromDotNet:(e,t,n,r,o)=>{const i=new Promise((e=>{e(w(t,o).apply(null,d(n)))}));e&&i.then((t=>g().endInvokeJSFromDotNet(e,!0,JSON.stringify([e,!0,_(t,r)],E))),(t=>g().endInvokeJSFromDotNet(e,!1,JSON.stringify([e,!1,y(t)]))))},endInvokeDotNetFromJS:(e,t,n)=>{const r=t?d(n):new Error(n);m(parseInt(e),t,r)}};class b{constructor(e){this._id=e}invokeMethod(e,...t){return p(null,e,this._id,t)}invokeMethodAsync(e,...t){return f(null,e,this._id,t)}dispose(){f(null,"__Dispose",this._id,null).catch((e=>console.error(e)))}serializeAsArg(){return{__dotNetObject:this._id}}}function _(e,t){switch(t){case s.Default:return e;case s.JSObjectReference:return u(e);default:throw new Error(`Invalid JS call result type '${t}'.`)}}function E(e,t){return t instanceof b?t.serializeAsArg():t}h((function(e,t){return t&&"object"==typeof t&&t.hasOwnProperty("__dotNetObject")?new b(t.__dotNetObject):t})),h((function(e,t){if(t&&"object"==typeof t&&t.hasOwnProperty(r)){const e=t.__jsObjectId,n=i[e];if(n)return n.getWrappedObject();throw new Error(`JS object instance with ID ${e} does not exist (has it been disposed?).`)}return t}))}(e||(e={})),function(e){e[e.prependFrame=1]="prependFrame",e[e.removeFrame=2]="removeFrame",e[e.setAttribute=3]="setAttribute",e[e.removeAttribute=4]="removeAttribute",e[e.updateText=5]="updateText",e[e.stepIn=6]="stepIn",e[e.stepOut=7]="stepOut",e[e.updateMarkup=8]="updateMarkup",e[e.permutationListEntry=9]="permutationListEntry",e[e.permutationListEnd=10]="permutationListEnd"}(t||(t={})),function(e){e[e.element=1]="element",e[e.text=2]="text",e[e.attribute=3]="attribute",e[e.component=4]="component",e[e.region=5]="region",e[e.elementReferenceCapture=6]="elementReferenceCapture",e[e.markup=8]="markup"}(n||(n={}));class r{constructor(e,t){this.componentId=e,this.fieldValue=t}static fromEvent(e,t){const n=t.target;if(n instanceof Element){const t=function(e){return e instanceof HTMLInputElement?e.type&&"checkbox"===e.type.toLowerCase()?{value:e.checked}:{value:e.value}:e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?{value:e.value}:null}(n);if(t)return new r(e,t.value)}return null}}let o;function i(e,t){if(!o)throw new Error("eventDispatcher not initialized. Call 'setEventDispatcher' to configure it.");o(e,t)}const s=new Map,a=new Map,c={createEventArgs:()=>({})},l=[];function h(e){return s.get(e)}function u(e){const t=s.get(e);return(null==t?void 0:t.browserEventName)||e}function d(e,t){e.forEach((e=>s.set(e,t)))}function p(e){const t=[];for(let n=0;n{return{...f(t=e),dataTransfer:t.dataTransfer?{dropEffect:t.dataTransfer.dropEffect,effectAllowed:t.dataTransfer.effectAllowed,files:Array.from(t.dataTransfer.files).map((e=>e.name)),items:Array.from(t.dataTransfer.items).map((e=>({kind:e.kind,type:e.type}))),types:t.dataTransfer.types}:null};var t}}),d(["focus","blur","focusin","focusout"],c),d(["keydown","keyup","keypress"],{createEventArgs:e=>{return{key:(t=e).key,code:t.code,location:t.location,repeat:t.repeat,ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),d(["contextmenu","click","mouseover","mouseout","mousemove","mousedown","mouseup","dblclick"],{createEventArgs:e=>f(e)}),d(["error"],{createEventArgs:e=>{return{message:(t=e).message,filename:t.filename,lineno:t.lineno,colno:t.colno};var t}}),d(["loadstart","timeout","abort","load","loadend","progress"],{createEventArgs:e=>{return{lengthComputable:(t=e).lengthComputable,loaded:t.loaded,total:t.total};var t}}),d(["touchcancel","touchend","touchmove","touchenter","touchleave","touchstart"],{createEventArgs:e=>{return{detail:(t=e).detail,touches:p(t.touches),targetTouches:p(t.targetTouches),changedTouches:p(t.changedTouches),ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),d(["gotpointercapture","lostpointercapture","pointercancel","pointerdown","pointerenter","pointerleave","pointermove","pointerout","pointerover","pointerup"],{createEventArgs:e=>{return{...f(t=e),pointerId:t.pointerId,width:t.width,height:t.height,pressure:t.pressure,tiltX:t.tiltX,tiltY:t.tiltY,pointerType:t.pointerType,isPrimary:t.isPrimary};var t}}),d(["wheel","mousewheel"],{createEventArgs:e=>{return{...f(t=e),deltaX:t.deltaX,deltaY:t.deltaY,deltaZ:t.deltaZ,deltaMode:t.deltaMode};var t}}),d(["toggle"],c);const g=["date","datetime-local","month","time","week"],m=E(["abort","blur","change","error","focus","load","loadend","loadstart","mouseenter","mouseleave","progress","reset","scroll","submit","unload","toggle","DOMNodeInsertedIntoDocument","DOMNodeRemovedFromDocument"]),y={submit:!0},w=E(["click","dblclick","mousedown","mousemove","mouseup"]);class v{constructor(e){this.browserRendererId=e,this.afterClickCallbacks=[];const t=++v.nextEventDelegatorId;this.eventsCollectionKey=`_blazorEvents_${t}`,this.eventInfoStore=new b(this.onGlobalEvent.bind(this))}setListener(e,t,n,r){const o=this.getEventHandlerInfosForElement(e,!0),i=o.getHandler(t);if(i)this.eventInfoStore.update(i.eventHandlerId,n);else{const i={element:e,eventName:t,eventHandlerId:n,renderingComponentId:r};this.eventInfoStore.add(i),o.setHandler(t,i)}}getHandler(e){return this.eventInfoStore.get(e)}removeListener(e){const t=this.eventInfoStore.remove(e);if(t){const e=t.element,n=this.getEventHandlerInfosForElement(e,!1);n&&n.removeHandler(t.eventName)}}notifyAfterClick(e){this.afterClickCallbacks.push(e),this.eventInfoStore.addGlobalListener("click")}setStopPropagation(e,t,n){this.getEventHandlerInfosForElement(e,!0).stopPropagation(t,n)}setPreventDefault(e,t,n){this.getEventHandlerInfosForElement(e,!0).preventDefault(t,n)}onGlobalEvent(e){if(!(e.target instanceof Element))return;this.dispatchGlobalEventToAllElements(e.type,e);const t=(n=e.type,a.get(n));var n;t&&t.forEach((t=>this.dispatchGlobalEventToAllElements(t,e))),"click"===e.type&&this.afterClickCallbacks.forEach((t=>t(e)))}dispatchGlobalEventToAllElements(e,t){let n=t.target,o=null,s=!1;const a=m.hasOwnProperty(e);let c=!1;for(;n;){const d=this.getEventHandlerInfosForElement(n,!1);if(d){const a=d.getHandler(e);if(a&&(l=n,u=t.type,!((l instanceof HTMLButtonElement||l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)&&w.hasOwnProperty(u)&&l.disabled))){if(!s){const n=h(e);o=(null==n?void 0:n.createEventArgs)?n.createEventArgs(t):{},s=!0}y.hasOwnProperty(t.type)&&t.preventDefault(),i({browserRendererId:this.browserRendererId,eventHandlerId:a.eventHandlerId,eventName:e,eventFieldInfo:r.fromEvent(a.renderingComponentId,t)},o)}d.stopPropagation(e)&&(c=!0),d.preventDefault(e)&&t.preventDefault()}n=a||c?null:n.parentElement}var l,u}getEventHandlerInfosForElement(e,t){return e.hasOwnProperty(this.eventsCollectionKey)?e[this.eventsCollectionKey]:t?e[this.eventsCollectionKey]=new _:null}}v.nextEventDelegatorId=0;class b{constructor(e){this.globalListener=e,this.infosByEventHandlerId={},this.countByEventName={},l.push(this.handleEventNameAliasAdded.bind(this))}add(e){if(this.infosByEventHandlerId[e.eventHandlerId])throw new Error(`Event ${e.eventHandlerId} is already tracked`);this.infosByEventHandlerId[e.eventHandlerId]=e,this.addGlobalListener(e.eventName)}get(e){return this.infosByEventHandlerId[e]}addGlobalListener(e){if(e=u(e),this.countByEventName.hasOwnProperty(e))this.countByEventName[e]++;else{this.countByEventName[e]=1;const t=m.hasOwnProperty(e);document.addEventListener(e,this.globalListener,t)}}update(e,t){if(this.infosByEventHandlerId.hasOwnProperty(t))throw new Error(`Event ${t} is already tracked`);const n=this.infosByEventHandlerId[e];delete this.infosByEventHandlerId[e],n.eventHandlerId=t,this.infosByEventHandlerId[t]=n}remove(e){const t=this.infosByEventHandlerId[e];if(t){delete this.infosByEventHandlerId[e];const n=u(t.eventName);0==--this.countByEventName[n]&&(delete this.countByEventName[n],document.removeEventListener(n,this.globalListener))}return t}handleEventNameAliasAdded(e,t){if(this.countByEventName.hasOwnProperty(e)){const n=this.countByEventName[e];delete this.countByEventName[e],document.removeEventListener(e,this.globalListener),this.addGlobalListener(t),this.countByEventName[t]+=n-1}}}class _{constructor(){this.handlers={},this.preventDefaultFlags=null,this.stopPropagationFlags=null}getHandler(e){return this.handlers.hasOwnProperty(e)?this.handlers[e]:null}setHandler(e,t){this.handlers[e]=t}removeHandler(e){delete this.handlers[e]}preventDefault(e,t){return void 0!==t&&(this.preventDefaultFlags=this.preventDefaultFlags||{},this.preventDefaultFlags[e]=t),!!this.preventDefaultFlags&&this.preventDefaultFlags[e]}stopPropagation(e,t){return void 0!==t&&(this.stopPropagationFlags=this.stopPropagationFlags||{},this.stopPropagationFlags[e]=t),!!this.stopPropagationFlags&&this.stopPropagationFlags[e]}}function E(e){const t={};return e.forEach((e=>{t[e]=!0})),t}const S=H("_blazorLogicalChildren"),C=H("_blazorLogicalParent"),I=H("_blazorLogicalEnd");function k(e,t){if(e.childNodes.length>0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return S in e||(e[S]=[]),e}function T(e,t){const n=document.createComment("!");return x(n,e,t),n}function x(e,t,n){const r=e;if(e instanceof Comment&&A(r)&&A(r).length>0)throw new Error("Not implemented: inserting non-empty logical container");if(R(r))throw new Error("Not implemented: moving existing logical children");const o=A(t);if(n0;)D(n,0)}const r=n;r.parentNode.removeChild(r)}function R(e){return e[C]||null}function P(e,t){return A(e)[t]}function U(e){var t=$(e);return"http://www.w3.org/2000/svg"===t.namespaceURI&&"foreignObject"!==t.tagName}function A(e){return e[S]}function N(e,t){const n=A(e);t.forEach((e=>{e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=L(e.moveRangeStart)})),t.forEach((t=>{const r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):M(r,e)})),t.forEach((e=>{const t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd;let i=r;for(;i;){const e=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=e}n.removeChild(t)})),t.forEach((e=>{n[e.toSiblingIndex]=e.moveRangeStart}))}function $(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}function B(e){const t=A(R(e));return t[Array.prototype.indexOf.call(t,e)+1]||null}function M(e,t){if(t instanceof Element)t.appendChild(e);else{if(!(t instanceof Comment))throw new Error(`Cannot append node because the parent is not a valid logical element. Parent: ${t}`);{const n=B(t);n?n.parentNode.insertBefore(e,n):M(e,R(t))}}}function L(e){if(e instanceof Element)return e;const t=B(e);if(t)return t.previousSibling;{const t=R(e);return t instanceof Element?t.lastChild:L(t)}}function H(e){return"function"==typeof Symbol?Symbol():e}function F(e){return`_bl_${e}`}e.attachReviver(((e,t)=>t&&"object"==typeof t&&t.hasOwnProperty("__internalId")&&"string"==typeof t.__internalId?function(e){const t=`[${F(e)}]`;return document.querySelector(t)}(t.__internalId):t));const O="_blazorSelectValue",j=document.createElement("template"),W=document.createElementNS("http://www.w3.org/2000/svg","g"),z={},q="__internal_",J="preventDefault_",K="stopPropagation_";class V{constructor(e){this.childComponentLocations={},this.eventDelegator=new v(e),this.eventDelegator.notifyAfterClick((e=>{if(!ee)return;if(0!==e.button||function(e){return e.ctrlKey||e.shiftKey||e.altKey||e.metaKey}(e))return;if(e.defaultPrevented)return;const t=function(e){const t=!window._blazorDisableComposedPath&&e.composedPath&&e.composedPath();if(t){for(let e=0;ese(!1))))},enableNavigationInterception:function(){ee=!0},navigateTo:oe,getBaseURI:()=>document.baseURI,getLocationHref:()=>location.href};function oe(e,t,n=!1){const r=ce(e);if(!t&&he(r))ie(r,!1,n);else if(t&&location.href===e){const t=e+"?";history.replaceState(null,"",t),location.replace(e)}else n?history.replaceState(null,"",r):location.href=e}function ie(e,t,n=!1){Z=!0,n?history.replaceState(null,"",e):history.pushState(null,"",e),se(t)}async function se(e){ne&&await ne(location.href,e)}let ae;function ce(e){return ae=ae||document.createElement("a"),ae.href=e,ae.href}function le(e,t){return e?e.tagName===t?e:le(e.parentElement,t):null}function he(e){const t=(n=document.baseURI).substr(0,n.lastIndexOf("/")+1);var n;return e.startsWith(t)}const ue={init:function(e,t,n,r=50){const o=pe(t);(o||document.documentElement).style.overflowAnchor="none";const i=new IntersectionObserver((function(r){r.forEach((r=>{var o;if(!r.isIntersecting)return;const i=t.getBoundingClientRect(),s=n.getBoundingClientRect().top-i.bottom,a=null===(o=r.rootBounds)||void 0===o?void 0:o.height;r.target===t?e.invokeMethodAsync("OnSpacerBeforeVisible",r.intersectionRect.top-r.boundingClientRect.top,s,a):r.target===n&&n.offsetHeight>0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,s,a)}))}),{root:o,rootMargin:`${r}px`});i.observe(t),i.observe(n);const s=c(t),a=c(n);function c(e){const t=new MutationObserver((()=>{i.unobserve(e),i.observe(e)}));return t.observe(e,{attributes:!0}),t}de[e._id]={intersectionObserver:i,mutationObserverBefore:s,mutationObserverAfter:a}},dispose:function(e){const t=de[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete de[e._id])}},de={};function pe(e){return e?"visible"!==getComputedStyle(e).overflowY?e:pe(e.parentElement):null}const fe={navigateTo:oe,registerCustomEventType:function(e,t){if(!t)throw new Error("The options parameter is required.");if(s.has(e))throw new Error(`The event '${e}' is already registered.`);if(t.browserEventName){const n=a.get(t.browserEventName);n?n.push(e):a.set(t.browserEventName,[e]),l.forEach((n=>n(e,t.browserEventName)))}s.set(e,t)},_internal:{navigationManager:re,domWrapper:{focus:function(e,t){if(!(e instanceof HTMLElement))throw new Error("Unable to focus an invalid element.");e.focus({preventScroll:t})}},Virtualize:ue}};window.Blazor=fe;const ge=[0,2e3,1e4,3e4,null];class me{constructor(e){this._retryDelays=void 0!==e?[...e,null]:ge}nextRetryDelayInMilliseconds(e){return this._retryDelays[e.previousRetryCount]}}class ye extends Error{constructor(e,t){const n=new.target.prototype;super(`${e}: Status code '${t}'`),this.statusCode=t,this.__proto__=n}}class we extends Error{constructor(e="A timeout occurred."){const t=new.target.prototype;super(e),this.__proto__=t}}class ve extends Error{constructor(e="An abort occurred."){const t=new.target.prototype;super(e),this.__proto__=t}}class be{constructor(e,t,n){this.statusCode=e,this.statusText=t,this.content=n}}class _e{get(e,t){return this.send({...t,method:"GET",url:e})}post(e,t){return this.send({...t,method:"POST",url:e})}delete(e,t){return this.send({...t,method:"DELETE",url:e})}getCookieString(e){return""}}var Ee,Se,Ce,Ie,ke;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Information=2]="Information",e[e.Warning=3]="Warning",e[e.Error=4]="Error",e[e.Critical=5]="Critical",e[e.None=6]="None"}(Ee||(Ee={}));class Te extends _e{constructor(e){if(super(),this._logger=e,"undefined"==typeof fetch){const e=require;this._jar=new(e("tough-cookie").CookieJar),this._fetchType=e("node-fetch"),this._fetchType=e("fetch-cookie")(this._fetchType,this._jar),this._abortControllerType=e("abort-controller")}else this._fetchType=fetch.bind(self),this._abortControllerType=AbortController}async send(e){if(e.abortSignal&&e.abortSignal.aborted)throw new ve;if(!e.method)throw new Error("No method defined.");if(!e.url)throw new Error("No url defined.");const t=new this._abortControllerType;let n;e.abortSignal&&(e.abortSignal.onabort=()=>{t.abort(),n=new ve});let r,o=null;if(e.timeout){const r=e.timeout;o=setTimeout((()=>{t.abort(),this._logger.log(Ee.Warning,"Timeout from HTTP request."),n=new we}),r)}try{r=await this._fetchType(e.url,{body:e.content,cache:"no-cache",credentials:!0===e.withCredentials?"include":"same-origin",headers:{"Content-Type":"text/plain;charset=UTF-8","X-Requested-With":"XMLHttpRequest",...e.headers},method:e.method,mode:"cors",redirect:"follow",signal:t.signal})}catch(e){if(n)throw n;throw this._logger.log(Ee.Warning,`Error from HTTP request. ${e}.`),e}finally{o&&clearTimeout(o),e.abortSignal&&(e.abortSignal.onabort=null)}if(!r.ok){const e=await xe(r,"text");throw new ye(e||r.statusText,r.status)}const i=xe(r,e.responseType),s=await i;return new be(r.status,r.statusText,s)}getCookieString(e){return""}}function xe(e,t){let n;switch(t){case"arraybuffer":n=e.arrayBuffer();break;case"text":n=e.text();break;case"blob":case"document":case"json":throw new Error(`${t} is not supported.`);default:n=e.text()}return n}class De extends _e{constructor(e){super(),this._logger=e}send(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new ve):e.method?e.url?new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open(e.method,e.url,!0),r.withCredentials=void 0===e.withCredentials||e.withCredentials,r.setRequestHeader("X-Requested-With","XMLHttpRequest"),r.setRequestHeader("Content-Type","text/plain;charset=UTF-8");const o=e.headers;o&&Object.keys(o).forEach((e=>{r.setRequestHeader(e,o[e])})),e.responseType&&(r.responseType=e.responseType),e.abortSignal&&(e.abortSignal.onabort=()=>{r.abort(),n(new ve)}),e.timeout&&(r.timeout=e.timeout),r.onload=()=>{e.abortSignal&&(e.abortSignal.onabort=null),r.status>=200&&r.status<300?t(new be(r.status,r.statusText,r.response||r.responseText)):n(new ye(r.response||r.responseText||r.statusText,r.status))},r.onerror=()=>{this._logger.log(Ee.Warning,`Error from HTTP request. ${r.status}: ${r.statusText}.`),n(new ye(r.statusText,r.status))},r.ontimeout=()=>{this._logger.log(Ee.Warning,"Timeout from HTTP request."),n(new we)},r.send(e.content||"")})):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))}}class Re extends _e{constructor(e){if(super(),"undefined"!=typeof fetch)this._httpClient=new Te(e);else{if("undefined"==typeof XMLHttpRequest)throw new Error("No usable HttpClient found.");this._httpClient=new De(e)}}send(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new ve):e.method?e.url?this._httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))}getCookieString(e){return this._httpClient.getCookieString(e)}}class Pe{}Pe.Authorization="Authorization",Pe.Cookie="Cookie",function(e){e[e.None=0]="None",e[e.WebSockets=1]="WebSockets",e[e.ServerSentEvents=2]="ServerSentEvents",e[e.LongPolling=4]="LongPolling"}(Se||(Se={})),function(e){e[e.Text=1]="Text",e[e.Binary=2]="Binary"}(Ce||(Ce={}));class Ue{constructor(){this._isAborted=!1,this.onabort=null}abort(){this._isAborted||(this._isAborted=!0,this.onabort&&this.onabort())}get signal(){return this}get aborted(){return this._isAborted}}class Ae{constructor(){}log(e,t){}}Ae.instance=new Ae;class Ne{static isRequired(e,t){if(null==e)throw new Error(`The '${t}' argument is required.`)}static isNotEmpty(e,t){if(!e||e.match(/^\s*$/))throw new Error(`The '${t}' argument should not be empty.`)}static isIn(e,t,n){if(!(e in t))throw new Error(`Unknown ${n} value: ${e}.`)}}class $e{static get isBrowser(){return"object"==typeof window}static get isWebWorker(){return"object"==typeof self&&"importScripts"in self}static get isNode(){return!this.isBrowser&&!this.isWebWorker}}function Be(e,t){let n="";return Me(e)?(n=`Binary data of length ${e.byteLength}`,t&&(n+=`. Content: '${function(e){const t=new Uint8Array(e);let n="";return t.forEach((e=>{n+=`0x${e<16?"0":""}${e.toString(16)} `})),n.substr(0,n.length-1)}(e)}'`)):"string"==typeof e&&(n=`String data of length ${e.length}`,t&&(n+=`. Content: '${e}'`)),n}function Me(e){return e&&"undefined"!=typeof ArrayBuffer&&(e instanceof ArrayBuffer||e.constructor&&"ArrayBuffer"===e.constructor.name)}async function Le(e,t,n,r,o,i,s,a,c){let l={};if(o){const e=await o();e&&(l={Authorization:`Bearer ${e}`})}const[h,u]=Oe();l[h]=u,e.log(Ee.Trace,`(${t} transport) sending data. ${Be(i,s)}.`);const d=Me(i)?"arraybuffer":"text",p=await n.post(r,{content:i,headers:{...l,...c},responseType:d,withCredentials:a});e.log(Ee.Trace,`(${t} transport) request complete. Response status: ${p.statusCode}.`)}class He{constructor(e,t){this._subject=e,this._observer=t}dispose(){const e=this._subject.observers.indexOf(this._observer);e>-1&&this._subject.observers.splice(e,1),0===this._subject.observers.length&&this._subject.cancelCallback&&this._subject.cancelCallback().catch((e=>{}))}}class Fe{constructor(e){this._minLevel=e,this.out=console}log(e,t){if(e>=this._minLevel){const n=`[${(new Date).toISOString()}] ${Ee[e]}: ${t}`;switch(e){case Ee.Critical:case Ee.Error:this.out.error(n);break;case Ee.Warning:this.out.warn(n);break;case Ee.Information:this.out.info(n);break;default:this.out.log(n)}}}}function Oe(){let e="X-SignalR-User-Agent";return $e.isNode&&(e="User-Agent"),[e,je("0.0.0-DEV_BUILD",We(),$e.isNode?"NodeJS":"Browser",ze())]}function je(e,t,n,r){let o="Microsoft SignalR/";const i=e.split(".");return o+=`${i[0]}.${i[1]}`,o+=` (${e}; `,o+=t&&""!==t?`${t}; `:"Unknown OS; ",o+=`${n}`,o+=r?`; ${r}`:"; Unknown Runtime Version",o+=")",o}function We(){if(!$e.isNode)return"";switch(process.platform){case"win32":return"Windows NT";case"darwin":return"macOS";case"linux":return"Linux";default:return process.platform}}function ze(){if($e.isNode)return process.versions.node}class qe{constructor(e,t,n,r,o,i){this._httpClient=e,this._accessTokenFactory=t,this._logger=n,this._pollAbort=new Ue,this._logMessageContent=r,this._withCredentials=o,this._headers=i,this._running=!1,this.onreceive=null,this.onclose=null}get pollAborted(){return this._pollAbort.aborted}async connect(e,t){if(Ne.isRequired(e,"url"),Ne.isRequired(t,"transferFormat"),Ne.isIn(t,Ce,"transferFormat"),this._url=e,this._logger.log(Ee.Trace,"(LongPolling transport) Connecting."),t===Ce.Binary&&"undefined"!=typeof XMLHttpRequest&&"string"!=typeof(new XMLHttpRequest).responseType)throw new Error("Binary protocols over XmlHttpRequest not implementing advanced features are not supported.");const[n,r]=Oe(),o={[n]:r,...this._headers},i={abortSignal:this._pollAbort.signal,headers:o,timeout:1e5,withCredentials:this._withCredentials};t===Ce.Binary&&(i.responseType="arraybuffer");const s=await this._getAccessToken();this._updateHeaderToken(i,s);const a=`${e}&_=${Date.now()}`;this._logger.log(Ee.Trace,`(LongPolling transport) polling: ${a}.`);const c=await this._httpClient.get(a,i);200!==c.statusCode?(this._logger.log(Ee.Error,`(LongPolling transport) Unexpected response code: ${c.statusCode}.`),this._closeError=new ye(c.statusText||"",c.statusCode),this._running=!1):this._running=!0,this._receiving=this._poll(this._url,i)}async _getAccessToken(){return this._accessTokenFactory?await this._accessTokenFactory():null}_updateHeaderToken(e,t){e.headers||(e.headers={}),t?e.headers[Pe.Authorization]=`Bearer ${t}`:e.headers[Pe.Authorization]&&delete e.headers[Pe.Authorization]}async _poll(e,t){try{for(;this._running;){const n=await this._getAccessToken();this._updateHeaderToken(t,n);try{const n=`${e}&_=${Date.now()}`;this._logger.log(Ee.Trace,`(LongPolling transport) polling: ${n}.`);const r=await this._httpClient.get(n,t);204===r.statusCode?(this._logger.log(Ee.Information,"(LongPolling transport) Poll terminated by server."),this._running=!1):200!==r.statusCode?(this._logger.log(Ee.Error,`(LongPolling transport) Unexpected response code: ${r.statusCode}.`),this._closeError=new ye(r.statusText||"",r.statusCode),this._running=!1):r.content?(this._logger.log(Ee.Trace,`(LongPolling transport) data received. ${Be(r.content,this._logMessageContent)}.`),this.onreceive&&this.onreceive(r.content)):this._logger.log(Ee.Trace,"(LongPolling transport) Poll timed out, reissuing.")}catch(e){this._running?e instanceof we?this._logger.log(Ee.Trace,"(LongPolling transport) Poll timed out, reissuing."):(this._closeError=e,this._running=!1):this._logger.log(Ee.Trace,`(LongPolling transport) Poll errored after shutdown: ${e.message}`)}}}finally{this._logger.log(Ee.Trace,"(LongPolling transport) Polling complete."),this.pollAborted||this._raiseOnClose()}}async send(e){return this._running?Le(this._logger,"LongPolling",this._httpClient,this._url,this._accessTokenFactory,e,this._logMessageContent,this._withCredentials,this._headers):Promise.reject(new Error("Cannot send until the transport is connected"))}async stop(){this._logger.log(Ee.Trace,"(LongPolling transport) Stopping polling."),this._running=!1,this._pollAbort.abort();try{await this._receiving,this._logger.log(Ee.Trace,`(LongPolling transport) sending DELETE request to ${this._url}.`);const e={},[t,n]=Oe();e[t]=n;const r={headers:{...e,...this._headers},withCredentials:this._withCredentials},o=await this._getAccessToken();this._updateHeaderToken(r,o),await this._httpClient.delete(this._url,r),this._logger.log(Ee.Trace,"(LongPolling transport) DELETE request sent.")}finally{this._logger.log(Ee.Trace,"(LongPolling transport) Stop finished."),this._raiseOnClose()}}_raiseOnClose(){if(this.onclose){let e="(LongPolling transport) Firing onclose event.";this._closeError&&(e+=" Error: "+this._closeError),this._logger.log(Ee.Trace,e),this.onclose(this._closeError)}}}class Je{constructor(e,t,n,r,o,i,s){this._httpClient=e,this._accessTokenFactory=t,this._logger=n,this._logMessageContent=r,this._withCredentials=i,this._eventSourceConstructor=o,this._headers=s,this.onreceive=null,this.onclose=null}async connect(e,t){if(Ne.isRequired(e,"url"),Ne.isRequired(t,"transferFormat"),Ne.isIn(t,Ce,"transferFormat"),this._logger.log(Ee.Trace,"(SSE transport) Connecting."),this._url=e,this._accessTokenFactory){const t=await this._accessTokenFactory();t&&(e+=(e.indexOf("?")<0?"?":"&")+`access_token=${encodeURIComponent(t)}`)}return new Promise(((n,r)=>{let o,i=!1;if(t===Ce.Text){if($e.isBrowser||$e.isWebWorker)o=new this._eventSourceConstructor(e,{withCredentials:this._withCredentials});else{const t=this._httpClient.getCookieString(e),n={};n.Cookie=t;const[r,i]=Oe();n[r]=i,o=new this._eventSourceConstructor(e,{withCredentials:this._withCredentials,headers:{...n,...this._headers}})}try{o.onmessage=e=>{if(this.onreceive)try{this._logger.log(Ee.Trace,`(SSE transport) data received. ${Be(e.data,this._logMessageContent)}.`),this.onreceive(e.data)}catch(e){return void this._close(e)}},o.onerror=e=>{i?this._close():r(new Error("EventSource failed to connect. The connection could not be found on the server, either the connection ID is not present on the server, or a proxy is refusing/buffering the connection. If you have multiple servers check that sticky sessions are enabled."))},o.onopen=()=>{this._logger.log(Ee.Information,`SSE connected to ${this._url}`),this._eventSource=o,i=!0,n()}}catch(e){return void r(e)}}else r(new Error("The Server-Sent Events transport only supports the 'Text' transfer format"))}))}async send(e){return this._eventSource?Le(this._logger,"SSE",this._httpClient,this._url,this._accessTokenFactory,e,this._logMessageContent,this._withCredentials,this._headers):Promise.reject(new Error("Cannot send until the transport is connected"))}stop(){return this._close(),Promise.resolve()}_close(e){this._eventSource&&(this._eventSource.close(),this._eventSource=void 0,this.onclose&&this.onclose(e))}}class Ke{constructor(e,t,n,r,o,i){this._logger=n,this._accessTokenFactory=t,this._logMessageContent=r,this._webSocketConstructor=o,this._httpClient=e,this.onreceive=null,this.onclose=null,this._headers=i}async connect(e,t){if(Ne.isRequired(e,"url"),Ne.isRequired(t,"transferFormat"),Ne.isIn(t,Ce,"transferFormat"),this._logger.log(Ee.Trace,"(WebSockets transport) Connecting."),this._accessTokenFactory){const t=await this._accessTokenFactory();t&&(e+=(e.indexOf("?")<0?"?":"&")+`access_token=${encodeURIComponent(t)}`)}return new Promise(((n,r)=>{let o;e=e.replace(/^http/,"ws"),this._httpClient.getCookieString(e);let i=!1;o||(o=new this._webSocketConstructor(e)),t===Ce.Binary&&(o.binaryType="arraybuffer"),o.onopen=t=>{this._logger.log(Ee.Information,`WebSocket connected to ${e}.`),this._webSocket=o,i=!0,n()},o.onerror=e=>{let t=null;t="undefined"!=typeof ErrorEvent&&e instanceof ErrorEvent?e.error:"There was an error with the transport",this._logger.log(Ee.Information,`(WebSockets transport) ${t}.`)},o.onmessage=e=>{if(this._logger.log(Ee.Trace,`(WebSockets transport) data received. ${Be(e.data,this._logMessageContent)}.`),this.onreceive)try{this.onreceive(e.data)}catch(e){return void this._close(e)}},o.onclose=e=>{if(i)this._close(e);else{let t=null;t="undefined"!=typeof ErrorEvent&&e instanceof ErrorEvent?e.error:"WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.",r(new Error(t))}}}))}send(e){return this._webSocket&&this._webSocket.readyState===this._webSocketConstructor.OPEN?(this._logger.log(Ee.Trace,`(WebSockets transport) sending data. ${Be(e,this._logMessageContent)}.`),this._webSocket.send(e),Promise.resolve()):Promise.reject("WebSocket is not in the OPEN state")}stop(){return this._webSocket&&this._close(void 0),Promise.resolve()}_close(e){this._webSocket&&(this._webSocket.onclose=()=>{},this._webSocket.onmessage=()=>{},this._webSocket.onerror=()=>{},this._webSocket.close(),this._webSocket=void 0),this._logger.log(Ee.Trace,"(WebSockets transport) socket closed."),this.onclose&&(!this._isCloseEvent(e)||!1!==e.wasClean&&1e3===e.code?e instanceof Error?this.onclose(e):this.onclose():this.onclose(new Error(`WebSocket closed with status code: ${e.code} (${e.reason||"no reason given"}).`)))}_isCloseEvent(e){return e&&"boolean"==typeof e.wasClean&&"number"==typeof e.code}}class Ve{constructor(e,t={}){var n;if(this._stopPromiseResolver=()=>{},this.features={},this._negotiateVersion=1,Ne.isRequired(e,"url"),this._logger=void 0===(n=t.logger)?new Fe(Ee.Information):null===n?Ae.instance:void 0!==n.log?n:new Fe(n),this.baseUrl=this._resolveUrl(e),(t=t||{}).logMessageContent=void 0!==t.logMessageContent&&t.logMessageContent,"boolean"!=typeof t.withCredentials&&void 0!==t.withCredentials)throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");t.withCredentials=void 0===t.withCredentials||t.withCredentials,"undefined"==typeof WebSocket||t.WebSocket||(t.WebSocket=WebSocket),"undefined"==typeof EventSource||t.EventSource||(t.EventSource=EventSource),this._httpClient=t.httpClient||new Re(this._logger),this._connectionState="Disconnected",this._connectionStarted=!1,this._options=t,this.onreceive=null,this.onclose=null}async start(e){if(e=e||Ce.Binary,Ne.isIn(e,Ce,"transferFormat"),this._logger.log(Ee.Debug,`Starting connection with transfer format '${Ce[e]}'.`),"Disconnected"!==this._connectionState)return Promise.reject(new Error("Cannot start an HttpConnection that is not in the 'Disconnected' state."));if(this._connectionState="Connecting",this._startInternalPromise=this._startInternal(e),await this._startInternalPromise,"Disconnecting"===this._connectionState){const e="Failed to start the HttpConnection before stop() was called.";return this._logger.log(Ee.Error,e),await this._stopPromise,Promise.reject(new Error(e))}if("Connected"!==this._connectionState){const e="HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!";return this._logger.log(Ee.Error,e),Promise.reject(new Error(e))}this._connectionStarted=!0}send(e){return"Connected"!==this._connectionState?Promise.reject(new Error("Cannot send data if the connection is not in the 'Connected' State.")):(this._sendQueue||(this._sendQueue=new Xe(this.transport)),this._sendQueue.send(e))}async stop(e){return"Disconnected"===this._connectionState?(this._logger.log(Ee.Debug,`Call to HttpConnection.stop(${e}) ignored because the connection is already in the disconnected state.`),Promise.resolve()):"Disconnecting"===this._connectionState?(this._logger.log(Ee.Debug,`Call to HttpConnection.stop(${e}) ignored because the connection is already in the disconnecting state.`),this._stopPromise):(this._connectionState="Disconnecting",this._stopPromise=new Promise((e=>{this._stopPromiseResolver=e})),await this._stopInternal(e),void await this._stopPromise)}async _stopInternal(e){this._stopError=e;try{await this._startInternalPromise}catch(e){}if(this.transport){try{await this.transport.stop()}catch(e){this._logger.log(Ee.Error,`HttpConnection.transport.stop() threw error '${e}'.`),this._stopConnection()}this.transport=void 0}else this._logger.log(Ee.Debug,"HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.")}async _startInternal(e){let t=this.baseUrl;this._accessTokenFactory=this._options.accessTokenFactory;try{if(this._options.skipNegotiation){if(this._options.transport!==Se.WebSockets)throw new Error("Negotiation can only be skipped when using the WebSocket transport directly.");this.transport=this._constructTransport(Se.WebSockets),await this._startTransport(t,e)}else{let n=null,r=0;do{if(n=await this._getNegotiationResponse(t),"Disconnecting"===this._connectionState||"Disconnected"===this._connectionState)throw new Error("The connection was stopped during negotiation.");if(n.error)throw new Error(n.error);if(n.ProtocolVersion)throw new Error("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.");if(n.url&&(t=n.url),n.accessToken){const e=n.accessToken;this._accessTokenFactory=()=>e}r++}while(n.url&&r<100);if(100===r&&n.url)throw new Error("Negotiate redirection limit exceeded.");await this._createTransport(t,this._options.transport,n,e)}this.transport instanceof qe&&(this.features.inherentKeepAlive=!0),"Connecting"===this._connectionState&&(this._logger.log(Ee.Debug,"The HttpConnection connected successfully."),this._connectionState="Connected")}catch(e){return this._logger.log(Ee.Error,"Failed to start the connection: "+e),this._connectionState="Disconnected",this.transport=void 0,this._stopPromiseResolver(),Promise.reject(e)}}async _getNegotiationResponse(e){const t={};if(this._accessTokenFactory){const e=await this._accessTokenFactory();e&&(t[Pe.Authorization]=`Bearer ${e}`)}const[n,r]=Oe();t[n]=r;const o=this._resolveNegotiateUrl(e);this._logger.log(Ee.Debug,`Sending negotiation request: ${o}.`);try{const e=await this._httpClient.post(o,{content:"",headers:{...t,...this._options.headers},withCredentials:this._options.withCredentials});if(200!==e.statusCode)return Promise.reject(new Error(`Unexpected status code returned from negotiate '${e.statusCode}'`));const n=JSON.parse(e.content);return(!n.negotiateVersion||n.negotiateVersion<1)&&(n.connectionToken=n.connectionId),n}catch(e){let t="Failed to complete negotiation with the server: "+e;return e instanceof ye&&404===e.statusCode&&(t+=" Either this is not a SignalR endpoint or there is a proxy blocking the connection."),this._logger.log(Ee.Error,t),Promise.reject(new Error(t))}}_createConnectUrl(e,t){return t?e+(-1===e.indexOf("?")?"?":"&")+`id=${t}`:e}async _createTransport(e,t,n,r){let o=this._createConnectUrl(e,n.connectionToken);if(this._isITransport(t))return this._logger.log(Ee.Debug,"Connection was provided an instance of ITransport, using that directly."),this.transport=t,await this._startTransport(o,r),void(this.connectionId=n.connectionId);const i=[],s=n.availableTransports||[];let a=n;for(const n of s){const s=this._resolveTransportOrError(n,t,r);if(s instanceof Error)i.push(`${n.transport} failed: ${s}`);else if(this._isITransport(s)){if(this.transport=s,!a){try{a=await this._getNegotiationResponse(e)}catch(e){return Promise.reject(e)}o=this._createConnectUrl(e,a.connectionToken)}try{return await this._startTransport(o,r),void(this.connectionId=a.connectionId)}catch(e){if(this._logger.log(Ee.Error,`Failed to start the transport '${n.transport}': ${e}`),a=void 0,i.push(`${n.transport} failed: ${e}`),"Connecting"!==this._connectionState){const e="Failed to select transport before stop() was called.";return this._logger.log(Ee.Debug,e),Promise.reject(new Error(e))}}}}return i.length>0?Promise.reject(new Error(`Unable to connect to the server with any of the available transports. ${i.join(" ")}`)):Promise.reject(new Error("None of the transports supported by the client are supported by the server."))}_constructTransport(e){switch(e){case Se.WebSockets:if(!this._options.WebSocket)throw new Error("'WebSocket' is not supported in your environment.");return new Ke(this._httpClient,this._accessTokenFactory,this._logger,this._options.logMessageContent||!1,this._options.WebSocket,this._options.headers||{});case Se.ServerSentEvents:if(!this._options.EventSource)throw new Error("'EventSource' is not supported in your environment.");return new Je(this._httpClient,this._accessTokenFactory,this._logger,this._options.logMessageContent||!1,this._options.EventSource,this._options.withCredentials,this._options.headers||{});case Se.LongPolling:return new qe(this._httpClient,this._accessTokenFactory,this._logger,this._options.logMessageContent||!1,this._options.withCredentials,this._options.headers||{});default:throw new Error(`Unknown transport: ${e}.`)}}_startTransport(e,t){return this.transport.onreceive=this.onreceive,this.transport.onclose=e=>this._stopConnection(e),this.transport.connect(e,t)}_resolveTransportOrError(e,t,n){const r=Se[e.transport];if(null==r)return this._logger.log(Ee.Debug,`Skipping transport '${e.transport}' because it is not supported by this client.`),new Error(`Skipping transport '${e.transport}' because it is not supported by this client.`);if(!function(e,t){return!e||0!=(t&e)}(t,r))return this._logger.log(Ee.Debug,`Skipping transport '${Se[r]}' because it was disabled by the client.`),new Error(`'${Se[r]}' is disabled by the client.`);if(!(e.transferFormats.map((e=>Ce[e])).indexOf(n)>=0))return this._logger.log(Ee.Debug,`Skipping transport '${Se[r]}' because it does not support the requested transfer format '${Ce[n]}'.`),new Error(`'${Se[r]}' does not support ${Ce[n]}.`);if(r===Se.WebSockets&&!this._options.WebSocket||r===Se.ServerSentEvents&&!this._options.EventSource)return this._logger.log(Ee.Debug,`Skipping transport '${Se[r]}' because it is not supported in your environment.'`),new Error(`'${Se[r]}' is not supported in your environment.`);this._logger.log(Ee.Debug,`Selecting transport '${Se[r]}'.`);try{return this._constructTransport(r)}catch(e){return e}}_isITransport(e){return e&&"object"==typeof e&&"connect"in e}_stopConnection(e){if(this._logger.log(Ee.Debug,`HttpConnection.stopConnection(${e}) called while in state ${this._connectionState}.`),this.transport=void 0,e=this._stopError||e,this._stopError=void 0,"Disconnected"!==this._connectionState){if("Connecting"===this._connectionState)throw this._logger.log(Ee.Warning,`Call to HttpConnection.stopConnection(${e}) was ignored because the connection is still in the connecting state.`),new Error(`HttpConnection.stopConnection(${e}) was called while the connection is still in the connecting state.`);if("Disconnecting"===this._connectionState&&this._stopPromiseResolver(),e?this._logger.log(Ee.Error,`Connection disconnected with error '${e}'.`):this._logger.log(Ee.Information,"Connection disconnected."),this._sendQueue&&(this._sendQueue.stop().catch((e=>{this._logger.log(Ee.Error,`TransportSendQueue.stop() threw error '${e}'.`)})),this._sendQueue=void 0),this.connectionId=void 0,this._connectionState="Disconnected",this._connectionStarted){this._connectionStarted=!1;try{this.onclose&&this.onclose(e)}catch(t){this._logger.log(Ee.Error,`HttpConnection.onclose(${e}) threw error '${t}'.`)}}}else this._logger.log(Ee.Debug,`Call to HttpConnection.stopConnection(${e}) was ignored because the connection is already in the disconnected state.`)}_resolveUrl(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if(!$e.isBrowser||!window.document)throw new Error(`Cannot resolve '${e}'.`);const t=window.document.createElement("a");return t.href=e,this._logger.log(Ee.Information,`Normalizing '${e}' to '${t.href}'.`),t.href}_resolveNegotiateUrl(e){const t=e.indexOf("?");let n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t),-1===n.indexOf("negotiateVersion")&&(n+=-1===t?"?":"&",n+="negotiateVersion="+this._negotiateVersion),n}}class Xe{constructor(e){this._transport=e,this._buffer=[],this._executing=!0,this._sendBufferedData=new Ye,this._transportResult=new Ye,this._sendLoopPromise=this._sendLoop()}send(e){return this._bufferData(e),this._transportResult||(this._transportResult=new Ye),this._transportResult.promise}stop(){return this._executing=!1,this._sendBufferedData.resolve(),this._sendLoopPromise}_bufferData(e){if(this._buffer.length&&typeof this._buffer[0]!=typeof e)throw new Error(`Expected data to be of type ${typeof this._buffer} but was of type ${typeof e}`);this._buffer.push(e),this._sendBufferedData.resolve()}async _sendLoop(){for(;;){if(await this._sendBufferedData.promise,!this._executing){this._transportResult&&this._transportResult.reject("Connection stopped.");break}this._sendBufferedData=new Ye;const e=this._transportResult;this._transportResult=void 0;const t="string"==typeof this._buffer[0]?this._buffer.join(""):Xe._concatBuffers(this._buffer);this._buffer.length=0;try{await this._transport.send(t),e.resolve()}catch(t){e.reject(t)}}}static _concatBuffers(e){const t=e.map((e=>e.byteLength)).reduce(((e,t)=>e+t)),n=new Uint8Array(t);let r=0;for(const t of e)n.set(new Uint8Array(t),r),r+=t.byteLength;return n.buffer}}class Ye{constructor(){this.promise=new Promise(((e,t)=>[this._resolver,this._rejecter]=[e,t]))}resolve(){this._resolver()}reject(e){this._rejecter(e)}}class Ge{static write(e){return`${e}${Ge.RecordSeparator}`}static parse(e){if(e[e.length-1]!==Ge.RecordSeparator)throw new Error("Message is incomplete.");const t=e.split(Ge.RecordSeparator);return t.pop(),t}}Ge.RecordSeparatorCode=30,Ge.RecordSeparator=String.fromCharCode(Ge.RecordSeparatorCode);class Qe{writeHandshakeRequest(e){return Ge.write(JSON.stringify(e))}parseHandshakeResponse(e){let t,n;if(Me(e)){const r=new Uint8Array(e),o=r.indexOf(Ge.RecordSeparatorCode);if(-1===o)throw new Error("Message is incomplete.");const i=o+1;t=String.fromCharCode.apply(null,Array.prototype.slice.call(r.slice(0,i))),n=r.byteLength>i?r.slice(i).buffer:null}else{const r=e,o=r.indexOf(Ge.RecordSeparator);if(-1===o)throw new Error("Message is incomplete.");const i=o+1;t=r.substring(0,i),n=r.length>i?r.substring(i):null}const r=Ge.parse(t),o=JSON.parse(r[0]);if(o.type)throw new Error("Expected a handshake response from the server.");return[n,o]}}!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(Ie||(Ie={}));class Ze{constructor(){this.observers=[]}next(e){for(const t of this.observers)t.next(e)}error(e){for(const t of this.observers)t.error&&t.error(e)}complete(){for(const e of this.observers)e.complete&&e.complete()}subscribe(e){return this.observers.push(e),new He(this,e)}}!function(e){e.Disconnected="Disconnected",e.Connecting="Connecting",e.Connected="Connected",e.Disconnecting="Disconnecting",e.Reconnecting="Reconnecting"}(ke||(ke={}));class et{constructor(e,t,n,r){this._nextKeepAlive=0,Ne.isRequired(e,"connection"),Ne.isRequired(t,"logger"),Ne.isRequired(n,"protocol"),this.serverTimeoutInMilliseconds=3e4,this.keepAliveIntervalInMilliseconds=15e3,this._logger=t,this._protocol=n,this.connection=e,this._reconnectPolicy=r,this._handshakeProtocol=new Qe,this.connection.onreceive=e=>this._processIncomingData(e),this.connection.onclose=e=>this._connectionClosed(e),this._callbacks={},this._methods={},this._closedCallbacks=[],this._reconnectingCallbacks=[],this._reconnectedCallbacks=[],this._invocationId=0,this._receivedHandshakeResponse=!1,this._connectionState=ke.Disconnected,this._connectionStarted=!1,this._cachedPingMessage=this._protocol.writeMessage({type:Ie.Ping})}static create(e,t,n,r){return new et(e,t,n,r)}get state(){return this._connectionState}get connectionId(){return this.connection&&this.connection.connectionId||null}get baseUrl(){return this.connection.baseUrl||""}set baseUrl(e){if(this._connectionState!==ke.Disconnected&&this._connectionState!==ke.Reconnecting)throw new Error("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");if(!e)throw new Error("The HubConnection url must be a valid url.");this.connection.baseUrl=e}start(){return this._startPromise=this._startWithStateTransitions(),this._startPromise}async _startWithStateTransitions(){if(this._connectionState!==ke.Disconnected)return Promise.reject(new Error("Cannot start a HubConnection that is not in the 'Disconnected' state."));this._connectionState=ke.Connecting,this._logger.log(Ee.Debug,"Starting HubConnection.");try{await this._startInternal(),this._connectionState=ke.Connected,this._connectionStarted=!0,this._logger.log(Ee.Debug,"HubConnection connected successfully.")}catch(e){return this._connectionState=ke.Disconnected,this._logger.log(Ee.Debug,`HubConnection failed to start successfully because of error '${e}'.`),Promise.reject(e)}}async _startInternal(){this._stopDuringStartError=void 0,this._receivedHandshakeResponse=!1;const e=new Promise(((e,t)=>{this._handshakeResolver=e,this._handshakeRejecter=t}));await this.connection.start(this._protocol.transferFormat);try{const t={protocol:this._protocol.name,version:this._protocol.version};if(this._logger.log(Ee.Debug,"Sending handshake request."),await this._sendMessage(this._handshakeProtocol.writeHandshakeRequest(t)),this._logger.log(Ee.Information,`Using HubProtocol '${this._protocol.name}'.`),this._cleanupTimeout(),this._resetTimeoutPeriod(),this._resetKeepAliveInterval(),await e,this._stopDuringStartError)throw this._stopDuringStartError}catch(e){throw this._logger.log(Ee.Debug,`Hub handshake failed with error '${e}' during start(). Stopping HubConnection.`),this._cleanupTimeout(),this._cleanupPingTimer(),await this.connection.stop(e),e}}async stop(){const e=this._startPromise;this._stopPromise=this._stopInternal(),await this._stopPromise;try{await e}catch(e){}}_stopInternal(e){return this._connectionState===ke.Disconnected?(this._logger.log(Ee.Debug,`Call to HubConnection.stop(${e}) ignored because it is already in the disconnected state.`),Promise.resolve()):this._connectionState===ke.Disconnecting?(this._logger.log(Ee.Debug,`Call to HttpConnection.stop(${e}) ignored because the connection is already in the disconnecting state.`),this._stopPromise):(this._connectionState=ke.Disconnecting,this._logger.log(Ee.Debug,"Stopping HubConnection."),this._reconnectDelayHandle?(this._logger.log(Ee.Debug,"Connection stopped during reconnect delay. Done reconnecting."),clearTimeout(this._reconnectDelayHandle),this._reconnectDelayHandle=void 0,this._completeClose(),Promise.resolve()):(this._cleanupTimeout(),this._cleanupPingTimer(),this._stopDuringStartError=e||new Error("The connection was stopped before the hub handshake could complete."),this.connection.stop(e)))}stream(e,...t){const[n,r]=this._replaceStreamingParams(t),o=this._createStreamInvocation(e,t,r);let i;const s=new Ze;return s.cancelCallback=()=>{const e=this._createCancelInvocation(o.invocationId);return delete this._callbacks[o.invocationId],i.then((()=>this._sendWithProtocol(e)))},this._callbacks[o.invocationId]=(e,t)=>{t?s.error(t):e&&(e.type===Ie.Completion?e.error?s.error(new Error(e.error)):s.complete():s.next(e.item))},i=this._sendWithProtocol(o).catch((e=>{s.error(e),delete this._callbacks[o.invocationId]})),this._launchStreams(n,i),s}_sendMessage(e){return this._resetKeepAliveInterval(),this.connection.send(e)}_sendWithProtocol(e){return this._sendMessage(this._protocol.writeMessage(e))}send(e,...t){const[n,r]=this._replaceStreamingParams(t),o=this._sendWithProtocol(this._createInvocation(e,t,!0,r));return this._launchStreams(n,o),o}invoke(e,...t){const[n,r]=this._replaceStreamingParams(t),o=this._createInvocation(e,t,!1,r);return new Promise(((e,t)=>{this._callbacks[o.invocationId]=(n,r)=>{r?t(r):n&&(n.type===Ie.Completion?n.error?t(new Error(n.error)):e(n.result):t(new Error(`Unexpected message type: ${n.type}`)))};const r=this._sendWithProtocol(o).catch((e=>{t(e),delete this._callbacks[o.invocationId]}));this._launchStreams(n,r)}))}on(e,t){e&&t&&(e=e.toLowerCase(),this._methods[e]||(this._methods[e]=[]),-1===this._methods[e].indexOf(t)&&this._methods[e].push(t))}off(e,t){if(!e)return;e=e.toLowerCase();const n=this._methods[e];if(n)if(t){const r=n.indexOf(t);-1!==r&&(n.splice(r,1),0===n.length&&delete this._methods[e])}else delete this._methods[e]}onclose(e){e&&this._closedCallbacks.push(e)}onreconnecting(e){e&&this._reconnectingCallbacks.push(e)}onreconnected(e){e&&this._reconnectedCallbacks.push(e)}_processIncomingData(e){if(this._cleanupTimeout(),this._receivedHandshakeResponse||(e=this._processHandshakeResponse(e),this._receivedHandshakeResponse=!0),e){const t=this._protocol.parseMessages(e,this._logger);for(const e of t)switch(e.type){case Ie.Invocation:this._invokeClientMethod(e);break;case Ie.StreamItem:case Ie.Completion:{const t=this._callbacks[e.invocationId];t&&(e.type===Ie.Completion&&delete this._callbacks[e.invocationId],t(e));break}case Ie.Ping:break;case Ie.Close:{this._logger.log(Ee.Information,"Close message received from server.");const t=e.error?new Error("Server returned an error on close: "+e.error):void 0;!0===e.allowReconnect?this.connection.stop(t):this._stopPromise=this._stopInternal(t);break}default:this._logger.log(Ee.Warning,`Invalid message type: ${e.type}.`)}}this._resetTimeoutPeriod()}_processHandshakeResponse(e){let t,n;try{[n,t]=this._handshakeProtocol.parseHandshakeResponse(e)}catch(e){const t="Error parsing handshake response: "+e;this._logger.log(Ee.Error,t);const n=new Error(t);throw this._handshakeRejecter(n),n}if(t.error){const e="Server returned handshake error: "+t.error;this._logger.log(Ee.Error,e);const n=new Error(e);throw this._handshakeRejecter(n),n}return this._logger.log(Ee.Debug,"Server handshake complete."),this._handshakeResolver(),n}_resetKeepAliveInterval(){this.connection.features.inherentKeepAlive||(this._nextKeepAlive=(new Date).getTime()+this.keepAliveIntervalInMilliseconds,this._cleanupPingTimer())}_resetTimeoutPeriod(){if(!(this.connection.features&&this.connection.features.inherentKeepAlive||(this._timeoutHandle=setTimeout((()=>this.serverTimeout()),this.serverTimeoutInMilliseconds),void 0!==this._pingServerHandle))){let e=this._nextKeepAlive-(new Date).getTime();e<0&&(e=0),this._pingServerHandle=setTimeout((async()=>{if(this._connectionState===ke.Connected)try{await this._sendMessage(this._cachedPingMessage)}catch{this._cleanupPingTimer()}}),e)}}serverTimeout(){this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."))}_invokeClientMethod(e){const t=this._methods[e.target.toLowerCase()];if(t){try{t.forEach((t=>t.apply(this,e.arguments)))}catch(t){this._logger.log(Ee.Error,`A callback for the method ${e.target.toLowerCase()} threw error '${t}'.`)}if(e.invocationId){const e="Server requested a response, which is not supported in this version of the client.";this._logger.log(Ee.Error,e),this._stopPromise=this._stopInternal(new Error(e))}}else this._logger.log(Ee.Warning,`No client method with the name '${e.target}' found.`)}_connectionClosed(e){this._logger.log(Ee.Debug,`HubConnection.connectionClosed(${e}) called while in state ${this._connectionState}.`),this._stopDuringStartError=this._stopDuringStartError||e||new Error("The underlying connection was closed before the hub handshake could complete."),this._handshakeResolver&&this._handshakeResolver(),this._cancelCallbacksWithError(e||new Error("Invocation canceled due to the underlying connection being closed.")),this._cleanupTimeout(),this._cleanupPingTimer(),this._connectionState===ke.Disconnecting?this._completeClose(e):this._connectionState===ke.Connected&&this._reconnectPolicy?this._reconnect(e):this._connectionState===ke.Connected&&this._completeClose(e)}_completeClose(e){if(this._connectionStarted){this._connectionState=ke.Disconnected,this._connectionStarted=!1;try{this._closedCallbacks.forEach((t=>t.apply(this,[e])))}catch(t){this._logger.log(Ee.Error,`An onclose callback called with error '${e}' threw error '${t}'.`)}}}async _reconnect(e){const t=Date.now();let n=0,r=void 0!==e?e:new Error("Attempting to reconnect due to a unknown error."),o=this._getNextRetryDelay(n++,0,r);if(null===o)return this._logger.log(Ee.Debug,"Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt."),void this._completeClose(e);if(this._connectionState=ke.Reconnecting,e?this._logger.log(Ee.Information,`Connection reconnecting because of error '${e}'.`):this._logger.log(Ee.Information,"Connection reconnecting."),0!==this._reconnectingCallbacks.length){try{this._reconnectingCallbacks.forEach((t=>t.apply(this,[e])))}catch(t){this._logger.log(Ee.Error,`An onreconnecting callback called with error '${e}' threw error '${t}'.`)}if(this._connectionState!==ke.Reconnecting)return void this._logger.log(Ee.Debug,"Connection left the reconnecting state in onreconnecting callback. Done reconnecting.")}for(;null!==o;){if(this._logger.log(Ee.Information,`Reconnect attempt number ${n} will start in ${o} ms.`),await new Promise((e=>{this._reconnectDelayHandle=setTimeout(e,o)})),this._reconnectDelayHandle=void 0,this._connectionState!==ke.Reconnecting)return void this._logger.log(Ee.Debug,"Connection left the reconnecting state during reconnect delay. Done reconnecting.");try{if(await this._startInternal(),this._connectionState=ke.Connected,this._logger.log(Ee.Information,"HubConnection reconnected successfully."),0!==this._reconnectedCallbacks.length)try{this._reconnectedCallbacks.forEach((e=>e.apply(this,[this.connection.connectionId])))}catch(e){this._logger.log(Ee.Error,`An onreconnected callback called with connectionId '${this.connection.connectionId}; threw error '${e}'.`)}return}catch(e){if(this._logger.log(Ee.Information,`Reconnect attempt failed because of error '${e}'.`),this._connectionState!==ke.Reconnecting)return this._logger.log(Ee.Debug,`Connection moved to the '${this._connectionState}' from the reconnecting state during reconnect attempt. Done reconnecting.`),void(this._connectionState===ke.Disconnecting&&this._completeClose());r=e instanceof Error?e:new Error(e.toString()),o=this._getNextRetryDelay(n++,Date.now()-t,r)}}this._logger.log(Ee.Information,`Reconnect retries have been exhausted after ${Date.now()-t} ms and ${n} failed attempts. Connection disconnecting.`),this._completeClose()}_getNextRetryDelay(e,t,n){try{return this._reconnectPolicy.nextRetryDelayInMilliseconds({elapsedMilliseconds:t,previousRetryCount:e,retryReason:n})}catch(n){return this._logger.log(Ee.Error,`IRetryPolicy.nextRetryDelayInMilliseconds(${e}, ${t}) threw error '${n}'.`),null}}_cancelCallbacksWithError(e){const t=this._callbacks;this._callbacks={},Object.keys(t).forEach((n=>{(0,t[n])(null,e)}))}_cleanupPingTimer(){this._pingServerHandle&&(clearTimeout(this._pingServerHandle),this._pingServerHandle=void 0)}_cleanupTimeout(){this._timeoutHandle&&clearTimeout(this._timeoutHandle)}_createInvocation(e,t,n,r){if(n)return 0!==r.length?{arguments:t,streamIds:r,target:e,type:Ie.Invocation}:{arguments:t,target:e,type:Ie.Invocation};{const n=this._invocationId;return this._invocationId++,0!==r.length?{arguments:t,invocationId:n.toString(),streamIds:r,target:e,type:Ie.Invocation}:{arguments:t,invocationId:n.toString(),target:e,type:Ie.Invocation}}}_launchStreams(e,t){if(0!==e.length){t||(t=Promise.resolve());for(const n in e)e[n].subscribe({complete:()=>{t=t.then((()=>this._sendWithProtocol(this._createCompletionMessage(n))))},error:e=>{let r;r=e instanceof Error?e.message:e&&e.toString?e.toString():"Unknown error",t=t.then((()=>this._sendWithProtocol(this._createCompletionMessage(n,r))))},next:e=>{t=t.then((()=>this._sendWithProtocol(this._createStreamItemMessage(n,e))))}})}}_replaceStreamingParams(e){const t=[],n=[];for(let r=0;r=55296&&o<=56319&&r65535&&(h-=65536,i.push(h>>>10&1023|55296),h=56320|1023&h),i.push(h)}else i.push(a);i.length>=4096&&(s+=String.fromCharCode.apply(String,i),i.length=0)}return i.length>0&&(s+=String.fromCharCode.apply(String,i)),s}var ut=ot?new TextDecoder:null,dt=ot?"undefined"!=typeof process&&"force"!==process.env.TEXT_DECODER?200:0:it,pt=function(e,t){this.type=e,this.data=t};function ft(e,t,n){var r=Math.floor(n/4294967296),o=n;e.setUint32(t,r),e.setUint32(t+4,o)}function gt(e,t){return 4294967296*e.getInt32(t)+e.getUint32(t+4)}var mt={type:-1,encode:function(e){var t,n,r,o;return e instanceof Date?function(e){var t,n=e.sec,r=e.nsec;if(n>=0&&r>=0&&n<=17179869183){if(0===r&&n<=4294967295){var o=new Uint8Array(4);return(t=new DataView(o.buffer)).setUint32(0,n),o}var i=n/4294967296,s=4294967295&n;return o=new Uint8Array(8),(t=new DataView(o.buffer)).setUint32(0,r<<2|3&i),t.setUint32(4,s),o}return o=new Uint8Array(12),(t=new DataView(o.buffer)).setUint32(0,r),ft(t,4,n),o}((r=1e6*((t=e.getTime())-1e3*(n=Math.floor(t/1e3))),{sec:n+(o=Math.floor(r/1e9)),nsec:r-1e9*o})):null},decode:function(e){var t=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);switch(e.byteLength){case 4:return{sec:t.getUint32(0),nsec:0};case 8:var n=t.getUint32(0);return{sec:4294967296*(3&n)+t.getUint32(4),nsec:n>>>2};case 12:return{sec:gt(t,4),nsec:t.getUint32(0)};default:throw new Error("Unrecognized data size for timestamp: "+e.length)}}(e);return new Date(1e3*t.sec+t.nsec/1e6)}},yt=function(){function e(){this.builtInEncoders=[],this.builtInDecoders=[],this.encoders=[],this.decoders=[],this.register(mt)}return e.prototype.register=function(e){var t=e.type,n=e.encode,r=e.decode;if(t>=0)this.encoders[t]=n,this.decoders[t]=r;else{var o=1+t;this.builtInEncoders[o]=n,this.builtInDecoders[o]=r}},e.prototype.tryToEncode=function(e,t){for(var n=0;nthis.maxDepth)throw new Error("Too deep objects in depth "+t);null==e?this.encodeNil():"boolean"==typeof e?this.encodeBoolean(e):"number"==typeof e?this.encodeNumber(e):"string"==typeof e?this.encodeString(e):this.encodeObject(e,t)},e.prototype.ensureBufferSizeToWrite=function(e){var t=this.pos+e;this.view.byteLength=0?e<128?this.writeU8(e):e<256?(this.writeU8(204),this.writeU8(e)):e<65536?(this.writeU8(205),this.writeU16(e)):e<4294967296?(this.writeU8(206),this.writeU32(e)):(this.writeU8(207),this.writeU64(e)):e>=-32?this.writeU8(224|e+32):e>=-128?(this.writeU8(208),this.writeI8(e)):e>=-32768?(this.writeU8(209),this.writeI16(e)):e>=-2147483648?(this.writeU8(210),this.writeI32(e)):(this.writeU8(211),this.writeI64(e)):this.forceFloat32?(this.writeU8(202),this.writeF32(e)):(this.writeU8(203),this.writeF64(e))},e.prototype.writeStringHeader=function(e){if(e<32)this.writeU8(160+e);else if(e<256)this.writeU8(217),this.writeU8(e);else if(e<65536)this.writeU8(218),this.writeU16(e);else{if(!(e<4294967296))throw new Error("Too long string: "+e+" bytes in UTF-8");this.writeU8(219),this.writeU32(e)}},e.prototype.encodeString=function(e){if(e.length>ct){var t=st(e);this.ensureBufferSizeToWrite(5+t),this.writeStringHeader(t),lt(e,this.bytes,this.pos),this.pos+=t}else t=st(e),this.ensureBufferSizeToWrite(5+t),this.writeStringHeader(t),function(e,t,n){for(var r=e.length,o=n,i=0;i>6&31|192;else{if(s>=55296&&s<=56319&&i>12&15|224,t[o++]=s>>6&63|128):(t[o++]=s>>18&7|240,t[o++]=s>>12&63|128,t[o++]=s>>6&63|128)}t[o++]=63&s|128}else t[o++]=s}}(e,this.bytes,this.pos),this.pos+=t},e.prototype.encodeObject=function(e,t){var n=this.extensionCodec.tryToEncode(e,this.context);if(null!=n)this.encodeExtension(n);else if(Array.isArray(e))this.encodeArray(e,t);else if(ArrayBuffer.isView(e))this.encodeBinary(e);else{if("object"!=typeof e)throw new Error("Unrecognized object: "+Object.prototype.toString.apply(e));this.encodeMap(e,t)}},e.prototype.encodeBinary=function(e){var t=e.byteLength;if(t<256)this.writeU8(196),this.writeU8(t);else if(t<65536)this.writeU8(197),this.writeU16(t);else{if(!(t<4294967296))throw new Error("Too large binary: "+t);this.writeU8(198),this.writeU32(t)}var n=wt(e);this.writeU8a(n)},e.prototype.encodeArray=function(e,t){var n=e.length;if(n<16)this.writeU8(144+n);else if(n<65536)this.writeU8(220),this.writeU16(n);else{if(!(n<4294967296))throw new Error("Too large array: "+n);this.writeU8(221),this.writeU32(n)}for(var r=0,o=e;r0&&e<=this.maxKeyLength},e.prototype.find=function(e,t,n){e:for(var r=0,o=this.caches[n-1];r=this.maxLengthPerKey?n[Math.random()*n.length|0]=r:n.push(r)},e.prototype.decode=function(e,t,n){var r=this.find(e,t,n);if(null!=r)return this.hit++,r;this.miss++;var o=ht(e,t,n),i=Uint8Array.prototype.slice.call(e,t,t+n);return this.store(i,o),o},e}(),St=(_t=function(e,t){return(_t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}_t(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),Ct=function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!((o=(o=s.trys).length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]1||a(e,t)}))})}function a(e,t){try{(n=o[e](t)).value instanceof kt?Promise.resolve(n.value.v).then(c,l):h(i[0][2],n)}catch(e){h(i[0][3],e)}var n}function c(e){a("next",e)}function l(e){a("throw",e)}function h(e,t){e(t),i.shift(),i.length&&a(i[0][0],i[0][1])}},xt=new DataView(new ArrayBuffer(0)),Dt=new Uint8Array(xt.buffer),Rt=function(){try{xt.getInt8(0)}catch(e){return e.constructor}throw new Error("never reached")}(),Pt=new Rt("Insufficient data"),Ut=4294967295,At=new Et,Nt=function(e){function t(n){var r=e.call(this,n)||this,o=Object.create(t.prototype);return Object.setPrototypeOf(r,o),Object.defineProperty(r,"name",{configurable:!0,enumerable:!1,value:t.name}),r}return St(t,e),t}(Error),$t=function(){function e(e,t,n,r,o,i,s,a){void 0===e&&(e=yt.defaultCodec),void 0===t&&(t=void 0),void 0===n&&(n=Ut),void 0===r&&(r=Ut),void 0===o&&(o=Ut),void 0===i&&(i=Ut),void 0===s&&(s=Ut),void 0===a&&(a=At),this.extensionCodec=e,this.context=t,this.maxStrLength=n,this.maxBinLength=r,this.maxArrayLength=o,this.maxMapLength=i,this.maxExtLength=s,this.keyDecoder=a,this.totalPos=0,this.pos=0,this.view=xt,this.bytes=Dt,this.headByte=-1,this.stack=[]}return e.prototype.reinitializeState=function(){this.totalPos=0,this.headByte=-1,this.stack.length=0},e.prototype.setBuffer=function(e){this.bytes=wt(e),this.view=function(e){if(e instanceof ArrayBuffer)return new DataView(e);var t=wt(e);return new DataView(t.buffer,t.byteOffset,t.byteLength)}(this.bytes),this.pos=0},e.prototype.appendBuffer=function(e){if(-1!==this.headByte||this.hasRemaining()){var t=this.bytes.subarray(this.pos),n=wt(e),r=new Uint8Array(t.length+n.length);r.set(t),r.set(n,t.length),this.setBuffer(r)}else this.setBuffer(e)},e.prototype.hasRemaining=function(e){return void 0===e&&(e=1),this.view.byteLength-this.pos>=e},e.prototype.createExtraByteError=function(e){var t=this.view,n=this.pos;return new RangeError("Extra "+(t.byteLength-n)+" of "+t.byteLength+" byte(s) found at buffer["+e+"]")},e.prototype.decode=function(e){this.reinitializeState(),this.setBuffer(e);var t=this.doDecodeSync();if(this.hasRemaining())throw this.createExtraByteError(this.pos);return t},e.prototype.decodeMulti=function(e){return Ct(this,(function(t){switch(t.label){case 0:this.reinitializeState(),this.setBuffer(e),t.label=1;case 1:return this.hasRemaining()?[4,this.doDecodeSync()]:[3,3];case 2:return t.sent(),[3,1];case 3:return[2]}}))},e.prototype.decodeAsync=function(e){var t,n,r,o,i,s,a;return i=this,void 0,a=function(){var i,s,a,c,l,h,u,d;return Ct(this,(function(p){switch(p.label){case 0:i=!1,p.label=1;case 1:p.trys.push([1,6,7,12]),t=It(e),p.label=2;case 2:return[4,t.next()];case 3:if((n=p.sent()).done)return[3,5];if(a=n.value,i)throw this.createExtraByteError(this.totalPos);this.appendBuffer(a);try{s=this.doDecodeSync(),i=!0}catch(e){if(!(e instanceof Rt))throw e}this.totalPos+=this.pos,p.label=4;case 4:return[3,2];case 5:return[3,12];case 6:return c=p.sent(),r={error:c},[3,12];case 7:return p.trys.push([7,,10,11]),n&&!n.done&&(o=t.return)?[4,o.call(t)]:[3,9];case 8:p.sent(),p.label=9;case 9:return[3,11];case 10:if(r)throw r.error;return[7];case 11:return[7];case 12:if(i){if(this.hasRemaining())throw this.createExtraByteError(this.totalPos);return[2,s]}throw h=(l=this).headByte,u=l.pos,d=l.totalPos,new RangeError("Insufficient data in parsing "+bt(h)+" at "+d+" ("+u+" in the current buffer)")}}))},new((s=void 0)||(s=Promise))((function(e,t){function n(e){try{o(a.next(e))}catch(e){t(e)}}function r(e){try{o(a.throw(e))}catch(e){t(e)}}function o(t){var o;t.done?e(t.value):(o=t.value,o instanceof s?o:new s((function(e){e(o)}))).then(n,r)}o((a=a.apply(i,[])).next())}))},e.prototype.decodeArrayStream=function(e){return this.decodeMultiAsync(e,!0)},e.prototype.decodeStream=function(e){return this.decodeMultiAsync(e,!1)},e.prototype.decodeMultiAsync=function(e,t){return Tt(this,arguments,(function(){var n,r,o,i,s,a,c,l,h;return Ct(this,(function(u){switch(u.label){case 0:n=t,r=-1,u.label=1;case 1:u.trys.push([1,13,14,19]),o=It(e),u.label=2;case 2:return[4,kt(o.next())];case 3:if((i=u.sent()).done)return[3,12];if(s=i.value,t&&0===r)throw this.createExtraByteError(this.totalPos);this.appendBuffer(s),n&&(r=this.readArraySize(),n=!1,this.complete()),u.label=4;case 4:u.trys.push([4,9,,10]),u.label=5;case 5:return[4,kt(this.doDecodeSync())];case 6:return[4,u.sent()];case 7:return u.sent(),0==--r?[3,8]:[3,5];case 8:return[3,10];case 9:if(!((a=u.sent())instanceof Rt))throw a;return[3,10];case 10:this.totalPos+=this.pos,u.label=11;case 11:return[3,2];case 12:return[3,19];case 13:return c=u.sent(),l={error:c},[3,19];case 14:return u.trys.push([14,,17,18]),i&&!i.done&&(h=o.return)?[4,kt(h.call(o))]:[3,16];case 15:u.sent(),u.label=16;case 16:return[3,18];case 17:if(l)throw l.error;return[7];case 18:return[7];case 19:return[2]}}))}))},e.prototype.doDecodeSync=function(){e:for(;;){var e=this.readHeadByte(),t=void 0;if(e>=224)t=e-256;else if(e<192)if(e<128)t=e;else if(e<144){if(0!=(r=e-128)){this.pushMapState(r),this.complete();continue e}t={}}else if(e<160){if(0!=(r=e-144)){this.pushArrayState(r),this.complete();continue e}t=[]}else{var n=e-160;t=this.decodeUtf8String(n,0)}else if(192===e)t=null;else if(194===e)t=!1;else if(195===e)t=!0;else if(202===e)t=this.readF32();else if(203===e)t=this.readF64();else if(204===e)t=this.readU8();else if(205===e)t=this.readU16();else if(206===e)t=this.readU32();else if(207===e)t=this.readU64();else if(208===e)t=this.readI8();else if(209===e)t=this.readI16();else if(210===e)t=this.readI32();else if(211===e)t=this.readI64();else if(217===e)n=this.lookU8(),t=this.decodeUtf8String(n,1);else if(218===e)n=this.lookU16(),t=this.decodeUtf8String(n,2);else if(219===e)n=this.lookU32(),t=this.decodeUtf8String(n,4);else if(220===e){if(0!==(r=this.readU16())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(221===e){if(0!==(r=this.readU32())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(222===e){if(0!==(r=this.readU16())){this.pushMapState(r),this.complete();continue e}t={}}else if(223===e){if(0!==(r=this.readU32())){this.pushMapState(r),this.complete();continue e}t={}}else if(196===e){var r=this.lookU8();t=this.decodeBinary(r,1)}else if(197===e)r=this.lookU16(),t=this.decodeBinary(r,2);else if(198===e)r=this.lookU32(),t=this.decodeBinary(r,4);else if(212===e)t=this.decodeExtension(1,0);else if(213===e)t=this.decodeExtension(2,0);else if(214===e)t=this.decodeExtension(4,0);else if(215===e)t=this.decodeExtension(8,0);else if(216===e)t=this.decodeExtension(16,0);else if(199===e)r=this.lookU8(),t=this.decodeExtension(r,1);else if(200===e)r=this.lookU16(),t=this.decodeExtension(r,2);else{if(201!==e)throw new Nt("Unrecognized type byte: "+bt(e));r=this.lookU32(),t=this.decodeExtension(r,4)}this.complete();for(var o=this.stack;o.length>0;){var i=o[o.length-1];if(0===i.type){if(i.array[i.position]=t,i.position++,i.position!==i.size)continue e;o.pop(),t=i.array}else{if(1===i.type){if("string"!=(s=typeof t)&&"number"!==s)throw new Nt("The type of key must be string or number but "+typeof t);if("__proto__"===t)throw new Nt("The key __proto__ is not allowed");i.key=t,i.type=2;continue e}if(i.map[i.key]=t,i.readCount++,i.readCount!==i.size){i.key=null,i.type=1;continue e}o.pop(),t=i.map}}return t}var s},e.prototype.readHeadByte=function(){return-1===this.headByte&&(this.headByte=this.readU8()),this.headByte},e.prototype.complete=function(){this.headByte=-1},e.prototype.readArraySize=function(){var e=this.readHeadByte();switch(e){case 220:return this.readU16();case 221:return this.readU32();default:if(e<160)return e-144;throw new Nt("Unrecognized array type byte: "+bt(e))}},e.prototype.pushMapState=function(e){if(e>this.maxMapLength)throw new Nt("Max length exceeded: map length ("+e+") > maxMapLengthLength ("+this.maxMapLength+")");this.stack.push({type:1,size:e,key:null,readCount:0,map:{}})},e.prototype.pushArrayState=function(e){if(e>this.maxArrayLength)throw new Nt("Max length exceeded: array length ("+e+") > maxArrayLength ("+this.maxArrayLength+")");this.stack.push({type:0,size:e,array:new Array(e),position:0})},e.prototype.decodeUtf8String=function(e,t){var n;if(e>this.maxStrLength)throw new Nt("Max length exceeded: UTF-8 byte length ("+e+") > maxStrLength ("+this.maxStrLength+")");if(this.bytes.byteLengthdt?function(e,t,n){var r=e.subarray(t,t+n);return ut.decode(r)}(this.bytes,o,e):ht(this.bytes,o,e),this.pos+=t+e,r},e.prototype.stateIsMapKey=function(){return this.stack.length>0&&1===this.stack[this.stack.length-1].type},e.prototype.decodeBinary=function(e,t){if(e>this.maxBinLength)throw new Nt("Max length exceeded: bin length ("+e+") > maxBinLength ("+this.maxBinLength+")");if(!this.hasRemaining(e+t))throw Pt;var n=this.pos+t,r=this.bytes.subarray(n,n+e);return this.pos+=t+e,r},e.prototype.decodeExtension=function(e,t){if(e>this.maxExtLength)throw new Nt("Max length exceeded: ext length ("+e+") > maxExtLength ("+this.maxExtLength+")");var n=this.view.getInt8(this.pos+t),r=this.decodeBinary(e,t+1);return this.extensionCodec.decode(r,n,this.context)},e.prototype.lookU8=function(){return this.view.getUint8(this.pos)},e.prototype.lookU16=function(){return this.view.getUint16(this.pos)},e.prototype.lookU32=function(){return this.view.getUint32(this.pos)},e.prototype.readU8=function(){var e=this.view.getUint8(this.pos);return this.pos++,e},e.prototype.readI8=function(){var e=this.view.getInt8(this.pos);return this.pos++,e},e.prototype.readU16=function(){var e=this.view.getUint16(this.pos);return this.pos+=2,e},e.prototype.readI16=function(){var e=this.view.getInt16(this.pos);return this.pos+=2,e},e.prototype.readU32=function(){var e=this.view.getUint32(this.pos);return this.pos+=4,e},e.prototype.readI32=function(){var e=this.view.getInt32(this.pos);return this.pos+=4,e},e.prototype.readU64=function(){var e,t,n=(e=this.view,t=this.pos,4294967296*e.getUint32(t)+e.getUint32(t+4));return this.pos+=8,n},e.prototype.readI64=function(){var e=gt(this.view,this.pos);return this.pos+=8,e},e.prototype.readF32=function(){var e=this.view.getFloat32(this.pos);return this.pos+=4,e},e.prototype.readF64=function(){var e=this.view.getFloat64(this.pos);return this.pos+=8,e},e}();class Bt{static write(e){let t=e.byteLength||e.length;const n=[];do{let e=127&t;t>>=7,t>0&&(e|=128),n.push(e)}while(t>0);t=e.byteLength||e.length;const r=new Uint8Array(n.length+t);return r.set(n,0),r.set(e,n.length),r.buffer}static parse(e){const t=[],n=new Uint8Array(e),r=[0,7,14,21,28];for(let o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+s+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+s,o+s+a):n.subarray(o+s,o+s+a)),o=o+s+a}return t}}const Mt=new Uint8Array([145,Ie.Ping]);class Lt{constructor(e){this.name="messagepack",this.version=1,this.transferFormat=Ce.Binary,this._errorResult=1,this._voidResult=2,this._nonVoidResult=3,e=e||{},this._encoder=new vt(e.extensionCodec,e.context,e.maxDepth,e.initialBufferSize,e.sortKeys,e.forceFloat32,e.ignoreUndefined,e.forceIntegerToFloat),this._decoder=new $t(e.extensionCodec,e.context,e.maxStrLength,e.maxBinLength,e.maxArrayLength,e.maxMapLength,e.maxExtLength)}parseMessages(e,t){if(!(n=e)||"undefined"==typeof ArrayBuffer||!(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer.");var n;null===t&&(t=Ae.instance);const r=Bt.parse(e),o=[];for(const e of r){const n=this._parseMessage(e,t);n&&o.push(n)}return o}writeMessage(e){switch(e.type){case Ie.Invocation:return this._writeInvocation(e);case Ie.StreamInvocation:return this._writeStreamInvocation(e);case Ie.StreamItem:return this._writeStreamItem(e);case Ie.Completion:return this._writeCompletion(e);case Ie.Ping:return Bt.write(Mt);case Ie.CancelInvocation:return this._writeCancelInvocation(e);default:throw new Error("Invalid message type.")}}_parseMessage(e,t){if(0===e.length)throw new Error("Invalid payload.");const n=this._decoder.decode(e);if(0===n.length||!(n instanceof Array))throw new Error("Invalid payload.");const r=n[0];switch(r){case Ie.Invocation:return this._createInvocationMessage(this._readHeaders(n),n);case Ie.StreamItem:return this._createStreamItemMessage(this._readHeaders(n),n);case Ie.Completion:return this._createCompletionMessage(this._readHeaders(n),n);case Ie.Ping:return this._createPingMessage(n);case Ie.Close:return this._createCloseMessage(n);default:return t.log(Ee.Information,"Unknown message type '"+r+"' ignored."),null}}_createCloseMessage(e){if(e.length<2)throw new Error("Invalid payload for Close message.");return{allowReconnect:e.length>=3?e[2]:void 0,error:e[1],type:Ie.Close}}_createPingMessage(e){if(e.length<1)throw new Error("Invalid payload for Ping message.");return{type:Ie.Ping}}_createInvocationMessage(e,t){if(t.length<5)throw new Error("Invalid payload for Invocation message.");const n=t[2];return n?{arguments:t[4],headers:e,invocationId:n,streamIds:[],target:t[3],type:Ie.Invocation}:{arguments:t[4],headers:e,streamIds:[],target:t[3],type:Ie.Invocation}}_createStreamItemMessage(e,t){if(t.length<4)throw new Error("Invalid payload for StreamItem message.");return{headers:e,invocationId:t[2],item:t[3],type:Ie.StreamItem}}_createCompletionMessage(e,t){if(t.length<4)throw new Error("Invalid payload for Completion message.");const n=t[3];if(n!==this._voidResult&&t.length<5)throw new Error("Invalid payload for Completion message.");let r,o;switch(n){case this._errorResult:r=t[4];break;case this._nonVoidResult:o=t[4]}return{error:r,headers:e,invocationId:t[2],result:o,type:Ie.Completion}}_writeInvocation(e){let t;return t=e.streamIds?this._encoder.encode([Ie.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments,e.streamIds]):this._encoder.encode([Ie.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments]),Bt.write(t.slice())}_writeStreamInvocation(e){let t;return t=e.streamIds?this._encoder.encode([Ie.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments,e.streamIds]):this._encoder.encode([Ie.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments]),Bt.write(t.slice())}_writeStreamItem(e){const t=this._encoder.encode([Ie.StreamItem,e.headers||{},e.invocationId,e.item]);return Bt.write(t.slice())}_writeCompletion(e){const t=e.error?this._errorResult:e.result?this._nonVoidResult:this._voidResult;let n;switch(t){case this._errorResult:n=this._encoder.encode([Ie.Completion,e.headers||{},e.invocationId,t,e.error]);break;case this._voidResult:n=this._encoder.encode([Ie.Completion,e.headers||{},e.invocationId,t]);break;case this._nonVoidResult:n=this._encoder.encode([Ie.Completion,e.headers||{},e.invocationId,t,e.result])}return Bt.write(n.slice())}_writeCancelInvocation(e){const t=this._encoder.encode([Ie.CancelInvocation,e.headers||{},e.invocationId]);return Bt.write(t.slice())}_readHeaders(e){const t=e[1];if("object"!=typeof t)throw new Error("Invalid headers.");return t}}let Ht=!1;const Ft="function"==typeof TextDecoder?new TextDecoder("utf-8"):null,Ot=Ft?Ft.decode.bind(Ft):function(e){let t=0;const n=e.length,r=[],o=[];for(;t65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")},jt=Math.pow(2,32),Wt=Math.pow(2,21)-1;function zt(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24}function qt(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}function Jt(e,t){const n=qt(e,t+4);if(n>Wt)throw new Error(`Cannot read uint64 with high order part ${n}, because the result would exceed Number.MAX_SAFE_INTEGER.`);return n*jt+qt(e,t)}class Kt{constructor(e){this.batchData=e;const t=new Gt(e);this.arrayRangeReader=new Qt(e),this.arrayBuilderSegmentReader=new Zt(e),this.diffReader=new Vt(e),this.editReader=new Xt(e,t),this.frameReader=new Yt(e,t)}updatedComponents(){return zt(this.batchData,this.batchData.length-20)}referenceFrames(){return zt(this.batchData,this.batchData.length-16)}disposedComponentIds(){return zt(this.batchData,this.batchData.length-12)}disposedEventHandlerIds(){return zt(this.batchData,this.batchData.length-8)}updatedComponentsEntry(e,t){const n=e+4*t;return zt(this.batchData,n)}referenceFramesEntry(e,t){return e+20*t}disposedComponentIdsEntry(e,t){const n=e+4*t;return zt(this.batchData,n)}disposedEventHandlerIdsEntry(e,t){const n=e+8*t;return Jt(this.batchData,n)}}class Vt{constructor(e){this.batchDataUint8=e}componentId(e){return zt(this.batchDataUint8,e)}edits(e){return e+4}editsEntry(e,t){return e+16*t}}class Xt{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}editType(e){return zt(this.batchDataUint8,e)}siblingIndex(e){return zt(this.batchDataUint8,e+4)}newTreeIndex(e){return zt(this.batchDataUint8,e+8)}moveToSiblingIndex(e){return zt(this.batchDataUint8,e+8)}removedAttributeName(e){const t=zt(this.batchDataUint8,e+12);return this.stringReader.readString(t)}}class Yt{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}frameType(e){return zt(this.batchDataUint8,e)}subtreeLength(e){return zt(this.batchDataUint8,e+4)}elementReferenceCaptureId(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}componentId(e){return zt(this.batchDataUint8,e+8)}elementName(e){const t=zt(this.batchDataUint8,e+8);return this.stringReader.readString(t)}textContent(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}markupContent(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeName(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeValue(e){const t=zt(this.batchDataUint8,e+8);return this.stringReader.readString(t)}attributeEventHandlerId(e){return Jt(this.batchDataUint8,e+12)}}class Gt{constructor(e){this.batchDataUint8=e,this.stringTableStartIndex=zt(e,e.length-4)}readString(e){if(-1===e)return null;{const n=zt(this.batchDataUint8,this.stringTableStartIndex+4*e),r=function(e,t){let n=0,r=0;for(let o=0;o<4;o++){const i=e[t+o];if(n|=(127&i)<this.nextBatchId)return this.fatalError?(this.logger.log(en.Debug,`Received a new batch ${e} but errored out on a previous batch ${this.nextBatchId-1}`),void await n.send("OnRenderCompleted",this.nextBatchId-1,this.fatalError.toString())):void this.logger.log(en.Debug,`Waiting for batch ${this.nextBatchId}. Batch ${e} not processed.`);try{this.nextBatchId++,this.logger.log(en.Debug,`Applying batch ${e}.`),function(e,t){const n=Q[e];if(!n)throw new Error(`There is no browser renderer with ID ${e}.`);const r=t.arrayRangeReader,o=t.updatedComponents(),i=r.values(o),s=r.count(o),a=t.referenceFrames(),c=r.values(a),l=t.diffReader;for(let e=0;e=this.minLevel){const n=`[${(new Date).toISOString()}] ${en[e]}: ${t}`;switch(e){case en.Critical:case en.Error:console.error(n);break;case en.Warning:console.warn(n);break;case en.Information:console.info(n);break;default:console.log(n)}}}}class on{constructor(e,t){this.circuitId=void 0,this.components=e,this.applicationState=t}reconnect(e){if(!this.circuitId)throw new Error("Circuit host not initialized.");return e.state!==ke.Connected?Promise.resolve(!1):e.invoke("ConnectCircuit",this.circuitId)}initialize(e){if(this.circuitId)throw new Error(`Circuit host '${this.circuitId}' already initialized.`);this.circuitId=e}async startCircuit(e){if(e.state!==ke.Connected)return!1;const t=await e.invoke("StartCircuit",re.getBaseURI(),re.getLocationHref(),JSON.stringify(this.components.map((e=>e.toRecord()))),this.applicationState||"");return!!t&&(this.initialize(t),!0)}resolveElement(e){const t=Number.parseInt(e);if(Number.isNaN(t))throw new Error(`Invalid sequence number '${e}'.`);return function(e,t){if(!e.parentNode)throw new Error(`Comment not connected to the DOM ${e.textContent}`);const n=e.parentNode,r=k(n,!0),o=A(r);return Array.from(n.childNodes).forEach((e=>o.push(e))),e[C]=r,t&&(e[I]=t,k(t)),k(e)}(this.components[t].start,this.components[t].end)}}const sn={configureSignalR:e=>{},logLevel:en.Warning,reconnectionOptions:{maxRetries:8,retryIntervalMilliseconds:2e4,dialogId:"components-reconnect-modal"}};class an{constructor(e,t,n,r){this.maxRetries=t,this.document=n,this.logger=r,this.addedToDom=!1,this.modal=this.document.createElement("div"),this.modal.id=e,this.maxRetries=t,this.modal.style.cssText=["position: fixed","top: 0","right: 0","bottom: 0","left: 0","z-index: 1050","display: none","overflow: hidden","background-color: #fff","opacity: 0.8","text-align: center","font-weight: bold","transition: visibility 0s linear 500ms"].join(";"),this.modal.innerHTML='

Alternatively, reload

',this.message=this.modal.querySelector("h5"),this.button=this.modal.querySelector("button"),this.reloadParagraph=this.modal.querySelector("p"),this.loader=this.getLoader(),this.message.after(this.loader),this.button.addEventListener("click",(async()=>{this.show();try{await(null==fe?void 0:fe.reconnect)()||this.rejected()}catch(e){this.logger.log(en.Error,e),this.failed()}})),this.reloadParagraph.querySelector("a").addEventListener("click",(()=>location.reload()))}show(){this.addedToDom||(this.addedToDom=!0,this.document.body.appendChild(this.modal)),this.modal.style.display="block",this.loader.style.display="inline-block",this.button.style.display="none",this.reloadParagraph.style.display="none",this.message.textContent="Attempting to reconnect to the server...",this.modal.style.visibility="hidden",setTimeout((()=>{this.modal.style.visibility="visible"}),0)}update(e){this.message.textContent=`Attempting to reconnect to the server: ${e} of ${this.maxRetries}`}hide(){this.modal.style.display="none"}failed(){this.button.style.display="block",this.reloadParagraph.style.display="none",this.loader.style.display="none",this.message.innerHTML="Reconnection failed. Try reloading the page if you're unable to reconnect.",this.message.querySelector("a").addEventListener("click",(()=>location.reload()))}rejected(){this.button.style.display="none",this.reloadParagraph.style.display="none",this.loader.style.display="none",this.message.innerHTML="Could not reconnect to the server. Reload the page to restore functionality.",this.message.querySelector("a").addEventListener("click",(()=>location.reload()))}getLoader(){const e=this.document.createElement("div");return e.style.cssText=["border: 0.3em solid #f3f3f3","border-top: 0.3em solid #3498db","border-radius: 50%","width: 2em","height: 2em","display: inline-block"].join(";"),e.animate([{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],{duration:2e3,iterations:1/0}),e}}class cn{constructor(e,t,n){this.dialog=e,this.maxRetries=t,this.document=n,this.document=n;const r=this.document.getElementById(cn.MaxRetriesId);r&&(r.innerText=this.maxRetries.toString())}show(){this.removeClasses(),this.dialog.classList.add(cn.ShowClassName)}update(e){const t=this.document.getElementById(cn.CurrentAttemptId);t&&(t.innerText=e.toString())}hide(){this.removeClasses(),this.dialog.classList.add(cn.HideClassName)}failed(){this.removeClasses(),this.dialog.classList.add(cn.FailedClassName)}rejected(){this.removeClasses(),this.dialog.classList.add(cn.RejectedClassName)}removeClasses(){this.dialog.classList.remove(cn.ShowClassName,cn.HideClassName,cn.FailedClassName,cn.RejectedClassName)}}cn.ShowClassName="components-reconnect-show",cn.HideClassName="components-reconnect-hide",cn.FailedClassName="components-reconnect-failed",cn.RejectedClassName="components-reconnect-rejected",cn.MaxRetriesId="components-reconnect-max-retries",cn.CurrentAttemptId="components-reconnect-current-attempt";class ln{constructor(e,t,n){this._currentReconnectionProcess=null,this._logger=e,this._reconnectionDisplay=t,this._reconnectCallback=n||(()=>fe.reconnect())}onConnectionDown(e,t){if(!this._reconnectionDisplay){const t=document.getElementById(e.dialogId);this._reconnectionDisplay=t?new cn(t,e.maxRetries,document):new an(e.dialogId,e.maxRetries,document,this._logger)}this._currentReconnectionProcess||(this._currentReconnectionProcess=new hn(e,this._logger,this._reconnectCallback,this._reconnectionDisplay))}onConnectionUp(){this._currentReconnectionProcess&&(this._currentReconnectionProcess.dispose(),this._currentReconnectionProcess=null)}}class hn{constructor(e,t,n,r){this.logger=t,this.reconnectCallback=n,this.isDisposed=!1,this.reconnectDisplay=r,this.reconnectDisplay.show(),this.attemptPeriodicReconnection(e)}dispose(){this.isDisposed=!0,this.reconnectDisplay.hide()}async attemptPeriodicReconnection(e){for(let t=0;thn.MaximumFirstRetryInterval?hn.MaximumFirstRetryInterval:e.retryIntervalMilliseconds;if(await this.delay(n),this.isDisposed)break;try{return await this.reconnectCallback()?void 0:void this.reconnectDisplay.rejected()}catch(e){this.logger.log(en.Error,e)}}this.reconnectDisplay.failed()}delay(e){return new Promise((t=>setTimeout(t,e)))}}hn.MaximumFirstRetryInterval=3e3;const un=/^\s*Blazor-Component-State:(?[a-zA-Z0-9\+\/=]+)$/;function dn(e){var t;if(e.nodeType===Node.COMMENT_NODE){const n=e.textContent||"",r=un.exec(n),o=r&&r.groups&&r.groups.state;return o&&(null===(t=e.parentNode)||void 0===t||t.removeChild(e)),o}if(!e.hasChildNodes())return;const n=e.childNodes;for(let e=0;e.*)$/);function gn(e,t){const n=e.currentElement;if(n&&n.nodeType===Node.COMMENT_NODE&&n.textContent){const r=fn.exec(n.textContent),o=r&&r.groups&&r.groups.descriptor;if(!o)return;try{const r=function(e){const t=JSON.parse(e),{type:n}=t;if("server"!==n&&"webassembly"!==n)throw new Error(`Invalid component type '${n}'.`);return t}(o);switch(t){case"webassembly":return function(e,t,n){const{type:r,assembly:o,typeName:i,parameterDefinitions:s,parameterValues:a,prerenderId:c}=e;if("webassembly"===r){if(!o)throw new Error("assembly must be defined when using a descriptor.");if(!i)throw new Error("typeName must be defined when using a descriptor.");if(c){const e=mn(c,n);if(!e)throw new Error(`Could not find an end component comment for '${t}'`);return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:a&&atob(a),start:t,prerenderId:c,end:e}}return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:a&&atob(a),start:t}}}(r,n,e);case"server":return function(e,t,n){const{type:r,descriptor:o,sequence:i,prerenderId:s}=e;if("server"===r){if(!o)throw new Error("descriptor must be defined when using a descriptor.");if(void 0===i)throw new Error("sequence must be defined when using a descriptor.");if(!Number.isInteger(i))throw new Error(`Error parsing the sequence '${i}' for component '${JSON.stringify(e)}'`);if(s){const e=mn(s,n);if(!e)throw new Error(`Could not find an end component comment for '${t}'`);return{type:r,sequence:i,descriptor:o,start:t,prerenderId:s,end:e}}return{type:r,sequence:i,descriptor:o,start:t}}}(r,n,e)}}catch(e){throw new Error(`Found malformed component comment at ${n.textContent}`)}}}function mn(e,t){for(;t.next()&&t.currentElement;){const n=t.currentElement;if(n.nodeType!==Node.COMMENT_NODE)continue;if(!n.textContent)continue;const r=fn.exec(n.textContent),o=r&&r[1];if(o)return yn(o,e),n}}function yn(e,t){const n=JSON.parse(e);if(1!==Object.keys(n).length)throw new Error(`Invalid end of component comment: '${e}'`);const r=n.prerenderId;if(!r)throw new Error(`End of component comment must have a value for the prerendered property: '${e}'`);if(r!==t)throw new Error(`End of component comment prerendered property must match the start comment prerender id: '${t}', '${r}'`)}class wn{constructor(e){this.childNodes=e,this.currentIndex=-1,this.length=e.length}next(){return this.currentIndex++,this.currentIndexe.sequence-t.sequence))}(e)}(document),o=dn(document),i=new on(r,o||""),s=await Tn(t,n,i);if(!await i.startCircuit(s))return void n.log(en.Error,"Failed to start the circuit.");let a=!1;const c=()=>{if(!a){const e=new FormData,t=i.circuitId;e.append("circuitId",t),a=navigator.sendBeacon("_blazor/disconnect",e)}};fe.disconnect=c,window.addEventListener("unload",c,{capture:!1,once:!0}),fe.reconnect=async e=>{if(Cn)return!1;const r=e||await Tn(t,n,i);return await i.reconnect(r)?(t.reconnectionHandler.onConnectionUp(),!0):(n.log(en.Information,"Reconnection attempt to the circuit was rejected by the server. This may indicate that the associated state is no longer available on the server."),!1)},n.log(en.Information,"Blazor server-side application started.")}async function Tn(t,n,r){const i=new Lt;i.name="blazorpack";const s=(new rt).withUrl("_blazor").withHubProtocol(i);t.configureSignalR(s);const a=s.build();o=(e,t)=>{a.send("DispatchBrowserEvent",JSON.stringify(e),JSON.stringify(t))},fe._internal.navigationManager.listenForNavigationEvents(((e,t)=>a.send("OnLocationChanged",e,t))),a.on("JS.AttachComponent",((e,t)=>function(e,t,n){let r=Q[0];r||(r=Q[0]=new V(0)),r.attachRootComponentToLogicalElement(n,t)}(0,r.resolveElement(t),e))),a.on("JS.BeginInvokeJS",e.jsCallDispatcher.beginInvokeJSFromDotNet),a.on("JS.EndInvokeDotNet",e.jsCallDispatcher.endInvokeDotNetFromJS);const c=tn.getOrCreate(n);a.on("JS.RenderBatch",((e,t)=>{n.log(en.Debug,`Received render batch with id ${e} and ${t.byteLength} bytes.`),c.processBatch(e,t,a)})),a.onclose((e=>!Cn&&t.reconnectionHandler.onConnectionDown(t.reconnectionOptions,e))),a.on("JS.Error",(e=>{Cn=!0,xn(a,e,n),async function(){let e=document.querySelector("#blazor-error-ui");e&&(e.style.display="block"),Ht||(Ht=!0,document.querySelectorAll("#blazor-error-ui .reload").forEach((e=>{e.onclick=function(e){location.reload(),e.preventDefault()}})),document.querySelectorAll("#blazor-error-ui .dismiss").forEach((e=>{e.onclick=function(e){const t=document.querySelector("#blazor-error-ui");t&&(t.style.display="none"),e.preventDefault()}})))}()})),fe._internal.forceCloseConnection=()=>a.stop();try{await a.start()}catch(e){xn(a,e,n)}return e.attachDispatcher({beginInvokeDotNetFromJS:(e,t,n,r,o)=>{a.send("BeginInvokeDotNetFromJS",e?e.toString():null,t,n,r||0,o)},endInvokeJSFromDotNet:(e,t,n)=>{a.send("EndInvokeJSFromDotNet",e,t,n)}}),a}function xn(e,t,n){n.log(en.Error,t),e&&e.stop()}fe.start=kn,document&&document.currentScript&&"false"!==document.currentScript.getAttribute("autostart")&&kn()})(); \ No newline at end of file +(()=>{"use strict";var e,t,n;!function(e){window.DotNet=e;const t=[];class n{constructor(e){this._jsObject=e,this._cachedFunctions=new Map}findFunction(e){const t=this._cachedFunctions.get(e);if(t)return t;let n,r=this._jsObject;if(e.split(".").forEach((t=>{if(!(t in r))throw new Error(`Could not find '${e}' ('${t}' was undefined).`);n=r,r=r[t]})),r instanceof Function)return r=r.bind(n),this._cachedFunctions.set(e,r),r;throw new Error(`The value '${e}' is not a function.`)}getWrappedObject(){return this._jsObject}}const r="__jsObjectId",o={},i={0:new n(window)};i[0]._cachedFunctions.set("import",(e=>("string"==typeof e&&e.startsWith("./")&&(e=document.baseURI+e.substr(2)),import(e))));let s,a=1,c=1,l=null;function h(e){t.push(e)}function u(e){if(e&&"object"==typeof e){i[c]=new n(e);const t={[r]:c};return c++,t}throw new Error(`Cannot create a JSObjectReference from the value '${e}'.`)}function d(e,n){return e?JSON.parse(e,((e,r)=>t.reduce(((t,r)=>r(e,t,void 0===n?null:n)),r))):null}function p(e,t,n,r){const o=g();if(o.invokeDotNetFromJS){const i=[],s=JSON.stringify(r,((e,t)=>C(0,t,i))),a=o.invokeDotNetFromJS(e,t,n,s,i);return a&&a.ArgsJson?d(a.ArgsJson,a.ByteArrays):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function f(e,t,n,r){if(e&&n)throw new Error(`For instance method calls, assemblyName should be null. Received '${e}'.`);const i=a++,s=new Promise(((e,t)=>{o[i]={resolve:e,reject:t}}));try{const o=[],s=JSON.stringify(r,((e,t)=>C(0,t,o)));g().beginInvokeDotNetFromJS(i,e,t,n,s,o)}catch(e){m(i,!1,e)}return s}function g(){if(null!==l)return l;throw new Error("No .NET call dispatcher has been set.")}function m(e,t,n){if(!o.hasOwnProperty(e))throw new Error(`There is no pending async call with ID ${e}.`);const r=o[e];delete o[e],t?r.resolve(n):r.reject(n)}e.attachDispatcher=function(e){l=e},e.attachReviver=h,e.invokeMethod=function(e,t,...n){return p(e,t,null,n)},e.invokeMethodAsync=function(e,t,...n){return f(e,t,null,n)},e.createJSObjectReference=u,e.disposeJSObjectReference=function(e){const t=e&&e.__jsObjectId;"number"==typeof t&&b(t)},function(e){e[e.Default=0]="Default",e[e.JSObjectReference=1]="JSObjectReference"}(s=e.JSCallResultType||(e.JSCallResultType={}));class y{constructor(e,t){this.ArgsJson=e,this.ByteArrays=t}}function w(e){return e instanceof Error?`${e.message}\n${e.stack}`:e?e.toString():"null"}function v(e,t){let n=i[t];if(n)return n.findFunction(e);throw new Error(`JS object instance with ID ${t} does not exist (has it been disposed?).`)}function b(e){delete i[e]}e.SerializedArgs=y,e.jsCallDispatcher={findJSFunction:v,disposeJSObjectReferenceById:b,invokeJSFromDotNet:(e,t,n,r,o)=>{const i=S(v(e,o).apply(null,d(t,n)),r),s=[];var a=null==i?null:JSON.stringify(i,((e,t)=>C(0,t,s)));return new y(a,s)},beginInvokeJSFromDotNet:(e,t,n,r,o,i)=>{const s=new Promise((e=>{e(v(t,i).apply(null,d(n,r)))}));if(e){const t=[];s.then((n=>g().endInvokeJSFromDotNet(e,!0,JSON.stringify([e,!0,S(n,o)],((e,n)=>C(0,n,t))),t)),(t=>g().endInvokeJSFromDotNet(e,!1,JSON.stringify([e,!1,w(t)]),null)))}},endInvokeDotNetFromJS:(e,t,n,r)=>{const o=t?d(n,r):new Error(n);m(parseInt(e),t,o)}};class _{constructor(e){this._id=e}invokeMethod(e,...t){return p(null,e,this._id,t)}invokeMethodAsync(e,...t){return f(null,e,this._id,t)}dispose(){f(null,"__Dispose",this._id,null).catch((e=>console.error(e)))}serializeAsArg(){return{__dotNetObject:this._id}}}h((function(e,t,n){return t&&"object"==typeof t&&t.hasOwnProperty("__dotNetObject")?new _(t.__dotNetObject):t})),h((function(e,t,n){if(t&&"object"==typeof t&&t.hasOwnProperty(r)){const e=t.__jsObjectId,n=i[e];if(n)return n.getWrappedObject();throw new Error(`JS object instance with ID ${e} does not exist (has it been disposed?).`)}return t}));const E="__byte[]";function S(e,t){switch(t){case s.Default:return e;case s.JSObjectReference:return u(e);default:throw new Error(`Invalid JS call result type '${t}'.`)}}function C(e,t,n){if(t instanceof _)return t.serializeAsArg();if(t instanceof Uint8Array){var r=n.length;return n.push(t),{[E]:r}}return t}h((function(e,t,n){if(t&&"object"==typeof t&&t.hasOwnProperty(E)&&n){const e=t["__byte[]"];if(e>=n.length||e<0)throw new Error(`Byte array index '${e}' does not exist.`);return n[t["__byte[]"]]}return t}))}(e||(e={})),function(e){e[e.prependFrame=1]="prependFrame",e[e.removeFrame=2]="removeFrame",e[e.setAttribute=3]="setAttribute",e[e.removeAttribute=4]="removeAttribute",e[e.updateText=5]="updateText",e[e.stepIn=6]="stepIn",e[e.stepOut=7]="stepOut",e[e.updateMarkup=8]="updateMarkup",e[e.permutationListEntry=9]="permutationListEntry",e[e.permutationListEnd=10]="permutationListEnd"}(t||(t={})),function(e){e[e.element=1]="element",e[e.text=2]="text",e[e.attribute=3]="attribute",e[e.component=4]="component",e[e.region=5]="region",e[e.elementReferenceCapture=6]="elementReferenceCapture",e[e.markup=8]="markup"}(n||(n={}));class r{constructor(e,t){this.componentId=e,this.fieldValue=t}static fromEvent(e,t){const n=t.target;if(n instanceof Element){const t=function(e){return e instanceof HTMLInputElement?e.type&&"checkbox"===e.type.toLowerCase()?{value:e.checked}:{value:e.value}:e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?{value:e.value}:null}(n);if(t)return new r(e,t.value)}return null}}let o;function i(e,t){if(!o)throw new Error("eventDispatcher not initialized. Call 'setEventDispatcher' to configure it.");o(e,t)}const s=new Map,a=new Map,c={createEventArgs:()=>({})},l=[];function h(e){return s.get(e)}function u(e){const t=s.get(e);return(null==t?void 0:t.browserEventName)||e}function d(e,t){e.forEach((e=>s.set(e,t)))}function p(e){const t=[];for(let n=0;n{return{...f(t=e),dataTransfer:t.dataTransfer?{dropEffect:t.dataTransfer.dropEffect,effectAllowed:t.dataTransfer.effectAllowed,files:Array.from(t.dataTransfer.files).map((e=>e.name)),items:Array.from(t.dataTransfer.items).map((e=>({kind:e.kind,type:e.type}))),types:t.dataTransfer.types}:null};var t}}),d(["focus","blur","focusin","focusout"],c),d(["keydown","keyup","keypress"],{createEventArgs:e=>{return{key:(t=e).key,code:t.code,location:t.location,repeat:t.repeat,ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),d(["contextmenu","click","mouseover","mouseout","mousemove","mousedown","mouseup","dblclick"],{createEventArgs:e=>f(e)}),d(["error"],{createEventArgs:e=>{return{message:(t=e).message,filename:t.filename,lineno:t.lineno,colno:t.colno};var t}}),d(["loadstart","timeout","abort","load","loadend","progress"],{createEventArgs:e=>{return{lengthComputable:(t=e).lengthComputable,loaded:t.loaded,total:t.total};var t}}),d(["touchcancel","touchend","touchmove","touchenter","touchleave","touchstart"],{createEventArgs:e=>{return{detail:(t=e).detail,touches:p(t.touches),targetTouches:p(t.targetTouches),changedTouches:p(t.changedTouches),ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),d(["gotpointercapture","lostpointercapture","pointercancel","pointerdown","pointerenter","pointerleave","pointermove","pointerout","pointerover","pointerup"],{createEventArgs:e=>{return{...f(t=e),pointerId:t.pointerId,width:t.width,height:t.height,pressure:t.pressure,tiltX:t.tiltX,tiltY:t.tiltY,pointerType:t.pointerType,isPrimary:t.isPrimary};var t}}),d(["wheel","mousewheel"],{createEventArgs:e=>{return{...f(t=e),deltaX:t.deltaX,deltaY:t.deltaY,deltaZ:t.deltaZ,deltaMode:t.deltaMode};var t}}),d(["toggle"],c);const g=["date","datetime-local","month","time","week"],m=E(["abort","blur","change","error","focus","load","loadend","loadstart","mouseenter","mouseleave","progress","reset","scroll","submit","unload","toggle","DOMNodeInsertedIntoDocument","DOMNodeRemovedFromDocument"]),y={submit:!0},w=E(["click","dblclick","mousedown","mousemove","mouseup"]);class v{constructor(e){this.browserRendererId=e,this.afterClickCallbacks=[];const t=++v.nextEventDelegatorId;this.eventsCollectionKey=`_blazorEvents_${t}`,this.eventInfoStore=new b(this.onGlobalEvent.bind(this))}setListener(e,t,n,r){const o=this.getEventHandlerInfosForElement(e,!0),i=o.getHandler(t);if(i)this.eventInfoStore.update(i.eventHandlerId,n);else{const i={element:e,eventName:t,eventHandlerId:n,renderingComponentId:r};this.eventInfoStore.add(i),o.setHandler(t,i)}}getHandler(e){return this.eventInfoStore.get(e)}removeListener(e){const t=this.eventInfoStore.remove(e);if(t){const e=t.element,n=this.getEventHandlerInfosForElement(e,!1);n&&n.removeHandler(t.eventName)}}notifyAfterClick(e){this.afterClickCallbacks.push(e),this.eventInfoStore.addGlobalListener("click")}setStopPropagation(e,t,n){this.getEventHandlerInfosForElement(e,!0).stopPropagation(t,n)}setPreventDefault(e,t,n){this.getEventHandlerInfosForElement(e,!0).preventDefault(t,n)}onGlobalEvent(e){if(!(e.target instanceof Element))return;this.dispatchGlobalEventToAllElements(e.type,e);const t=(n=e.type,a.get(n));var n;t&&t.forEach((t=>this.dispatchGlobalEventToAllElements(t,e))),"click"===e.type&&this.afterClickCallbacks.forEach((t=>t(e)))}dispatchGlobalEventToAllElements(e,t){let n=t.target,o=null,s=!1;const a=m.hasOwnProperty(e);let c=!1;for(;n;){const d=this.getEventHandlerInfosForElement(n,!1);if(d){const a=d.getHandler(e);if(a&&(l=n,u=t.type,!((l instanceof HTMLButtonElement||l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)&&w.hasOwnProperty(u)&&l.disabled))){if(!s){const n=h(e);o=(null==n?void 0:n.createEventArgs)?n.createEventArgs(t):{},s=!0}y.hasOwnProperty(t.type)&&t.preventDefault(),i({browserRendererId:this.browserRendererId,eventHandlerId:a.eventHandlerId,eventName:e,eventFieldInfo:r.fromEvent(a.renderingComponentId,t)},o)}d.stopPropagation(e)&&(c=!0),d.preventDefault(e)&&t.preventDefault()}n=a||c?null:n.parentElement}var l,u}getEventHandlerInfosForElement(e,t){return e.hasOwnProperty(this.eventsCollectionKey)?e[this.eventsCollectionKey]:t?e[this.eventsCollectionKey]=new _:null}}v.nextEventDelegatorId=0;class b{constructor(e){this.globalListener=e,this.infosByEventHandlerId={},this.countByEventName={},l.push(this.handleEventNameAliasAdded.bind(this))}add(e){if(this.infosByEventHandlerId[e.eventHandlerId])throw new Error(`Event ${e.eventHandlerId} is already tracked`);this.infosByEventHandlerId[e.eventHandlerId]=e,this.addGlobalListener(e.eventName)}get(e){return this.infosByEventHandlerId[e]}addGlobalListener(e){if(e=u(e),this.countByEventName.hasOwnProperty(e))this.countByEventName[e]++;else{this.countByEventName[e]=1;const t=m.hasOwnProperty(e);document.addEventListener(e,this.globalListener,t)}}update(e,t){if(this.infosByEventHandlerId.hasOwnProperty(t))throw new Error(`Event ${t} is already tracked`);const n=this.infosByEventHandlerId[e];delete this.infosByEventHandlerId[e],n.eventHandlerId=t,this.infosByEventHandlerId[t]=n}remove(e){const t=this.infosByEventHandlerId[e];if(t){delete this.infosByEventHandlerId[e];const n=u(t.eventName);0==--this.countByEventName[n]&&(delete this.countByEventName[n],document.removeEventListener(n,this.globalListener))}return t}handleEventNameAliasAdded(e,t){if(this.countByEventName.hasOwnProperty(e)){const n=this.countByEventName[e];delete this.countByEventName[e],document.removeEventListener(e,this.globalListener),this.addGlobalListener(t),this.countByEventName[t]+=n-1}}}class _{constructor(){this.handlers={},this.preventDefaultFlags=null,this.stopPropagationFlags=null}getHandler(e){return this.handlers.hasOwnProperty(e)?this.handlers[e]:null}setHandler(e,t){this.handlers[e]=t}removeHandler(e){delete this.handlers[e]}preventDefault(e,t){return void 0!==t&&(this.preventDefaultFlags=this.preventDefaultFlags||{},this.preventDefaultFlags[e]=t),!!this.preventDefaultFlags&&this.preventDefaultFlags[e]}stopPropagation(e,t){return void 0!==t&&(this.stopPropagationFlags=this.stopPropagationFlags||{},this.stopPropagationFlags[e]=t),!!this.stopPropagationFlags&&this.stopPropagationFlags[e]}}function E(e){const t={};return e.forEach((e=>{t[e]=!0})),t}const S=H("_blazorLogicalChildren"),C=H("_blazorLogicalParent"),I=H("_blazorLogicalEnd");function k(e,t){if(e.childNodes.length>0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return S in e||(e[S]=[]),e}function T(e,t){const n=document.createComment("!");return x(n,e,t),n}function x(e,t,n){const r=e;if(e instanceof Comment&&A(r)&&A(r).length>0)throw new Error("Not implemented: inserting non-empty logical container");if(R(r))throw new Error("Not implemented: moving existing logical children");const o=A(t);if(n0;)D(n,0)}const r=n;r.parentNode.removeChild(r)}function R(e){return e[C]||null}function P(e,t){return A(e)[t]}function U(e){var t=$(e);return"http://www.w3.org/2000/svg"===t.namespaceURI&&"foreignObject"!==t.tagName}function A(e){return e[S]}function N(e,t){const n=A(e);t.forEach((e=>{e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=L(e.moveRangeStart)})),t.forEach((t=>{const r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):M(r,e)})),t.forEach((e=>{const t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd;let i=r;for(;i;){const e=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=e}n.removeChild(t)})),t.forEach((e=>{n[e.toSiblingIndex]=e.moveRangeStart}))}function $(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}function B(e){const t=A(R(e));return t[Array.prototype.indexOf.call(t,e)+1]||null}function M(e,t){if(t instanceof Element)t.appendChild(e);else{if(!(t instanceof Comment))throw new Error(`Cannot append node because the parent is not a valid logical element. Parent: ${t}`);{const n=B(t);n?n.parentNode.insertBefore(e,n):M(e,R(t))}}}function L(e){if(e instanceof Element)return e;const t=B(e);if(t)return t.previousSibling;{const t=R(e);return t instanceof Element?t.lastChild:L(t)}}function H(e){return"function"==typeof Symbol?Symbol():e}function O(e){return`_bl_${e}`}e.attachReviver((function(e,t,n){return t&&"object"==typeof t&&t.hasOwnProperty("__internalId")&&"string"==typeof t.__internalId?function(e){const t=`[${O(e)}]`;return document.querySelector(t)}(t.__internalId):t}));const F="_blazorSelectValue",j=document.createElement("template"),W=document.createElementNS("http://www.w3.org/2000/svg","g"),z={},q="__internal_",J="preventDefault_",K="stopPropagation_";class V{constructor(e){this.childComponentLocations={},this.eventDelegator=new v(e),this.eventDelegator.notifyAfterClick((e=>{if(!ee)return;if(0!==e.button||function(e){return e.ctrlKey||e.shiftKey||e.altKey||e.metaKey}(e))return;if(e.defaultPrevented)return;const t=function(e){const t=!window._blazorDisableComposedPath&&e.composedPath&&e.composedPath();if(t){for(let e=0;ese(!1))))},enableNavigationInterception:function(){ee=!0},navigateTo:oe,getBaseURI:()=>document.baseURI,getLocationHref:()=>location.href};function oe(e,t,n=!1){const r=ce(e);if(!t&&he(r))ie(r,!1,n);else if(t&&location.href===e){const t=e+"?";history.replaceState(null,"",t),location.replace(e)}else n?history.replaceState(null,"",r):location.href=e}function ie(e,t,n=!1){Z=!0,n?history.replaceState(null,"",e):history.pushState(null,"",e),se(t)}async function se(e){ne&&await ne(location.href,e)}let ae;function ce(e){return ae=ae||document.createElement("a"),ae.href=e,ae.href}function le(e,t){return e?e.tagName===t?e:le(e.parentElement,t):null}function he(e){const t=(n=document.baseURI).substr(0,n.lastIndexOf("/")+1);var n;return e.startsWith(t)}const ue={init:function(e,t,n,r=50){const o=pe(t);(o||document.documentElement).style.overflowAnchor="none";const i=new IntersectionObserver((function(r){r.forEach((r=>{var o;if(!r.isIntersecting)return;const i=t.getBoundingClientRect(),s=n.getBoundingClientRect().top-i.bottom,a=null===(o=r.rootBounds)||void 0===o?void 0:o.height;r.target===t?e.invokeMethodAsync("OnSpacerBeforeVisible",r.intersectionRect.top-r.boundingClientRect.top,s,a):r.target===n&&n.offsetHeight>0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,s,a)}))}),{root:o,rootMargin:`${r}px`});i.observe(t),i.observe(n);const s=c(t),a=c(n);function c(e){const t=new MutationObserver((()=>{i.unobserve(e),i.observe(e)}));return t.observe(e,{attributes:!0}),t}de[e._id]={intersectionObserver:i,mutationObserverBefore:s,mutationObserverAfter:a}},dispose:function(e){const t=de[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete de[e._id])}},de={};function pe(e){return e?"visible"!==getComputedStyle(e).overflowY?e:pe(e.parentElement):null}const fe={navigateTo:oe,registerCustomEventType:function(e,t){if(!t)throw new Error("The options parameter is required.");if(s.has(e))throw new Error(`The event '${e}' is already registered.`);if(t.browserEventName){const n=a.get(t.browserEventName);n?n.push(e):a.set(t.browserEventName,[e]),l.forEach((n=>n(e,t.browserEventName)))}s.set(e,t)},_internal:{navigationManager:re,domWrapper:{focus:function(e,t){if(!(e instanceof HTMLElement))throw new Error("Unable to focus an invalid element.");e.focus({preventScroll:t})}},Virtualize:ue}};window.Blazor=fe;const ge=[0,2e3,1e4,3e4,null];class me{constructor(e){this._retryDelays=void 0!==e?[...e,null]:ge}nextRetryDelayInMilliseconds(e){return this._retryDelays[e.previousRetryCount]}}class ye extends Error{constructor(e,t){const n=new.target.prototype;super(`${e}: Status code '${t}'`),this.statusCode=t,this.__proto__=n}}class we extends Error{constructor(e="A timeout occurred."){const t=new.target.prototype;super(e),this.__proto__=t}}class ve extends Error{constructor(e="An abort occurred."){const t=new.target.prototype;super(e),this.__proto__=t}}class be{constructor(e,t,n){this.statusCode=e,this.statusText=t,this.content=n}}class _e{get(e,t){return this.send({...t,method:"GET",url:e})}post(e,t){return this.send({...t,method:"POST",url:e})}delete(e,t){return this.send({...t,method:"DELETE",url:e})}getCookieString(e){return""}}var Ee,Se,Ce,Ie,ke;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Information=2]="Information",e[e.Warning=3]="Warning",e[e.Error=4]="Error",e[e.Critical=5]="Critical",e[e.None=6]="None"}(Ee||(Ee={}));class Te extends _e{constructor(e){if(super(),this._logger=e,"undefined"==typeof fetch){const e=require;this._jar=new(e("tough-cookie").CookieJar),this._fetchType=e("node-fetch"),this._fetchType=e("fetch-cookie")(this._fetchType,this._jar),this._abortControllerType=e("abort-controller")}else this._fetchType=fetch.bind(self),this._abortControllerType=AbortController}async send(e){if(e.abortSignal&&e.abortSignal.aborted)throw new ve;if(!e.method)throw new Error("No method defined.");if(!e.url)throw new Error("No url defined.");const t=new this._abortControllerType;let n;e.abortSignal&&(e.abortSignal.onabort=()=>{t.abort(),n=new ve});let r,o=null;if(e.timeout){const r=e.timeout;o=setTimeout((()=>{t.abort(),this._logger.log(Ee.Warning,"Timeout from HTTP request."),n=new we}),r)}try{r=await this._fetchType(e.url,{body:e.content,cache:"no-cache",credentials:!0===e.withCredentials?"include":"same-origin",headers:{"Content-Type":"text/plain;charset=UTF-8","X-Requested-With":"XMLHttpRequest",...e.headers},method:e.method,mode:"cors",redirect:"follow",signal:t.signal})}catch(e){if(n)throw n;throw this._logger.log(Ee.Warning,`Error from HTTP request. ${e}.`),e}finally{o&&clearTimeout(o),e.abortSignal&&(e.abortSignal.onabort=null)}if(!r.ok){const e=await xe(r,"text");throw new ye(e||r.statusText,r.status)}const i=xe(r,e.responseType),s=await i;return new be(r.status,r.statusText,s)}getCookieString(e){return""}}function xe(e,t){let n;switch(t){case"arraybuffer":n=e.arrayBuffer();break;case"text":n=e.text();break;case"blob":case"document":case"json":throw new Error(`${t} is not supported.`);default:n=e.text()}return n}class De extends _e{constructor(e){super(),this._logger=e}send(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new ve):e.method?e.url?new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open(e.method,e.url,!0),r.withCredentials=void 0===e.withCredentials||e.withCredentials,r.setRequestHeader("X-Requested-With","XMLHttpRequest"),r.setRequestHeader("Content-Type","text/plain;charset=UTF-8");const o=e.headers;o&&Object.keys(o).forEach((e=>{r.setRequestHeader(e,o[e])})),e.responseType&&(r.responseType=e.responseType),e.abortSignal&&(e.abortSignal.onabort=()=>{r.abort(),n(new ve)}),e.timeout&&(r.timeout=e.timeout),r.onload=()=>{e.abortSignal&&(e.abortSignal.onabort=null),r.status>=200&&r.status<300?t(new be(r.status,r.statusText,r.response||r.responseText)):n(new ye(r.response||r.responseText||r.statusText,r.status))},r.onerror=()=>{this._logger.log(Ee.Warning,`Error from HTTP request. ${r.status}: ${r.statusText}.`),n(new ye(r.statusText,r.status))},r.ontimeout=()=>{this._logger.log(Ee.Warning,"Timeout from HTTP request."),n(new we)},r.send(e.content||"")})):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))}}class Re extends _e{constructor(e){if(super(),"undefined"!=typeof fetch)this._httpClient=new Te(e);else{if("undefined"==typeof XMLHttpRequest)throw new Error("No usable HttpClient found.");this._httpClient=new De(e)}}send(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new ve):e.method?e.url?this._httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))}getCookieString(e){return this._httpClient.getCookieString(e)}}class Pe{}Pe.Authorization="Authorization",Pe.Cookie="Cookie",function(e){e[e.None=0]="None",e[e.WebSockets=1]="WebSockets",e[e.ServerSentEvents=2]="ServerSentEvents",e[e.LongPolling=4]="LongPolling"}(Se||(Se={})),function(e){e[e.Text=1]="Text",e[e.Binary=2]="Binary"}(Ce||(Ce={}));class Ue{constructor(){this._isAborted=!1,this.onabort=null}abort(){this._isAborted||(this._isAborted=!0,this.onabort&&this.onabort())}get signal(){return this}get aborted(){return this._isAborted}}class Ae{constructor(){}log(e,t){}}Ae.instance=new Ae;class Ne{static isRequired(e,t){if(null==e)throw new Error(`The '${t}' argument is required.`)}static isNotEmpty(e,t){if(!e||e.match(/^\s*$/))throw new Error(`The '${t}' argument should not be empty.`)}static isIn(e,t,n){if(!(e in t))throw new Error(`Unknown ${n} value: ${e}.`)}}class $e{static get isBrowser(){return"object"==typeof window}static get isWebWorker(){return"object"==typeof self&&"importScripts"in self}static get isNode(){return!this.isBrowser&&!this.isWebWorker}}function Be(e,t){let n="";return Me(e)?(n=`Binary data of length ${e.byteLength}`,t&&(n+=`. Content: '${function(e){const t=new Uint8Array(e);let n="";return t.forEach((e=>{n+=`0x${e<16?"0":""}${e.toString(16)} `})),n.substr(0,n.length-1)}(e)}'`)):"string"==typeof e&&(n=`String data of length ${e.length}`,t&&(n+=`. Content: '${e}'`)),n}function Me(e){return e&&"undefined"!=typeof ArrayBuffer&&(e instanceof ArrayBuffer||e.constructor&&"ArrayBuffer"===e.constructor.name)}async function Le(e,t,n,r,o,i,s,a,c){let l={};if(o){const e=await o();e&&(l={Authorization:`Bearer ${e}`})}const[h,u]=Fe();l[h]=u,e.log(Ee.Trace,`(${t} transport) sending data. ${Be(i,s)}.`);const d=Me(i)?"arraybuffer":"text",p=await n.post(r,{content:i,headers:{...l,...c},responseType:d,withCredentials:a});e.log(Ee.Trace,`(${t} transport) request complete. Response status: ${p.statusCode}.`)}class He{constructor(e,t){this._subject=e,this._observer=t}dispose(){const e=this._subject.observers.indexOf(this._observer);e>-1&&this._subject.observers.splice(e,1),0===this._subject.observers.length&&this._subject.cancelCallback&&this._subject.cancelCallback().catch((e=>{}))}}class Oe{constructor(e){this._minLevel=e,this.out=console}log(e,t){if(e>=this._minLevel){const n=`[${(new Date).toISOString()}] ${Ee[e]}: ${t}`;switch(e){case Ee.Critical:case Ee.Error:this.out.error(n);break;case Ee.Warning:this.out.warn(n);break;case Ee.Information:this.out.info(n);break;default:this.out.log(n)}}}}function Fe(){let e="X-SignalR-User-Agent";return $e.isNode&&(e="User-Agent"),[e,je("0.0.0-DEV_BUILD",We(),$e.isNode?"NodeJS":"Browser",ze())]}function je(e,t,n,r){let o="Microsoft SignalR/";const i=e.split(".");return o+=`${i[0]}.${i[1]}`,o+=` (${e}; `,o+=t&&""!==t?`${t}; `:"Unknown OS; ",o+=`${n}`,o+=r?`; ${r}`:"; Unknown Runtime Version",o+=")",o}function We(){if(!$e.isNode)return"";switch(process.platform){case"win32":return"Windows NT";case"darwin":return"macOS";case"linux":return"Linux";default:return process.platform}}function ze(){if($e.isNode)return process.versions.node}class qe{constructor(e,t,n,r,o,i){this._httpClient=e,this._accessTokenFactory=t,this._logger=n,this._pollAbort=new Ue,this._logMessageContent=r,this._withCredentials=o,this._headers=i,this._running=!1,this.onreceive=null,this.onclose=null}get pollAborted(){return this._pollAbort.aborted}async connect(e,t){if(Ne.isRequired(e,"url"),Ne.isRequired(t,"transferFormat"),Ne.isIn(t,Ce,"transferFormat"),this._url=e,this._logger.log(Ee.Trace,"(LongPolling transport) Connecting."),t===Ce.Binary&&"undefined"!=typeof XMLHttpRequest&&"string"!=typeof(new XMLHttpRequest).responseType)throw new Error("Binary protocols over XmlHttpRequest not implementing advanced features are not supported.");const[n,r]=Fe(),o={[n]:r,...this._headers},i={abortSignal:this._pollAbort.signal,headers:o,timeout:1e5,withCredentials:this._withCredentials};t===Ce.Binary&&(i.responseType="arraybuffer");const s=await this._getAccessToken();this._updateHeaderToken(i,s);const a=`${e}&_=${Date.now()}`;this._logger.log(Ee.Trace,`(LongPolling transport) polling: ${a}.`);const c=await this._httpClient.get(a,i);200!==c.statusCode?(this._logger.log(Ee.Error,`(LongPolling transport) Unexpected response code: ${c.statusCode}.`),this._closeError=new ye(c.statusText||"",c.statusCode),this._running=!1):this._running=!0,this._receiving=this._poll(this._url,i)}async _getAccessToken(){return this._accessTokenFactory?await this._accessTokenFactory():null}_updateHeaderToken(e,t){e.headers||(e.headers={}),t?e.headers[Pe.Authorization]=`Bearer ${t}`:e.headers[Pe.Authorization]&&delete e.headers[Pe.Authorization]}async _poll(e,t){try{for(;this._running;){const n=await this._getAccessToken();this._updateHeaderToken(t,n);try{const n=`${e}&_=${Date.now()}`;this._logger.log(Ee.Trace,`(LongPolling transport) polling: ${n}.`);const r=await this._httpClient.get(n,t);204===r.statusCode?(this._logger.log(Ee.Information,"(LongPolling transport) Poll terminated by server."),this._running=!1):200!==r.statusCode?(this._logger.log(Ee.Error,`(LongPolling transport) Unexpected response code: ${r.statusCode}.`),this._closeError=new ye(r.statusText||"",r.statusCode),this._running=!1):r.content?(this._logger.log(Ee.Trace,`(LongPolling transport) data received. ${Be(r.content,this._logMessageContent)}.`),this.onreceive&&this.onreceive(r.content)):this._logger.log(Ee.Trace,"(LongPolling transport) Poll timed out, reissuing.")}catch(e){this._running?e instanceof we?this._logger.log(Ee.Trace,"(LongPolling transport) Poll timed out, reissuing."):(this._closeError=e,this._running=!1):this._logger.log(Ee.Trace,`(LongPolling transport) Poll errored after shutdown: ${e.message}`)}}}finally{this._logger.log(Ee.Trace,"(LongPolling transport) Polling complete."),this.pollAborted||this._raiseOnClose()}}async send(e){return this._running?Le(this._logger,"LongPolling",this._httpClient,this._url,this._accessTokenFactory,e,this._logMessageContent,this._withCredentials,this._headers):Promise.reject(new Error("Cannot send until the transport is connected"))}async stop(){this._logger.log(Ee.Trace,"(LongPolling transport) Stopping polling."),this._running=!1,this._pollAbort.abort();try{await this._receiving,this._logger.log(Ee.Trace,`(LongPolling transport) sending DELETE request to ${this._url}.`);const e={},[t,n]=Fe();e[t]=n;const r={headers:{...e,...this._headers},withCredentials:this._withCredentials},o=await this._getAccessToken();this._updateHeaderToken(r,o),await this._httpClient.delete(this._url,r),this._logger.log(Ee.Trace,"(LongPolling transport) DELETE request sent.")}finally{this._logger.log(Ee.Trace,"(LongPolling transport) Stop finished."),this._raiseOnClose()}}_raiseOnClose(){if(this.onclose){let e="(LongPolling transport) Firing onclose event.";this._closeError&&(e+=" Error: "+this._closeError),this._logger.log(Ee.Trace,e),this.onclose(this._closeError)}}}class Je{constructor(e,t,n,r,o,i,s){this._httpClient=e,this._accessTokenFactory=t,this._logger=n,this._logMessageContent=r,this._withCredentials=i,this._eventSourceConstructor=o,this._headers=s,this.onreceive=null,this.onclose=null}async connect(e,t){if(Ne.isRequired(e,"url"),Ne.isRequired(t,"transferFormat"),Ne.isIn(t,Ce,"transferFormat"),this._logger.log(Ee.Trace,"(SSE transport) Connecting."),this._url=e,this._accessTokenFactory){const t=await this._accessTokenFactory();t&&(e+=(e.indexOf("?")<0?"?":"&")+`access_token=${encodeURIComponent(t)}`)}return new Promise(((n,r)=>{let o,i=!1;if(t===Ce.Text){if($e.isBrowser||$e.isWebWorker)o=new this._eventSourceConstructor(e,{withCredentials:this._withCredentials});else{const t=this._httpClient.getCookieString(e),n={};n.Cookie=t;const[r,i]=Fe();n[r]=i,o=new this._eventSourceConstructor(e,{withCredentials:this._withCredentials,headers:{...n,...this._headers}})}try{o.onmessage=e=>{if(this.onreceive)try{this._logger.log(Ee.Trace,`(SSE transport) data received. ${Be(e.data,this._logMessageContent)}.`),this.onreceive(e.data)}catch(e){return void this._close(e)}},o.onerror=e=>{i?this._close():r(new Error("EventSource failed to connect. The connection could not be found on the server, either the connection ID is not present on the server, or a proxy is refusing/buffering the connection. If you have multiple servers check that sticky sessions are enabled."))},o.onopen=()=>{this._logger.log(Ee.Information,`SSE connected to ${this._url}`),this._eventSource=o,i=!0,n()}}catch(e){return void r(e)}}else r(new Error("The Server-Sent Events transport only supports the 'Text' transfer format"))}))}async send(e){return this._eventSource?Le(this._logger,"SSE",this._httpClient,this._url,this._accessTokenFactory,e,this._logMessageContent,this._withCredentials,this._headers):Promise.reject(new Error("Cannot send until the transport is connected"))}stop(){return this._close(),Promise.resolve()}_close(e){this._eventSource&&(this._eventSource.close(),this._eventSource=void 0,this.onclose&&this.onclose(e))}}class Ke{constructor(e,t,n,r,o,i){this._logger=n,this._accessTokenFactory=t,this._logMessageContent=r,this._webSocketConstructor=o,this._httpClient=e,this.onreceive=null,this.onclose=null,this._headers=i}async connect(e,t){if(Ne.isRequired(e,"url"),Ne.isRequired(t,"transferFormat"),Ne.isIn(t,Ce,"transferFormat"),this._logger.log(Ee.Trace,"(WebSockets transport) Connecting."),this._accessTokenFactory){const t=await this._accessTokenFactory();t&&(e+=(e.indexOf("?")<0?"?":"&")+`access_token=${encodeURIComponent(t)}`)}return new Promise(((n,r)=>{let o;e=e.replace(/^http/,"ws"),this._httpClient.getCookieString(e);let i=!1;o||(o=new this._webSocketConstructor(e)),t===Ce.Binary&&(o.binaryType="arraybuffer"),o.onopen=t=>{this._logger.log(Ee.Information,`WebSocket connected to ${e}.`),this._webSocket=o,i=!0,n()},o.onerror=e=>{let t=null;t="undefined"!=typeof ErrorEvent&&e instanceof ErrorEvent?e.error:"There was an error with the transport",this._logger.log(Ee.Information,`(WebSockets transport) ${t}.`)},o.onmessage=e=>{if(this._logger.log(Ee.Trace,`(WebSockets transport) data received. ${Be(e.data,this._logMessageContent)}.`),this.onreceive)try{this.onreceive(e.data)}catch(e){return void this._close(e)}},o.onclose=e=>{if(i)this._close(e);else{let t=null;t="undefined"!=typeof ErrorEvent&&e instanceof ErrorEvent?e.error:"WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.",r(new Error(t))}}}))}send(e){return this._webSocket&&this._webSocket.readyState===this._webSocketConstructor.OPEN?(this._logger.log(Ee.Trace,`(WebSockets transport) sending data. ${Be(e,this._logMessageContent)}.`),this._webSocket.send(e),Promise.resolve()):Promise.reject("WebSocket is not in the OPEN state")}stop(){return this._webSocket&&this._close(void 0),Promise.resolve()}_close(e){this._webSocket&&(this._webSocket.onclose=()=>{},this._webSocket.onmessage=()=>{},this._webSocket.onerror=()=>{},this._webSocket.close(),this._webSocket=void 0),this._logger.log(Ee.Trace,"(WebSockets transport) socket closed."),this.onclose&&(!this._isCloseEvent(e)||!1!==e.wasClean&&1e3===e.code?e instanceof Error?this.onclose(e):this.onclose():this.onclose(new Error(`WebSocket closed with status code: ${e.code} (${e.reason||"no reason given"}).`)))}_isCloseEvent(e){return e&&"boolean"==typeof e.wasClean&&"number"==typeof e.code}}class Ve{constructor(e,t={}){var n;if(this._stopPromiseResolver=()=>{},this.features={},this._negotiateVersion=1,Ne.isRequired(e,"url"),this._logger=void 0===(n=t.logger)?new Oe(Ee.Information):null===n?Ae.instance:void 0!==n.log?n:new Oe(n),this.baseUrl=this._resolveUrl(e),(t=t||{}).logMessageContent=void 0!==t.logMessageContent&&t.logMessageContent,"boolean"!=typeof t.withCredentials&&void 0!==t.withCredentials)throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");t.withCredentials=void 0===t.withCredentials||t.withCredentials,"undefined"==typeof WebSocket||t.WebSocket||(t.WebSocket=WebSocket),"undefined"==typeof EventSource||t.EventSource||(t.EventSource=EventSource),this._httpClient=t.httpClient||new Re(this._logger),this._connectionState="Disconnected",this._connectionStarted=!1,this._options=t,this.onreceive=null,this.onclose=null}async start(e){if(e=e||Ce.Binary,Ne.isIn(e,Ce,"transferFormat"),this._logger.log(Ee.Debug,`Starting connection with transfer format '${Ce[e]}'.`),"Disconnected"!==this._connectionState)return Promise.reject(new Error("Cannot start an HttpConnection that is not in the 'Disconnected' state."));if(this._connectionState="Connecting",this._startInternalPromise=this._startInternal(e),await this._startInternalPromise,"Disconnecting"===this._connectionState){const e="Failed to start the HttpConnection before stop() was called.";return this._logger.log(Ee.Error,e),await this._stopPromise,Promise.reject(new Error(e))}if("Connected"!==this._connectionState){const e="HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!";return this._logger.log(Ee.Error,e),Promise.reject(new Error(e))}this._connectionStarted=!0}send(e){return"Connected"!==this._connectionState?Promise.reject(new Error("Cannot send data if the connection is not in the 'Connected' State.")):(this._sendQueue||(this._sendQueue=new Xe(this.transport)),this._sendQueue.send(e))}async stop(e){return"Disconnected"===this._connectionState?(this._logger.log(Ee.Debug,`Call to HttpConnection.stop(${e}) ignored because the connection is already in the disconnected state.`),Promise.resolve()):"Disconnecting"===this._connectionState?(this._logger.log(Ee.Debug,`Call to HttpConnection.stop(${e}) ignored because the connection is already in the disconnecting state.`),this._stopPromise):(this._connectionState="Disconnecting",this._stopPromise=new Promise((e=>{this._stopPromiseResolver=e})),await this._stopInternal(e),void await this._stopPromise)}async _stopInternal(e){this._stopError=e;try{await this._startInternalPromise}catch(e){}if(this.transport){try{await this.transport.stop()}catch(e){this._logger.log(Ee.Error,`HttpConnection.transport.stop() threw error '${e}'.`),this._stopConnection()}this.transport=void 0}else this._logger.log(Ee.Debug,"HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.")}async _startInternal(e){let t=this.baseUrl;this._accessTokenFactory=this._options.accessTokenFactory;try{if(this._options.skipNegotiation){if(this._options.transport!==Se.WebSockets)throw new Error("Negotiation can only be skipped when using the WebSocket transport directly.");this.transport=this._constructTransport(Se.WebSockets),await this._startTransport(t,e)}else{let n=null,r=0;do{if(n=await this._getNegotiationResponse(t),"Disconnecting"===this._connectionState||"Disconnected"===this._connectionState)throw new Error("The connection was stopped during negotiation.");if(n.error)throw new Error(n.error);if(n.ProtocolVersion)throw new Error("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.");if(n.url&&(t=n.url),n.accessToken){const e=n.accessToken;this._accessTokenFactory=()=>e}r++}while(n.url&&r<100);if(100===r&&n.url)throw new Error("Negotiate redirection limit exceeded.");await this._createTransport(t,this._options.transport,n,e)}this.transport instanceof qe&&(this.features.inherentKeepAlive=!0),"Connecting"===this._connectionState&&(this._logger.log(Ee.Debug,"The HttpConnection connected successfully."),this._connectionState="Connected")}catch(e){return this._logger.log(Ee.Error,"Failed to start the connection: "+e),this._connectionState="Disconnected",this.transport=void 0,this._stopPromiseResolver(),Promise.reject(e)}}async _getNegotiationResponse(e){const t={};if(this._accessTokenFactory){const e=await this._accessTokenFactory();e&&(t[Pe.Authorization]=`Bearer ${e}`)}const[n,r]=Fe();t[n]=r;const o=this._resolveNegotiateUrl(e);this._logger.log(Ee.Debug,`Sending negotiation request: ${o}.`);try{const e=await this._httpClient.post(o,{content:"",headers:{...t,...this._options.headers},withCredentials:this._options.withCredentials});if(200!==e.statusCode)return Promise.reject(new Error(`Unexpected status code returned from negotiate '${e.statusCode}'`));const n=JSON.parse(e.content);return(!n.negotiateVersion||n.negotiateVersion<1)&&(n.connectionToken=n.connectionId),n}catch(e){let t="Failed to complete negotiation with the server: "+e;return e instanceof ye&&404===e.statusCode&&(t+=" Either this is not a SignalR endpoint or there is a proxy blocking the connection."),this._logger.log(Ee.Error,t),Promise.reject(new Error(t))}}_createConnectUrl(e,t){return t?e+(-1===e.indexOf("?")?"?":"&")+`id=${t}`:e}async _createTransport(e,t,n,r){let o=this._createConnectUrl(e,n.connectionToken);if(this._isITransport(t))return this._logger.log(Ee.Debug,"Connection was provided an instance of ITransport, using that directly."),this.transport=t,await this._startTransport(o,r),void(this.connectionId=n.connectionId);const i=[],s=n.availableTransports||[];let a=n;for(const n of s){const s=this._resolveTransportOrError(n,t,r);if(s instanceof Error)i.push(`${n.transport} failed: ${s}`);else if(this._isITransport(s)){if(this.transport=s,!a){try{a=await this._getNegotiationResponse(e)}catch(e){return Promise.reject(e)}o=this._createConnectUrl(e,a.connectionToken)}try{return await this._startTransport(o,r),void(this.connectionId=a.connectionId)}catch(e){if(this._logger.log(Ee.Error,`Failed to start the transport '${n.transport}': ${e}`),a=void 0,i.push(`${n.transport} failed: ${e}`),"Connecting"!==this._connectionState){const e="Failed to select transport before stop() was called.";return this._logger.log(Ee.Debug,e),Promise.reject(new Error(e))}}}}return i.length>0?Promise.reject(new Error(`Unable to connect to the server with any of the available transports. ${i.join(" ")}`)):Promise.reject(new Error("None of the transports supported by the client are supported by the server."))}_constructTransport(e){switch(e){case Se.WebSockets:if(!this._options.WebSocket)throw new Error("'WebSocket' is not supported in your environment.");return new Ke(this._httpClient,this._accessTokenFactory,this._logger,this._options.logMessageContent||!1,this._options.WebSocket,this._options.headers||{});case Se.ServerSentEvents:if(!this._options.EventSource)throw new Error("'EventSource' is not supported in your environment.");return new Je(this._httpClient,this._accessTokenFactory,this._logger,this._options.logMessageContent||!1,this._options.EventSource,this._options.withCredentials,this._options.headers||{});case Se.LongPolling:return new qe(this._httpClient,this._accessTokenFactory,this._logger,this._options.logMessageContent||!1,this._options.withCredentials,this._options.headers||{});default:throw new Error(`Unknown transport: ${e}.`)}}_startTransport(e,t){return this.transport.onreceive=this.onreceive,this.transport.onclose=e=>this._stopConnection(e),this.transport.connect(e,t)}_resolveTransportOrError(e,t,n){const r=Se[e.transport];if(null==r)return this._logger.log(Ee.Debug,`Skipping transport '${e.transport}' because it is not supported by this client.`),new Error(`Skipping transport '${e.transport}' because it is not supported by this client.`);if(!function(e,t){return!e||0!=(t&e)}(t,r))return this._logger.log(Ee.Debug,`Skipping transport '${Se[r]}' because it was disabled by the client.`),new Error(`'${Se[r]}' is disabled by the client.`);if(!(e.transferFormats.map((e=>Ce[e])).indexOf(n)>=0))return this._logger.log(Ee.Debug,`Skipping transport '${Se[r]}' because it does not support the requested transfer format '${Ce[n]}'.`),new Error(`'${Se[r]}' does not support ${Ce[n]}.`);if(r===Se.WebSockets&&!this._options.WebSocket||r===Se.ServerSentEvents&&!this._options.EventSource)return this._logger.log(Ee.Debug,`Skipping transport '${Se[r]}' because it is not supported in your environment.'`),new Error(`'${Se[r]}' is not supported in your environment.`);this._logger.log(Ee.Debug,`Selecting transport '${Se[r]}'.`);try{return this._constructTransport(r)}catch(e){return e}}_isITransport(e){return e&&"object"==typeof e&&"connect"in e}_stopConnection(e){if(this._logger.log(Ee.Debug,`HttpConnection.stopConnection(${e}) called while in state ${this._connectionState}.`),this.transport=void 0,e=this._stopError||e,this._stopError=void 0,"Disconnected"!==this._connectionState){if("Connecting"===this._connectionState)throw this._logger.log(Ee.Warning,`Call to HttpConnection.stopConnection(${e}) was ignored because the connection is still in the connecting state.`),new Error(`HttpConnection.stopConnection(${e}) was called while the connection is still in the connecting state.`);if("Disconnecting"===this._connectionState&&this._stopPromiseResolver(),e?this._logger.log(Ee.Error,`Connection disconnected with error '${e}'.`):this._logger.log(Ee.Information,"Connection disconnected."),this._sendQueue&&(this._sendQueue.stop().catch((e=>{this._logger.log(Ee.Error,`TransportSendQueue.stop() threw error '${e}'.`)})),this._sendQueue=void 0),this.connectionId=void 0,this._connectionState="Disconnected",this._connectionStarted){this._connectionStarted=!1;try{this.onclose&&this.onclose(e)}catch(t){this._logger.log(Ee.Error,`HttpConnection.onclose(${e}) threw error '${t}'.`)}}}else this._logger.log(Ee.Debug,`Call to HttpConnection.stopConnection(${e}) was ignored because the connection is already in the disconnected state.`)}_resolveUrl(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if(!$e.isBrowser||!window.document)throw new Error(`Cannot resolve '${e}'.`);const t=window.document.createElement("a");return t.href=e,this._logger.log(Ee.Information,`Normalizing '${e}' to '${t.href}'.`),t.href}_resolveNegotiateUrl(e){const t=e.indexOf("?");let n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t),-1===n.indexOf("negotiateVersion")&&(n+=-1===t?"?":"&",n+="negotiateVersion="+this._negotiateVersion),n}}class Xe{constructor(e){this._transport=e,this._buffer=[],this._executing=!0,this._sendBufferedData=new Ye,this._transportResult=new Ye,this._sendLoopPromise=this._sendLoop()}send(e){return this._bufferData(e),this._transportResult||(this._transportResult=new Ye),this._transportResult.promise}stop(){return this._executing=!1,this._sendBufferedData.resolve(),this._sendLoopPromise}_bufferData(e){if(this._buffer.length&&typeof this._buffer[0]!=typeof e)throw new Error(`Expected data to be of type ${typeof this._buffer} but was of type ${typeof e}`);this._buffer.push(e),this._sendBufferedData.resolve()}async _sendLoop(){for(;;){if(await this._sendBufferedData.promise,!this._executing){this._transportResult&&this._transportResult.reject("Connection stopped.");break}this._sendBufferedData=new Ye;const e=this._transportResult;this._transportResult=void 0;const t="string"==typeof this._buffer[0]?this._buffer.join(""):Xe._concatBuffers(this._buffer);this._buffer.length=0;try{await this._transport.send(t),e.resolve()}catch(t){e.reject(t)}}}static _concatBuffers(e){const t=e.map((e=>e.byteLength)).reduce(((e,t)=>e+t)),n=new Uint8Array(t);let r=0;for(const t of e)n.set(new Uint8Array(t),r),r+=t.byteLength;return n.buffer}}class Ye{constructor(){this.promise=new Promise(((e,t)=>[this._resolver,this._rejecter]=[e,t]))}resolve(){this._resolver()}reject(e){this._rejecter(e)}}class Ge{static write(e){return`${e}${Ge.RecordSeparator}`}static parse(e){if(e[e.length-1]!==Ge.RecordSeparator)throw new Error("Message is incomplete.");const t=e.split(Ge.RecordSeparator);return t.pop(),t}}Ge.RecordSeparatorCode=30,Ge.RecordSeparator=String.fromCharCode(Ge.RecordSeparatorCode);class Qe{writeHandshakeRequest(e){return Ge.write(JSON.stringify(e))}parseHandshakeResponse(e){let t,n;if(Me(e)){const r=new Uint8Array(e),o=r.indexOf(Ge.RecordSeparatorCode);if(-1===o)throw new Error("Message is incomplete.");const i=o+1;t=String.fromCharCode.apply(null,Array.prototype.slice.call(r.slice(0,i))),n=r.byteLength>i?r.slice(i).buffer:null}else{const r=e,o=r.indexOf(Ge.RecordSeparator);if(-1===o)throw new Error("Message is incomplete.");const i=o+1;t=r.substring(0,i),n=r.length>i?r.substring(i):null}const r=Ge.parse(t),o=JSON.parse(r[0]);if(o.type)throw new Error("Expected a handshake response from the server.");return[n,o]}}!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(Ie||(Ie={}));class Ze{constructor(){this.observers=[]}next(e){for(const t of this.observers)t.next(e)}error(e){for(const t of this.observers)t.error&&t.error(e)}complete(){for(const e of this.observers)e.complete&&e.complete()}subscribe(e){return this.observers.push(e),new He(this,e)}}!function(e){e.Disconnected="Disconnected",e.Connecting="Connecting",e.Connected="Connected",e.Disconnecting="Disconnecting",e.Reconnecting="Reconnecting"}(ke||(ke={}));class et{constructor(e,t,n,r){this._nextKeepAlive=0,Ne.isRequired(e,"connection"),Ne.isRequired(t,"logger"),Ne.isRequired(n,"protocol"),this.serverTimeoutInMilliseconds=3e4,this.keepAliveIntervalInMilliseconds=15e3,this._logger=t,this._protocol=n,this.connection=e,this._reconnectPolicy=r,this._handshakeProtocol=new Qe,this.connection.onreceive=e=>this._processIncomingData(e),this.connection.onclose=e=>this._connectionClosed(e),this._callbacks={},this._methods={},this._closedCallbacks=[],this._reconnectingCallbacks=[],this._reconnectedCallbacks=[],this._invocationId=0,this._receivedHandshakeResponse=!1,this._connectionState=ke.Disconnected,this._connectionStarted=!1,this._cachedPingMessage=this._protocol.writeMessage({type:Ie.Ping})}static create(e,t,n,r){return new et(e,t,n,r)}get state(){return this._connectionState}get connectionId(){return this.connection&&this.connection.connectionId||null}get baseUrl(){return this.connection.baseUrl||""}set baseUrl(e){if(this._connectionState!==ke.Disconnected&&this._connectionState!==ke.Reconnecting)throw new Error("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");if(!e)throw new Error("The HubConnection url must be a valid url.");this.connection.baseUrl=e}start(){return this._startPromise=this._startWithStateTransitions(),this._startPromise}async _startWithStateTransitions(){if(this._connectionState!==ke.Disconnected)return Promise.reject(new Error("Cannot start a HubConnection that is not in the 'Disconnected' state."));this._connectionState=ke.Connecting,this._logger.log(Ee.Debug,"Starting HubConnection.");try{await this._startInternal(),this._connectionState=ke.Connected,this._connectionStarted=!0,this._logger.log(Ee.Debug,"HubConnection connected successfully.")}catch(e){return this._connectionState=ke.Disconnected,this._logger.log(Ee.Debug,`HubConnection failed to start successfully because of error '${e}'.`),Promise.reject(e)}}async _startInternal(){this._stopDuringStartError=void 0,this._receivedHandshakeResponse=!1;const e=new Promise(((e,t)=>{this._handshakeResolver=e,this._handshakeRejecter=t}));await this.connection.start(this._protocol.transferFormat);try{const t={protocol:this._protocol.name,version:this._protocol.version};if(this._logger.log(Ee.Debug,"Sending handshake request."),await this._sendMessage(this._handshakeProtocol.writeHandshakeRequest(t)),this._logger.log(Ee.Information,`Using HubProtocol '${this._protocol.name}'.`),this._cleanupTimeout(),this._resetTimeoutPeriod(),this._resetKeepAliveInterval(),await e,this._stopDuringStartError)throw this._stopDuringStartError}catch(e){throw this._logger.log(Ee.Debug,`Hub handshake failed with error '${e}' during start(). Stopping HubConnection.`),this._cleanupTimeout(),this._cleanupPingTimer(),await this.connection.stop(e),e}}async stop(){const e=this._startPromise;this._stopPromise=this._stopInternal(),await this._stopPromise;try{await e}catch(e){}}_stopInternal(e){return this._connectionState===ke.Disconnected?(this._logger.log(Ee.Debug,`Call to HubConnection.stop(${e}) ignored because it is already in the disconnected state.`),Promise.resolve()):this._connectionState===ke.Disconnecting?(this._logger.log(Ee.Debug,`Call to HttpConnection.stop(${e}) ignored because the connection is already in the disconnecting state.`),this._stopPromise):(this._connectionState=ke.Disconnecting,this._logger.log(Ee.Debug,"Stopping HubConnection."),this._reconnectDelayHandle?(this._logger.log(Ee.Debug,"Connection stopped during reconnect delay. Done reconnecting."),clearTimeout(this._reconnectDelayHandle),this._reconnectDelayHandle=void 0,this._completeClose(),Promise.resolve()):(this._cleanupTimeout(),this._cleanupPingTimer(),this._stopDuringStartError=e||new Error("The connection was stopped before the hub handshake could complete."),this.connection.stop(e)))}stream(e,...t){const[n,r]=this._replaceStreamingParams(t),o=this._createStreamInvocation(e,t,r);let i;const s=new Ze;return s.cancelCallback=()=>{const e=this._createCancelInvocation(o.invocationId);return delete this._callbacks[o.invocationId],i.then((()=>this._sendWithProtocol(e)))},this._callbacks[o.invocationId]=(e,t)=>{t?s.error(t):e&&(e.type===Ie.Completion?e.error?s.error(new Error(e.error)):s.complete():s.next(e.item))},i=this._sendWithProtocol(o).catch((e=>{s.error(e),delete this._callbacks[o.invocationId]})),this._launchStreams(n,i),s}_sendMessage(e){return this._resetKeepAliveInterval(),this.connection.send(e)}_sendWithProtocol(e){return this._sendMessage(this._protocol.writeMessage(e))}send(e,...t){const[n,r]=this._replaceStreamingParams(t),o=this._sendWithProtocol(this._createInvocation(e,t,!0,r));return this._launchStreams(n,o),o}invoke(e,...t){const[n,r]=this._replaceStreamingParams(t),o=this._createInvocation(e,t,!1,r);return new Promise(((e,t)=>{this._callbacks[o.invocationId]=(n,r)=>{r?t(r):n&&(n.type===Ie.Completion?n.error?t(new Error(n.error)):e(n.result):t(new Error(`Unexpected message type: ${n.type}`)))};const r=this._sendWithProtocol(o).catch((e=>{t(e),delete this._callbacks[o.invocationId]}));this._launchStreams(n,r)}))}on(e,t){e&&t&&(e=e.toLowerCase(),this._methods[e]||(this._methods[e]=[]),-1===this._methods[e].indexOf(t)&&this._methods[e].push(t))}off(e,t){if(!e)return;e=e.toLowerCase();const n=this._methods[e];if(n)if(t){const r=n.indexOf(t);-1!==r&&(n.splice(r,1),0===n.length&&delete this._methods[e])}else delete this._methods[e]}onclose(e){e&&this._closedCallbacks.push(e)}onreconnecting(e){e&&this._reconnectingCallbacks.push(e)}onreconnected(e){e&&this._reconnectedCallbacks.push(e)}_processIncomingData(e){if(this._cleanupTimeout(),this._receivedHandshakeResponse||(e=this._processHandshakeResponse(e),this._receivedHandshakeResponse=!0),e){const t=this._protocol.parseMessages(e,this._logger);for(const e of t)switch(e.type){case Ie.Invocation:this._invokeClientMethod(e);break;case Ie.StreamItem:case Ie.Completion:{const t=this._callbacks[e.invocationId];t&&(e.type===Ie.Completion&&delete this._callbacks[e.invocationId],t(e));break}case Ie.Ping:break;case Ie.Close:{this._logger.log(Ee.Information,"Close message received from server.");const t=e.error?new Error("Server returned an error on close: "+e.error):void 0;!0===e.allowReconnect?this.connection.stop(t):this._stopPromise=this._stopInternal(t);break}default:this._logger.log(Ee.Warning,`Invalid message type: ${e.type}.`)}}this._resetTimeoutPeriod()}_processHandshakeResponse(e){let t,n;try{[n,t]=this._handshakeProtocol.parseHandshakeResponse(e)}catch(e){const t="Error parsing handshake response: "+e;this._logger.log(Ee.Error,t);const n=new Error(t);throw this._handshakeRejecter(n),n}if(t.error){const e="Server returned handshake error: "+t.error;this._logger.log(Ee.Error,e);const n=new Error(e);throw this._handshakeRejecter(n),n}return this._logger.log(Ee.Debug,"Server handshake complete."),this._handshakeResolver(),n}_resetKeepAliveInterval(){this.connection.features.inherentKeepAlive||(this._nextKeepAlive=(new Date).getTime()+this.keepAliveIntervalInMilliseconds,this._cleanupPingTimer())}_resetTimeoutPeriod(){if(!(this.connection.features&&this.connection.features.inherentKeepAlive||(this._timeoutHandle=setTimeout((()=>this.serverTimeout()),this.serverTimeoutInMilliseconds),void 0!==this._pingServerHandle))){let e=this._nextKeepAlive-(new Date).getTime();e<0&&(e=0),this._pingServerHandle=setTimeout((async()=>{if(this._connectionState===ke.Connected)try{await this._sendMessage(this._cachedPingMessage)}catch{this._cleanupPingTimer()}}),e)}}serverTimeout(){this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."))}_invokeClientMethod(e){const t=this._methods[e.target.toLowerCase()];if(t){try{t.forEach((t=>t.apply(this,e.arguments)))}catch(t){this._logger.log(Ee.Error,`A callback for the method ${e.target.toLowerCase()} threw error '${t}'.`)}if(e.invocationId){const e="Server requested a response, which is not supported in this version of the client.";this._logger.log(Ee.Error,e),this._stopPromise=this._stopInternal(new Error(e))}}else this._logger.log(Ee.Warning,`No client method with the name '${e.target}' found.`)}_connectionClosed(e){this._logger.log(Ee.Debug,`HubConnection.connectionClosed(${e}) called while in state ${this._connectionState}.`),this._stopDuringStartError=this._stopDuringStartError||e||new Error("The underlying connection was closed before the hub handshake could complete."),this._handshakeResolver&&this._handshakeResolver(),this._cancelCallbacksWithError(e||new Error("Invocation canceled due to the underlying connection being closed.")),this._cleanupTimeout(),this._cleanupPingTimer(),this._connectionState===ke.Disconnecting?this._completeClose(e):this._connectionState===ke.Connected&&this._reconnectPolicy?this._reconnect(e):this._connectionState===ke.Connected&&this._completeClose(e)}_completeClose(e){if(this._connectionStarted){this._connectionState=ke.Disconnected,this._connectionStarted=!1;try{this._closedCallbacks.forEach((t=>t.apply(this,[e])))}catch(t){this._logger.log(Ee.Error,`An onclose callback called with error '${e}' threw error '${t}'.`)}}}async _reconnect(e){const t=Date.now();let n=0,r=void 0!==e?e:new Error("Attempting to reconnect due to a unknown error."),o=this._getNextRetryDelay(n++,0,r);if(null===o)return this._logger.log(Ee.Debug,"Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt."),void this._completeClose(e);if(this._connectionState=ke.Reconnecting,e?this._logger.log(Ee.Information,`Connection reconnecting because of error '${e}'.`):this._logger.log(Ee.Information,"Connection reconnecting."),0!==this._reconnectingCallbacks.length){try{this._reconnectingCallbacks.forEach((t=>t.apply(this,[e])))}catch(t){this._logger.log(Ee.Error,`An onreconnecting callback called with error '${e}' threw error '${t}'.`)}if(this._connectionState!==ke.Reconnecting)return void this._logger.log(Ee.Debug,"Connection left the reconnecting state in onreconnecting callback. Done reconnecting.")}for(;null!==o;){if(this._logger.log(Ee.Information,`Reconnect attempt number ${n} will start in ${o} ms.`),await new Promise((e=>{this._reconnectDelayHandle=setTimeout(e,o)})),this._reconnectDelayHandle=void 0,this._connectionState!==ke.Reconnecting)return void this._logger.log(Ee.Debug,"Connection left the reconnecting state during reconnect delay. Done reconnecting.");try{if(await this._startInternal(),this._connectionState=ke.Connected,this._logger.log(Ee.Information,"HubConnection reconnected successfully."),0!==this._reconnectedCallbacks.length)try{this._reconnectedCallbacks.forEach((e=>e.apply(this,[this.connection.connectionId])))}catch(e){this._logger.log(Ee.Error,`An onreconnected callback called with connectionId '${this.connection.connectionId}; threw error '${e}'.`)}return}catch(e){if(this._logger.log(Ee.Information,`Reconnect attempt failed because of error '${e}'.`),this._connectionState!==ke.Reconnecting)return this._logger.log(Ee.Debug,`Connection moved to the '${this._connectionState}' from the reconnecting state during reconnect attempt. Done reconnecting.`),void(this._connectionState===ke.Disconnecting&&this._completeClose());r=e instanceof Error?e:new Error(e.toString()),o=this._getNextRetryDelay(n++,Date.now()-t,r)}}this._logger.log(Ee.Information,`Reconnect retries have been exhausted after ${Date.now()-t} ms and ${n} failed attempts. Connection disconnecting.`),this._completeClose()}_getNextRetryDelay(e,t,n){try{return this._reconnectPolicy.nextRetryDelayInMilliseconds({elapsedMilliseconds:t,previousRetryCount:e,retryReason:n})}catch(n){return this._logger.log(Ee.Error,`IRetryPolicy.nextRetryDelayInMilliseconds(${e}, ${t}) threw error '${n}'.`),null}}_cancelCallbacksWithError(e){const t=this._callbacks;this._callbacks={},Object.keys(t).forEach((n=>{(0,t[n])(null,e)}))}_cleanupPingTimer(){this._pingServerHandle&&(clearTimeout(this._pingServerHandle),this._pingServerHandle=void 0)}_cleanupTimeout(){this._timeoutHandle&&clearTimeout(this._timeoutHandle)}_createInvocation(e,t,n,r){if(n)return 0!==r.length?{arguments:t,streamIds:r,target:e,type:Ie.Invocation}:{arguments:t,target:e,type:Ie.Invocation};{const n=this._invocationId;return this._invocationId++,0!==r.length?{arguments:t,invocationId:n.toString(),streamIds:r,target:e,type:Ie.Invocation}:{arguments:t,invocationId:n.toString(),target:e,type:Ie.Invocation}}}_launchStreams(e,t){if(0!==e.length){t||(t=Promise.resolve());for(const n in e)e[n].subscribe({complete:()=>{t=t.then((()=>this._sendWithProtocol(this._createCompletionMessage(n))))},error:e=>{let r;r=e instanceof Error?e.message:e&&e.toString?e.toString():"Unknown error",t=t.then((()=>this._sendWithProtocol(this._createCompletionMessage(n,r))))},next:e=>{t=t.then((()=>this._sendWithProtocol(this._createStreamItemMessage(n,e))))}})}}_replaceStreamingParams(e){const t=[],n=[];for(let r=0;r=55296&&o<=56319&&r65535&&(h-=65536,i.push(h>>>10&1023|55296),h=56320|1023&h),i.push(h)}else i.push(a);i.length>=4096&&(s+=String.fromCharCode.apply(String,i),i.length=0)}return i.length>0&&(s+=String.fromCharCode.apply(String,i)),s}var ut=ot?new TextDecoder:null,dt=ot?"undefined"!=typeof process&&"force"!==process.env.TEXT_DECODER?200:0:it,pt=function(e,t){this.type=e,this.data=t};function ft(e,t,n){var r=Math.floor(n/4294967296),o=n;e.setUint32(t,r),e.setUint32(t+4,o)}function gt(e,t){return 4294967296*e.getInt32(t)+e.getUint32(t+4)}var mt={type:-1,encode:function(e){var t,n,r,o;return e instanceof Date?function(e){var t,n=e.sec,r=e.nsec;if(n>=0&&r>=0&&n<=17179869183){if(0===r&&n<=4294967295){var o=new Uint8Array(4);return(t=new DataView(o.buffer)).setUint32(0,n),o}var i=n/4294967296,s=4294967295&n;return o=new Uint8Array(8),(t=new DataView(o.buffer)).setUint32(0,r<<2|3&i),t.setUint32(4,s),o}return o=new Uint8Array(12),(t=new DataView(o.buffer)).setUint32(0,r),ft(t,4,n),o}((r=1e6*((t=e.getTime())-1e3*(n=Math.floor(t/1e3))),{sec:n+(o=Math.floor(r/1e9)),nsec:r-1e9*o})):null},decode:function(e){var t=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);switch(e.byteLength){case 4:return{sec:t.getUint32(0),nsec:0};case 8:var n=t.getUint32(0);return{sec:4294967296*(3&n)+t.getUint32(4),nsec:n>>>2};case 12:return{sec:gt(t,4),nsec:t.getUint32(0)};default:throw new Error("Unrecognized data size for timestamp: "+e.length)}}(e);return new Date(1e3*t.sec+t.nsec/1e6)}},yt=function(){function e(){this.builtInEncoders=[],this.builtInDecoders=[],this.encoders=[],this.decoders=[],this.register(mt)}return e.prototype.register=function(e){var t=e.type,n=e.encode,r=e.decode;if(t>=0)this.encoders[t]=n,this.decoders[t]=r;else{var o=1+t;this.builtInEncoders[o]=n,this.builtInDecoders[o]=r}},e.prototype.tryToEncode=function(e,t){for(var n=0;nthis.maxDepth)throw new Error("Too deep objects in depth "+t);null==e?this.encodeNil():"boolean"==typeof e?this.encodeBoolean(e):"number"==typeof e?this.encodeNumber(e):"string"==typeof e?this.encodeString(e):this.encodeObject(e,t)},e.prototype.ensureBufferSizeToWrite=function(e){var t=this.pos+e;this.view.byteLength=0?e<128?this.writeU8(e):e<256?(this.writeU8(204),this.writeU8(e)):e<65536?(this.writeU8(205),this.writeU16(e)):e<4294967296?(this.writeU8(206),this.writeU32(e)):(this.writeU8(207),this.writeU64(e)):e>=-32?this.writeU8(224|e+32):e>=-128?(this.writeU8(208),this.writeI8(e)):e>=-32768?(this.writeU8(209),this.writeI16(e)):e>=-2147483648?(this.writeU8(210),this.writeI32(e)):(this.writeU8(211),this.writeI64(e)):this.forceFloat32?(this.writeU8(202),this.writeF32(e)):(this.writeU8(203),this.writeF64(e))},e.prototype.writeStringHeader=function(e){if(e<32)this.writeU8(160+e);else if(e<256)this.writeU8(217),this.writeU8(e);else if(e<65536)this.writeU8(218),this.writeU16(e);else{if(!(e<4294967296))throw new Error("Too long string: "+e+" bytes in UTF-8");this.writeU8(219),this.writeU32(e)}},e.prototype.encodeString=function(e){if(e.length>ct){var t=st(e);this.ensureBufferSizeToWrite(5+t),this.writeStringHeader(t),lt(e,this.bytes,this.pos),this.pos+=t}else t=st(e),this.ensureBufferSizeToWrite(5+t),this.writeStringHeader(t),function(e,t,n){for(var r=e.length,o=n,i=0;i>6&31|192;else{if(s>=55296&&s<=56319&&i>12&15|224,t[o++]=s>>6&63|128):(t[o++]=s>>18&7|240,t[o++]=s>>12&63|128,t[o++]=s>>6&63|128)}t[o++]=63&s|128}else t[o++]=s}}(e,this.bytes,this.pos),this.pos+=t},e.prototype.encodeObject=function(e,t){var n=this.extensionCodec.tryToEncode(e,this.context);if(null!=n)this.encodeExtension(n);else if(Array.isArray(e))this.encodeArray(e,t);else if(ArrayBuffer.isView(e))this.encodeBinary(e);else{if("object"!=typeof e)throw new Error("Unrecognized object: "+Object.prototype.toString.apply(e));this.encodeMap(e,t)}},e.prototype.encodeBinary=function(e){var t=e.byteLength;if(t<256)this.writeU8(196),this.writeU8(t);else if(t<65536)this.writeU8(197),this.writeU16(t);else{if(!(t<4294967296))throw new Error("Too large binary: "+t);this.writeU8(198),this.writeU32(t)}var n=wt(e);this.writeU8a(n)},e.prototype.encodeArray=function(e,t){var n=e.length;if(n<16)this.writeU8(144+n);else if(n<65536)this.writeU8(220),this.writeU16(n);else{if(!(n<4294967296))throw new Error("Too large array: "+n);this.writeU8(221),this.writeU32(n)}for(var r=0,o=e;r0&&e<=this.maxKeyLength},e.prototype.find=function(e,t,n){e:for(var r=0,o=this.caches[n-1];r=this.maxLengthPerKey?n[Math.random()*n.length|0]=r:n.push(r)},e.prototype.decode=function(e,t,n){var r=this.find(e,t,n);if(null!=r)return this.hit++,r;this.miss++;var o=ht(e,t,n),i=Uint8Array.prototype.slice.call(e,t,t+n);return this.store(i,o),o},e}(),St=(_t=function(e,t){return(_t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}_t(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),Ct=function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!((o=(o=s.trys).length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]1||a(e,t)}))})}function a(e,t){try{(n=o[e](t)).value instanceof kt?Promise.resolve(n.value.v).then(c,l):h(i[0][2],n)}catch(e){h(i[0][3],e)}var n}function c(e){a("next",e)}function l(e){a("throw",e)}function h(e,t){e(t),i.shift(),i.length&&a(i[0][0],i[0][1])}},xt=new DataView(new ArrayBuffer(0)),Dt=new Uint8Array(xt.buffer),Rt=function(){try{xt.getInt8(0)}catch(e){return e.constructor}throw new Error("never reached")}(),Pt=new Rt("Insufficient data"),Ut=4294967295,At=new Et,Nt=function(e){function t(n){var r=e.call(this,n)||this,o=Object.create(t.prototype);return Object.setPrototypeOf(r,o),Object.defineProperty(r,"name",{configurable:!0,enumerable:!1,value:t.name}),r}return St(t,e),t}(Error),$t=function(){function e(e,t,n,r,o,i,s,a){void 0===e&&(e=yt.defaultCodec),void 0===t&&(t=void 0),void 0===n&&(n=Ut),void 0===r&&(r=Ut),void 0===o&&(o=Ut),void 0===i&&(i=Ut),void 0===s&&(s=Ut),void 0===a&&(a=At),this.extensionCodec=e,this.context=t,this.maxStrLength=n,this.maxBinLength=r,this.maxArrayLength=o,this.maxMapLength=i,this.maxExtLength=s,this.keyDecoder=a,this.totalPos=0,this.pos=0,this.view=xt,this.bytes=Dt,this.headByte=-1,this.stack=[]}return e.prototype.reinitializeState=function(){this.totalPos=0,this.headByte=-1,this.stack.length=0},e.prototype.setBuffer=function(e){this.bytes=wt(e),this.view=function(e){if(e instanceof ArrayBuffer)return new DataView(e);var t=wt(e);return new DataView(t.buffer,t.byteOffset,t.byteLength)}(this.bytes),this.pos=0},e.prototype.appendBuffer=function(e){if(-1!==this.headByte||this.hasRemaining()){var t=this.bytes.subarray(this.pos),n=wt(e),r=new Uint8Array(t.length+n.length);r.set(t),r.set(n,t.length),this.setBuffer(r)}else this.setBuffer(e)},e.prototype.hasRemaining=function(e){return void 0===e&&(e=1),this.view.byteLength-this.pos>=e},e.prototype.createExtraByteError=function(e){var t=this.view,n=this.pos;return new RangeError("Extra "+(t.byteLength-n)+" of "+t.byteLength+" byte(s) found at buffer["+e+"]")},e.prototype.decode=function(e){this.reinitializeState(),this.setBuffer(e);var t=this.doDecodeSync();if(this.hasRemaining())throw this.createExtraByteError(this.pos);return t},e.prototype.decodeMulti=function(e){return Ct(this,(function(t){switch(t.label){case 0:this.reinitializeState(),this.setBuffer(e),t.label=1;case 1:return this.hasRemaining()?[4,this.doDecodeSync()]:[3,3];case 2:return t.sent(),[3,1];case 3:return[2]}}))},e.prototype.decodeAsync=function(e){var t,n,r,o,i,s,a;return i=this,void 0,a=function(){var i,s,a,c,l,h,u,d;return Ct(this,(function(p){switch(p.label){case 0:i=!1,p.label=1;case 1:p.trys.push([1,6,7,12]),t=It(e),p.label=2;case 2:return[4,t.next()];case 3:if((n=p.sent()).done)return[3,5];if(a=n.value,i)throw this.createExtraByteError(this.totalPos);this.appendBuffer(a);try{s=this.doDecodeSync(),i=!0}catch(e){if(!(e instanceof Rt))throw e}this.totalPos+=this.pos,p.label=4;case 4:return[3,2];case 5:return[3,12];case 6:return c=p.sent(),r={error:c},[3,12];case 7:return p.trys.push([7,,10,11]),n&&!n.done&&(o=t.return)?[4,o.call(t)]:[3,9];case 8:p.sent(),p.label=9;case 9:return[3,11];case 10:if(r)throw r.error;return[7];case 11:return[7];case 12:if(i){if(this.hasRemaining())throw this.createExtraByteError(this.totalPos);return[2,s]}throw h=(l=this).headByte,u=l.pos,d=l.totalPos,new RangeError("Insufficient data in parsing "+bt(h)+" at "+d+" ("+u+" in the current buffer)")}}))},new((s=void 0)||(s=Promise))((function(e,t){function n(e){try{o(a.next(e))}catch(e){t(e)}}function r(e){try{o(a.throw(e))}catch(e){t(e)}}function o(t){var o;t.done?e(t.value):(o=t.value,o instanceof s?o:new s((function(e){e(o)}))).then(n,r)}o((a=a.apply(i,[])).next())}))},e.prototype.decodeArrayStream=function(e){return this.decodeMultiAsync(e,!0)},e.prototype.decodeStream=function(e){return this.decodeMultiAsync(e,!1)},e.prototype.decodeMultiAsync=function(e,t){return Tt(this,arguments,(function(){var n,r,o,i,s,a,c,l,h;return Ct(this,(function(u){switch(u.label){case 0:n=t,r=-1,u.label=1;case 1:u.trys.push([1,13,14,19]),o=It(e),u.label=2;case 2:return[4,kt(o.next())];case 3:if((i=u.sent()).done)return[3,12];if(s=i.value,t&&0===r)throw this.createExtraByteError(this.totalPos);this.appendBuffer(s),n&&(r=this.readArraySize(),n=!1,this.complete()),u.label=4;case 4:u.trys.push([4,9,,10]),u.label=5;case 5:return[4,kt(this.doDecodeSync())];case 6:return[4,u.sent()];case 7:return u.sent(),0==--r?[3,8]:[3,5];case 8:return[3,10];case 9:if(!((a=u.sent())instanceof Rt))throw a;return[3,10];case 10:this.totalPos+=this.pos,u.label=11;case 11:return[3,2];case 12:return[3,19];case 13:return c=u.sent(),l={error:c},[3,19];case 14:return u.trys.push([14,,17,18]),i&&!i.done&&(h=o.return)?[4,kt(h.call(o))]:[3,16];case 15:u.sent(),u.label=16;case 16:return[3,18];case 17:if(l)throw l.error;return[7];case 18:return[7];case 19:return[2]}}))}))},e.prototype.doDecodeSync=function(){e:for(;;){var e=this.readHeadByte(),t=void 0;if(e>=224)t=e-256;else if(e<192)if(e<128)t=e;else if(e<144){if(0!=(r=e-128)){this.pushMapState(r),this.complete();continue e}t={}}else if(e<160){if(0!=(r=e-144)){this.pushArrayState(r),this.complete();continue e}t=[]}else{var n=e-160;t=this.decodeUtf8String(n,0)}else if(192===e)t=null;else if(194===e)t=!1;else if(195===e)t=!0;else if(202===e)t=this.readF32();else if(203===e)t=this.readF64();else if(204===e)t=this.readU8();else if(205===e)t=this.readU16();else if(206===e)t=this.readU32();else if(207===e)t=this.readU64();else if(208===e)t=this.readI8();else if(209===e)t=this.readI16();else if(210===e)t=this.readI32();else if(211===e)t=this.readI64();else if(217===e)n=this.lookU8(),t=this.decodeUtf8String(n,1);else if(218===e)n=this.lookU16(),t=this.decodeUtf8String(n,2);else if(219===e)n=this.lookU32(),t=this.decodeUtf8String(n,4);else if(220===e){if(0!==(r=this.readU16())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(221===e){if(0!==(r=this.readU32())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(222===e){if(0!==(r=this.readU16())){this.pushMapState(r),this.complete();continue e}t={}}else if(223===e){if(0!==(r=this.readU32())){this.pushMapState(r),this.complete();continue e}t={}}else if(196===e){var r=this.lookU8();t=this.decodeBinary(r,1)}else if(197===e)r=this.lookU16(),t=this.decodeBinary(r,2);else if(198===e)r=this.lookU32(),t=this.decodeBinary(r,4);else if(212===e)t=this.decodeExtension(1,0);else if(213===e)t=this.decodeExtension(2,0);else if(214===e)t=this.decodeExtension(4,0);else if(215===e)t=this.decodeExtension(8,0);else if(216===e)t=this.decodeExtension(16,0);else if(199===e)r=this.lookU8(),t=this.decodeExtension(r,1);else if(200===e)r=this.lookU16(),t=this.decodeExtension(r,2);else{if(201!==e)throw new Nt("Unrecognized type byte: "+bt(e));r=this.lookU32(),t=this.decodeExtension(r,4)}this.complete();for(var o=this.stack;o.length>0;){var i=o[o.length-1];if(0===i.type){if(i.array[i.position]=t,i.position++,i.position!==i.size)continue e;o.pop(),t=i.array}else{if(1===i.type){if("string"!=(s=typeof t)&&"number"!==s)throw new Nt("The type of key must be string or number but "+typeof t);if("__proto__"===t)throw new Nt("The key __proto__ is not allowed");i.key=t,i.type=2;continue e}if(i.map[i.key]=t,i.readCount++,i.readCount!==i.size){i.key=null,i.type=1;continue e}o.pop(),t=i.map}}return t}var s},e.prototype.readHeadByte=function(){return-1===this.headByte&&(this.headByte=this.readU8()),this.headByte},e.prototype.complete=function(){this.headByte=-1},e.prototype.readArraySize=function(){var e=this.readHeadByte();switch(e){case 220:return this.readU16();case 221:return this.readU32();default:if(e<160)return e-144;throw new Nt("Unrecognized array type byte: "+bt(e))}},e.prototype.pushMapState=function(e){if(e>this.maxMapLength)throw new Nt("Max length exceeded: map length ("+e+") > maxMapLengthLength ("+this.maxMapLength+")");this.stack.push({type:1,size:e,key:null,readCount:0,map:{}})},e.prototype.pushArrayState=function(e){if(e>this.maxArrayLength)throw new Nt("Max length exceeded: array length ("+e+") > maxArrayLength ("+this.maxArrayLength+")");this.stack.push({type:0,size:e,array:new Array(e),position:0})},e.prototype.decodeUtf8String=function(e,t){var n;if(e>this.maxStrLength)throw new Nt("Max length exceeded: UTF-8 byte length ("+e+") > maxStrLength ("+this.maxStrLength+")");if(this.bytes.byteLengthdt?function(e,t,n){var r=e.subarray(t,t+n);return ut.decode(r)}(this.bytes,o,e):ht(this.bytes,o,e),this.pos+=t+e,r},e.prototype.stateIsMapKey=function(){return this.stack.length>0&&1===this.stack[this.stack.length-1].type},e.prototype.decodeBinary=function(e,t){if(e>this.maxBinLength)throw new Nt("Max length exceeded: bin length ("+e+") > maxBinLength ("+this.maxBinLength+")");if(!this.hasRemaining(e+t))throw Pt;var n=this.pos+t,r=this.bytes.subarray(n,n+e);return this.pos+=t+e,r},e.prototype.decodeExtension=function(e,t){if(e>this.maxExtLength)throw new Nt("Max length exceeded: ext length ("+e+") > maxExtLength ("+this.maxExtLength+")");var n=this.view.getInt8(this.pos+t),r=this.decodeBinary(e,t+1);return this.extensionCodec.decode(r,n,this.context)},e.prototype.lookU8=function(){return this.view.getUint8(this.pos)},e.prototype.lookU16=function(){return this.view.getUint16(this.pos)},e.prototype.lookU32=function(){return this.view.getUint32(this.pos)},e.prototype.readU8=function(){var e=this.view.getUint8(this.pos);return this.pos++,e},e.prototype.readI8=function(){var e=this.view.getInt8(this.pos);return this.pos++,e},e.prototype.readU16=function(){var e=this.view.getUint16(this.pos);return this.pos+=2,e},e.prototype.readI16=function(){var e=this.view.getInt16(this.pos);return this.pos+=2,e},e.prototype.readU32=function(){var e=this.view.getUint32(this.pos);return this.pos+=4,e},e.prototype.readI32=function(){var e=this.view.getInt32(this.pos);return this.pos+=4,e},e.prototype.readU64=function(){var e,t,n=(e=this.view,t=this.pos,4294967296*e.getUint32(t)+e.getUint32(t+4));return this.pos+=8,n},e.prototype.readI64=function(){var e=gt(this.view,this.pos);return this.pos+=8,e},e.prototype.readF32=function(){var e=this.view.getFloat32(this.pos);return this.pos+=4,e},e.prototype.readF64=function(){var e=this.view.getFloat64(this.pos);return this.pos+=8,e},e}();class Bt{static write(e){let t=e.byteLength||e.length;const n=[];do{let e=127&t;t>>=7,t>0&&(e|=128),n.push(e)}while(t>0);t=e.byteLength||e.length;const r=new Uint8Array(n.length+t);return r.set(n,0),r.set(e,n.length),r.buffer}static parse(e){const t=[],n=new Uint8Array(e),r=[0,7,14,21,28];for(let o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+s+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+s,o+s+a):n.subarray(o+s,o+s+a)),o=o+s+a}return t}}const Mt=new Uint8Array([145,Ie.Ping]);class Lt{constructor(e){this.name="messagepack",this.version=1,this.transferFormat=Ce.Binary,this._errorResult=1,this._voidResult=2,this._nonVoidResult=3,e=e||{},this._encoder=new vt(e.extensionCodec,e.context,e.maxDepth,e.initialBufferSize,e.sortKeys,e.forceFloat32,e.ignoreUndefined,e.forceIntegerToFloat),this._decoder=new $t(e.extensionCodec,e.context,e.maxStrLength,e.maxBinLength,e.maxArrayLength,e.maxMapLength,e.maxExtLength)}parseMessages(e,t){if(!(n=e)||"undefined"==typeof ArrayBuffer||!(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer.");var n;null===t&&(t=Ae.instance);const r=Bt.parse(e),o=[];for(const e of r){const n=this._parseMessage(e,t);n&&o.push(n)}return o}writeMessage(e){switch(e.type){case Ie.Invocation:return this._writeInvocation(e);case Ie.StreamInvocation:return this._writeStreamInvocation(e);case Ie.StreamItem:return this._writeStreamItem(e);case Ie.Completion:return this._writeCompletion(e);case Ie.Ping:return Bt.write(Mt);case Ie.CancelInvocation:return this._writeCancelInvocation(e);default:throw new Error("Invalid message type.")}}_parseMessage(e,t){if(0===e.length)throw new Error("Invalid payload.");const n=this._decoder.decode(e);if(0===n.length||!(n instanceof Array))throw new Error("Invalid payload.");const r=n[0];switch(r){case Ie.Invocation:return this._createInvocationMessage(this._readHeaders(n),n);case Ie.StreamItem:return this._createStreamItemMessage(this._readHeaders(n),n);case Ie.Completion:return this._createCompletionMessage(this._readHeaders(n),n);case Ie.Ping:return this._createPingMessage(n);case Ie.Close:return this._createCloseMessage(n);default:return t.log(Ee.Information,"Unknown message type '"+r+"' ignored."),null}}_createCloseMessage(e){if(e.length<2)throw new Error("Invalid payload for Close message.");return{allowReconnect:e.length>=3?e[2]:void 0,error:e[1],type:Ie.Close}}_createPingMessage(e){if(e.length<1)throw new Error("Invalid payload for Ping message.");return{type:Ie.Ping}}_createInvocationMessage(e,t){if(t.length<5)throw new Error("Invalid payload for Invocation message.");const n=t[2];return n?{arguments:t[4],headers:e,invocationId:n,streamIds:[],target:t[3],type:Ie.Invocation}:{arguments:t[4],headers:e,streamIds:[],target:t[3],type:Ie.Invocation}}_createStreamItemMessage(e,t){if(t.length<4)throw new Error("Invalid payload for StreamItem message.");return{headers:e,invocationId:t[2],item:t[3],type:Ie.StreamItem}}_createCompletionMessage(e,t){if(t.length<4)throw new Error("Invalid payload for Completion message.");const n=t[3];if(n!==this._voidResult&&t.length<5)throw new Error("Invalid payload for Completion message.");let r,o;switch(n){case this._errorResult:r=t[4];break;case this._nonVoidResult:o=t[4]}return{error:r,headers:e,invocationId:t[2],result:o,type:Ie.Completion}}_writeInvocation(e){let t;return t=e.streamIds?this._encoder.encode([Ie.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments,e.streamIds]):this._encoder.encode([Ie.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments]),Bt.write(t.slice())}_writeStreamInvocation(e){let t;return t=e.streamIds?this._encoder.encode([Ie.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments,e.streamIds]):this._encoder.encode([Ie.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments]),Bt.write(t.slice())}_writeStreamItem(e){const t=this._encoder.encode([Ie.StreamItem,e.headers||{},e.invocationId,e.item]);return Bt.write(t.slice())}_writeCompletion(e){const t=e.error?this._errorResult:e.result?this._nonVoidResult:this._voidResult;let n;switch(t){case this._errorResult:n=this._encoder.encode([Ie.Completion,e.headers||{},e.invocationId,t,e.error]);break;case this._voidResult:n=this._encoder.encode([Ie.Completion,e.headers||{},e.invocationId,t]);break;case this._nonVoidResult:n=this._encoder.encode([Ie.Completion,e.headers||{},e.invocationId,t,e.result])}return Bt.write(n.slice())}_writeCancelInvocation(e){const t=this._encoder.encode([Ie.CancelInvocation,e.headers||{},e.invocationId]);return Bt.write(t.slice())}_readHeaders(e){const t=e[1];if("object"!=typeof t)throw new Error("Invalid headers.");return t}}let Ht=!1;const Ot="function"==typeof TextDecoder?new TextDecoder("utf-8"):null,Ft=Ot?Ot.decode.bind(Ot):function(e){let t=0;const n=e.length,r=[],o=[];for(;t65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")},jt=Math.pow(2,32),Wt=Math.pow(2,21)-1;function zt(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24}function qt(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}function Jt(e,t){const n=qt(e,t+4);if(n>Wt)throw new Error(`Cannot read uint64 with high order part ${n}, because the result would exceed Number.MAX_SAFE_INTEGER.`);return n*jt+qt(e,t)}class Kt{constructor(e){this.batchData=e;const t=new Gt(e);this.arrayRangeReader=new Qt(e),this.arrayBuilderSegmentReader=new Zt(e),this.diffReader=new Vt(e),this.editReader=new Xt(e,t),this.frameReader=new Yt(e,t)}updatedComponents(){return zt(this.batchData,this.batchData.length-20)}referenceFrames(){return zt(this.batchData,this.batchData.length-16)}disposedComponentIds(){return zt(this.batchData,this.batchData.length-12)}disposedEventHandlerIds(){return zt(this.batchData,this.batchData.length-8)}updatedComponentsEntry(e,t){const n=e+4*t;return zt(this.batchData,n)}referenceFramesEntry(e,t){return e+20*t}disposedComponentIdsEntry(e,t){const n=e+4*t;return zt(this.batchData,n)}disposedEventHandlerIdsEntry(e,t){const n=e+8*t;return Jt(this.batchData,n)}}class Vt{constructor(e){this.batchDataUint8=e}componentId(e){return zt(this.batchDataUint8,e)}edits(e){return e+4}editsEntry(e,t){return e+16*t}}class Xt{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}editType(e){return zt(this.batchDataUint8,e)}siblingIndex(e){return zt(this.batchDataUint8,e+4)}newTreeIndex(e){return zt(this.batchDataUint8,e+8)}moveToSiblingIndex(e){return zt(this.batchDataUint8,e+8)}removedAttributeName(e){const t=zt(this.batchDataUint8,e+12);return this.stringReader.readString(t)}}class Yt{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}frameType(e){return zt(this.batchDataUint8,e)}subtreeLength(e){return zt(this.batchDataUint8,e+4)}elementReferenceCaptureId(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}componentId(e){return zt(this.batchDataUint8,e+8)}elementName(e){const t=zt(this.batchDataUint8,e+8);return this.stringReader.readString(t)}textContent(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}markupContent(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeName(e){const t=zt(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeValue(e){const t=zt(this.batchDataUint8,e+8);return this.stringReader.readString(t)}attributeEventHandlerId(e){return Jt(this.batchDataUint8,e+12)}}class Gt{constructor(e){this.batchDataUint8=e,this.stringTableStartIndex=zt(e,e.length-4)}readString(e){if(-1===e)return null;{const n=zt(this.batchDataUint8,this.stringTableStartIndex+4*e),r=function(e,t){let n=0,r=0;for(let o=0;o<4;o++){const i=e[t+o];if(n|=(127&i)<this.nextBatchId)return this.fatalError?(this.logger.log(en.Debug,`Received a new batch ${e} but errored out on a previous batch ${this.nextBatchId-1}`),void await n.send("OnRenderCompleted",this.nextBatchId-1,this.fatalError.toString())):void this.logger.log(en.Debug,`Waiting for batch ${this.nextBatchId}. Batch ${e} not processed.`);try{this.nextBatchId++,this.logger.log(en.Debug,`Applying batch ${e}.`),function(e,t){const n=Q[e];if(!n)throw new Error(`There is no browser renderer with ID ${e}.`);const r=t.arrayRangeReader,o=t.updatedComponents(),i=r.values(o),s=r.count(o),a=t.referenceFrames(),c=r.values(a),l=t.diffReader;for(let e=0;e=this.minLevel){const n=`[${(new Date).toISOString()}] ${en[e]}: ${t}`;switch(e){case en.Critical:case en.Error:console.error(n);break;case en.Warning:console.warn(n);break;case en.Information:console.info(n);break;default:console.log(n)}}}}class on{constructor(e,t){this.circuitId=void 0,this.components=e,this.applicationState=t}reconnect(e){if(!this.circuitId)throw new Error("Circuit host not initialized.");return e.state!==ke.Connected?Promise.resolve(!1):e.invoke("ConnectCircuit",this.circuitId)}initialize(e){if(this.circuitId)throw new Error(`Circuit host '${this.circuitId}' already initialized.`);this.circuitId=e}async startCircuit(e){if(e.state!==ke.Connected)return!1;const t=await e.invoke("StartCircuit",re.getBaseURI(),re.getLocationHref(),JSON.stringify(this.components.map((e=>e.toRecord()))),this.applicationState||"");return!!t&&(this.initialize(t),!0)}resolveElement(e){const t=Number.parseInt(e);if(Number.isNaN(t))throw new Error(`Invalid sequence number '${e}'.`);return function(e,t){if(!e.parentNode)throw new Error(`Comment not connected to the DOM ${e.textContent}`);const n=e.parentNode,r=k(n,!0),o=A(r);return Array.from(n.childNodes).forEach((e=>o.push(e))),e[C]=r,t&&(e[I]=t,k(t)),k(e)}(this.components[t].start,this.components[t].end)}}const sn={configureSignalR:e=>{},logLevel:en.Warning,reconnectionOptions:{maxRetries:8,retryIntervalMilliseconds:2e4,dialogId:"components-reconnect-modal"}};class an{constructor(e,t,n,r){this.maxRetries=t,this.document=n,this.logger=r,this.addedToDom=!1,this.modal=this.document.createElement("div"),this.modal.id=e,this.maxRetries=t,this.modal.style.cssText=["position: fixed","top: 0","right: 0","bottom: 0","left: 0","z-index: 1050","display: none","overflow: hidden","background-color: #fff","opacity: 0.8","text-align: center","font-weight: bold","transition: visibility 0s linear 500ms"].join(";"),this.modal.innerHTML='

Alternatively, reload

',this.message=this.modal.querySelector("h5"),this.button=this.modal.querySelector("button"),this.reloadParagraph=this.modal.querySelector("p"),this.loader=this.getLoader(),this.message.after(this.loader),this.button.addEventListener("click",(async()=>{this.show();try{await(null==fe?void 0:fe.reconnect)()||this.rejected()}catch(e){this.logger.log(en.Error,e),this.failed()}})),this.reloadParagraph.querySelector("a").addEventListener("click",(()=>location.reload()))}show(){this.addedToDom||(this.addedToDom=!0,this.document.body.appendChild(this.modal)),this.modal.style.display="block",this.loader.style.display="inline-block",this.button.style.display="none",this.reloadParagraph.style.display="none",this.message.textContent="Attempting to reconnect to the server...",this.modal.style.visibility="hidden",setTimeout((()=>{this.modal.style.visibility="visible"}),0)}update(e){this.message.textContent=`Attempting to reconnect to the server: ${e} of ${this.maxRetries}`}hide(){this.modal.style.display="none"}failed(){this.button.style.display="block",this.reloadParagraph.style.display="none",this.loader.style.display="none",this.message.innerHTML="Reconnection failed. Try reloading the page if you're unable to reconnect.",this.message.querySelector("a").addEventListener("click",(()=>location.reload()))}rejected(){this.button.style.display="none",this.reloadParagraph.style.display="none",this.loader.style.display="none",this.message.innerHTML="Could not reconnect to the server. Reload the page to restore functionality.",this.message.querySelector("a").addEventListener("click",(()=>location.reload()))}getLoader(){const e=this.document.createElement("div");return e.style.cssText=["border: 0.3em solid #f3f3f3","border-top: 0.3em solid #3498db","border-radius: 50%","width: 2em","height: 2em","display: inline-block"].join(";"),e.animate([{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],{duration:2e3,iterations:1/0}),e}}class cn{constructor(e,t,n){this.dialog=e,this.maxRetries=t,this.document=n,this.document=n;const r=this.document.getElementById(cn.MaxRetriesId);r&&(r.innerText=this.maxRetries.toString())}show(){this.removeClasses(),this.dialog.classList.add(cn.ShowClassName)}update(e){const t=this.document.getElementById(cn.CurrentAttemptId);t&&(t.innerText=e.toString())}hide(){this.removeClasses(),this.dialog.classList.add(cn.HideClassName)}failed(){this.removeClasses(),this.dialog.classList.add(cn.FailedClassName)}rejected(){this.removeClasses(),this.dialog.classList.add(cn.RejectedClassName)}removeClasses(){this.dialog.classList.remove(cn.ShowClassName,cn.HideClassName,cn.FailedClassName,cn.RejectedClassName)}}cn.ShowClassName="components-reconnect-show",cn.HideClassName="components-reconnect-hide",cn.FailedClassName="components-reconnect-failed",cn.RejectedClassName="components-reconnect-rejected",cn.MaxRetriesId="components-reconnect-max-retries",cn.CurrentAttemptId="components-reconnect-current-attempt";class ln{constructor(e,t,n){this._currentReconnectionProcess=null,this._logger=e,this._reconnectionDisplay=t,this._reconnectCallback=n||(()=>fe.reconnect())}onConnectionDown(e,t){if(!this._reconnectionDisplay){const t=document.getElementById(e.dialogId);this._reconnectionDisplay=t?new cn(t,e.maxRetries,document):new an(e.dialogId,e.maxRetries,document,this._logger)}this._currentReconnectionProcess||(this._currentReconnectionProcess=new hn(e,this._logger,this._reconnectCallback,this._reconnectionDisplay))}onConnectionUp(){this._currentReconnectionProcess&&(this._currentReconnectionProcess.dispose(),this._currentReconnectionProcess=null)}}class hn{constructor(e,t,n,r){this.logger=t,this.reconnectCallback=n,this.isDisposed=!1,this.reconnectDisplay=r,this.reconnectDisplay.show(),this.attemptPeriodicReconnection(e)}dispose(){this.isDisposed=!0,this.reconnectDisplay.hide()}async attemptPeriodicReconnection(e){for(let t=0;thn.MaximumFirstRetryInterval?hn.MaximumFirstRetryInterval:e.retryIntervalMilliseconds;if(await this.delay(n),this.isDisposed)break;try{return await this.reconnectCallback()?void 0:void this.reconnectDisplay.rejected()}catch(e){this.logger.log(en.Error,e)}}this.reconnectDisplay.failed()}delay(e){return new Promise((t=>setTimeout(t,e)))}}hn.MaximumFirstRetryInterval=3e3;const un=/^\s*Blazor-Component-State:(?[a-zA-Z0-9\+\/=]+)$/;function dn(e){var t;if(e.nodeType===Node.COMMENT_NODE){const n=e.textContent||"",r=un.exec(n),o=r&&r.groups&&r.groups.state;return o&&(null===(t=e.parentNode)||void 0===t||t.removeChild(e)),o}if(!e.hasChildNodes())return;const n=e.childNodes;for(let e=0;e.*)$/);function gn(e,t){const n=e.currentElement;if(n&&n.nodeType===Node.COMMENT_NODE&&n.textContent){const r=fn.exec(n.textContent),o=r&&r.groups&&r.groups.descriptor;if(!o)return;try{const r=function(e){const t=JSON.parse(e),{type:n}=t;if("server"!==n&&"webassembly"!==n)throw new Error(`Invalid component type '${n}'.`);return t}(o);switch(t){case"webassembly":return function(e,t,n){const{type:r,assembly:o,typeName:i,parameterDefinitions:s,parameterValues:a,prerenderId:c}=e;if("webassembly"===r){if(!o)throw new Error("assembly must be defined when using a descriptor.");if(!i)throw new Error("typeName must be defined when using a descriptor.");if(c){const e=mn(c,n);if(!e)throw new Error(`Could not find an end component comment for '${t}'`);return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:a&&atob(a),start:t,prerenderId:c,end:e}}return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:a&&atob(a),start:t}}}(r,n,e);case"server":return function(e,t,n){const{type:r,descriptor:o,sequence:i,prerenderId:s}=e;if("server"===r){if(!o)throw new Error("descriptor must be defined when using a descriptor.");if(void 0===i)throw new Error("sequence must be defined when using a descriptor.");if(!Number.isInteger(i))throw new Error(`Error parsing the sequence '${i}' for component '${JSON.stringify(e)}'`);if(s){const e=mn(s,n);if(!e)throw new Error(`Could not find an end component comment for '${t}'`);return{type:r,sequence:i,descriptor:o,start:t,prerenderId:s,end:e}}return{type:r,sequence:i,descriptor:o,start:t}}}(r,n,e)}}catch(e){throw new Error(`Found malformed component comment at ${n.textContent}`)}}}function mn(e,t){for(;t.next()&&t.currentElement;){const n=t.currentElement;if(n.nodeType!==Node.COMMENT_NODE)continue;if(!n.textContent)continue;const r=fn.exec(n.textContent),o=r&&r[1];if(o)return yn(o,e),n}}function yn(e,t){const n=JSON.parse(e);if(1!==Object.keys(n).length)throw new Error(`Invalid end of component comment: '${e}'`);const r=n.prerenderId;if(!r)throw new Error(`End of component comment must have a value for the prerendered property: '${e}'`);if(r!==t)throw new Error(`End of component comment prerendered property must match the start comment prerender id: '${t}', '${r}'`)}class wn{constructor(e){this.childNodes=e,this.currentIndex=-1,this.length=e.length}next(){return this.currentIndex++,this.currentIndexe.sequence-t.sequence))}(e)}(document),o=dn(document),i=new on(r,o||""),s=await Tn(t,n,i);if(!await i.startCircuit(s))return void n.log(en.Error,"Failed to start the circuit.");let a=!1;const c=()=>{if(!a){const e=new FormData,t=i.circuitId;e.append("circuitId",t),a=navigator.sendBeacon("_blazor/disconnect",e)}};fe.disconnect=c,window.addEventListener("unload",c,{capture:!1,once:!0}),fe.reconnect=async e=>{if(Cn)return!1;const r=e||await Tn(t,n,i);return await i.reconnect(r)?(t.reconnectionHandler.onConnectionUp(),!0):(n.log(en.Information,"Reconnection attempt to the circuit was rejected by the server. This may indicate that the associated state is no longer available on the server."),!1)},n.log(en.Information,"Blazor server-side application started.")}async function Tn(t,n,r){const i=new Lt;i.name="blazorpack";const s=(new rt).withUrl("_blazor").withHubProtocol(i);t.configureSignalR(s);const a=s.build();o=(e,t)=>{a.send("DispatchBrowserEvent",JSON.stringify(e),JSON.stringify(t))},fe._internal.navigationManager.listenForNavigationEvents(((e,t)=>a.send("OnLocationChanged",e,t))),a.on("JS.AttachComponent",((e,t)=>function(e,t,n){let r=Q[0];r||(r=Q[0]=new V(0)),r.attachRootComponentToLogicalElement(n,t)}(0,r.resolveElement(t),e))),a.on("JS.BeginInvokeJS",e.jsCallDispatcher.beginInvokeJSFromDotNet),a.on("JS.EndInvokeDotNet",e.jsCallDispatcher.endInvokeDotNetFromJS);const c=tn.getOrCreate(n);a.on("JS.RenderBatch",((e,t)=>{n.log(en.Debug,`Received render batch with id ${e} and ${t.byteLength} bytes.`),c.processBatch(e,t,a)})),a.onclose((e=>!Cn&&t.reconnectionHandler.onConnectionDown(t.reconnectionOptions,e))),a.on("JS.Error",(e=>{Cn=!0,xn(a,e,n),async function(){let e=document.querySelector("#blazor-error-ui");e&&(e.style.display="block"),Ht||(Ht=!0,document.querySelectorAll("#blazor-error-ui .reload").forEach((e=>{e.onclick=function(e){location.reload(),e.preventDefault()}})),document.querySelectorAll("#blazor-error-ui .dismiss").forEach((e=>{e.onclick=function(e){const t=document.querySelector("#blazor-error-ui");t&&(t.style.display="none"),e.preventDefault()}})))}()})),fe._internal.forceCloseConnection=()=>a.stop();try{await a.start()}catch(e){xn(a,e,n)}return e.attachDispatcher({beginInvokeDotNetFromJS:(e,t,n,r,o,i)=>{a.send("BeginInvokeDotNetFromJS",e?e.toString():null,t,n,r||0,o,i)},endInvokeJSFromDotNet:(e,t,n,r)=>{a.send("EndInvokeJSFromDotNet",e,t,n,r)}}),a}function xn(e,t,n){n.log(en.Error,t),e&&e.stop()}fe.start=kn,document&&document.currentScript&&"false"!==document.currentScript.getAttribute("autostart")&&kn()})(); \ No newline at end of file diff --git a/src/Components/Web.JS/dist/Release/blazor.webview.js b/src/Components/Web.JS/dist/Release/blazor.webview.js index ab633eff1aae..3109ad384634 100644 --- a/src/Components/Web.JS/dist/Release/blazor.webview.js +++ b/src/Components/Web.JS/dist/Release/blazor.webview.js @@ -1 +1 @@ -(()=>{"use strict";var e,t,n;!function(e){window.DotNet=e;const t=[];class n{constructor(e){this._jsObject=e,this._cachedFunctions=new Map}findFunction(e){const t=this._cachedFunctions.get(e);if(t)return t;let n,r=this._jsObject;if(e.split(".").forEach((t=>{if(!(t in r))throw new Error(`Could not find '${e}' ('${t}' was undefined).`);n=r,r=r[t]})),r instanceof Function)return r=r.bind(n),this._cachedFunctions.set(e,r),r;throw new Error(`The value '${e}' is not a function.`)}getWrappedObject(){return this._jsObject}}const r="__jsObjectId",o={},a={0:new n(window)};a[0]._cachedFunctions.set("import",(e=>("string"==typeof e&&e.startsWith("./")&&(e=document.baseURI+e.substr(2)),import(e))));let i,s=1,c=1,l=null;function u(e){t.push(e)}function d(e){if(e&&"object"==typeof e){a[c]=new n(e);const t={[r]:c};return c++,t}throw new Error(`Cannot create a JSObjectReference from the value '${e}'.`)}function h(e){return e?JSON.parse(e,((e,n)=>t.reduce(((t,n)=>n(e,t)),n))):null}function f(e,t,n,r){const o=p();if(o.invokeDotNetFromJS){const a=JSON.stringify(r,I),i=o.invokeDotNetFromJS(e,t,n,a);return i?h(i):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function m(e,t,n,r){if(e&&n)throw new Error(`For instance method calls, assemblyName should be null. Received '${e}'.`);const a=s++,i=new Promise(((e,t)=>{o[a]={resolve:e,reject:t}}));try{const o=JSON.stringify(r,I);p().beginInvokeDotNetFromJS(a,e,t,n,o)}catch(e){v(a,!1,e)}return i}function p(){if(null!==l)return l;throw new Error("No .NET call dispatcher has been set.")}function v(e,t,n){if(!o.hasOwnProperty(e))throw new Error(`There is no pending async call with ID ${e}.`);const r=o[e];delete o[e],t?r.resolve(n):r.reject(n)}function g(e){return e instanceof Error?`${e.message}\n${e.stack}`:e?e.toString():"null"}function b(e,t){let n=a[t];if(n)return n.findFunction(e);throw new Error(`JS object instance with ID ${t} does not exist (has it been disposed?).`)}function y(e){delete a[e]}e.attachDispatcher=function(e){l=e},e.attachReviver=u,e.invokeMethod=function(e,t,...n){return f(e,t,null,n)},e.invokeMethodAsync=function(e,t,...n){return m(e,t,null,n)},e.createJSObjectReference=d,e.disposeJSObjectReference=function(e){const t=e&&e.__jsObjectId;"number"==typeof t&&y(t)},function(e){e[e.Default=0]="Default",e[e.JSObjectReference=1]="JSObjectReference"}(i=e.JSCallResultType||(e.JSCallResultType={})),e.jsCallDispatcher={findJSFunction:b,disposeJSObjectReferenceById:y,invokeJSFromDotNet:(e,t,n,r)=>{const o=w(b(e,r).apply(null,h(t)),n);return null==o?null:JSON.stringify(o,I)},beginInvokeJSFromDotNet:(e,t,n,r,o)=>{const a=new Promise((e=>{e(b(t,o).apply(null,h(n)))}));e&&a.then((t=>p().endInvokeJSFromDotNet(e,!0,JSON.stringify([e,!0,w(t,r)],I))),(t=>p().endInvokeJSFromDotNet(e,!1,JSON.stringify([e,!1,g(t)]))))},endInvokeDotNetFromJS:(e,t,n)=>{const r=t?h(n):new Error(n);v(parseInt(e),t,r)}};class E{constructor(e){this._id=e}invokeMethod(e,...t){return f(null,e,this._id,t)}invokeMethodAsync(e,...t){return m(null,e,this._id,t)}dispose(){m(null,"__Dispose",this._id,null).catch((e=>console.error(e)))}serializeAsArg(){return{__dotNetObject:this._id}}}function w(e,t){switch(t){case i.Default:return e;case i.JSObjectReference:return d(e);default:throw new Error(`Invalid JS call result type '${t}'.`)}}function I(e,t){return t instanceof E?t.serializeAsArg():t}u((function(e,t){return t&&"object"==typeof t&&t.hasOwnProperty("__dotNetObject")?new E(t.__dotNetObject):t})),u((function(e,t){if(t&&"object"==typeof t&&t.hasOwnProperty(r)){const e=t.__jsObjectId,n=a[e];if(n)return n.getWrappedObject();throw new Error(`JS object instance with ID ${e} does not exist (has it been disposed?).`)}return t}))}(e||(e={})),function(e){e[e.prependFrame=1]="prependFrame",e[e.removeFrame=2]="removeFrame",e[e.setAttribute=3]="setAttribute",e[e.removeAttribute=4]="removeAttribute",e[e.updateText=5]="updateText",e[e.stepIn=6]="stepIn",e[e.stepOut=7]="stepOut",e[e.updateMarkup=8]="updateMarkup",e[e.permutationListEntry=9]="permutationListEntry",e[e.permutationListEnd=10]="permutationListEnd"}(t||(t={})),function(e){e[e.element=1]="element",e[e.text=2]="text",e[e.attribute=3]="attribute",e[e.component=4]="component",e[e.region=5]="region",e[e.elementReferenceCapture=6]="elementReferenceCapture",e[e.markup=8]="markup"}(n||(n={}));class r{constructor(e,t){this.componentId=e,this.fieldValue=t}static fromEvent(e,t){const n=t.target;if(n instanceof Element){const t=function(e){return e instanceof HTMLInputElement?e.type&&"checkbox"===e.type.toLowerCase()?{value:e.checked}:{value:e.value}:e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?{value:e.value}:null}(n);if(t)return new r(e,t.value)}return null}}let o;function a(e,t){if(!o)throw new Error("eventDispatcher not initialized. Call 'setEventDispatcher' to configure it.");o(e,t)}const i=new Map,s=new Map,c={createEventArgs:()=>({})},l=[];function u(e){return i.get(e)}function d(e){const t=i.get(e);return(null==t?void 0:t.browserEventName)||e}function h(e,t){e.forEach((e=>i.set(e,t)))}function f(e){const t=[];for(let n=0;n{return{...m(t=e),dataTransfer:t.dataTransfer?{dropEffect:t.dataTransfer.dropEffect,effectAllowed:t.dataTransfer.effectAllowed,files:Array.from(t.dataTransfer.files).map((e=>e.name)),items:Array.from(t.dataTransfer.items).map((e=>({kind:e.kind,type:e.type}))),types:t.dataTransfer.types}:null};var t}}),h(["focus","blur","focusin","focusout"],c),h(["keydown","keyup","keypress"],{createEventArgs:e=>{return{key:(t=e).key,code:t.code,location:t.location,repeat:t.repeat,ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),h(["contextmenu","click","mouseover","mouseout","mousemove","mousedown","mouseup","dblclick"],{createEventArgs:e=>m(e)}),h(["error"],{createEventArgs:e=>{return{message:(t=e).message,filename:t.filename,lineno:t.lineno,colno:t.colno};var t}}),h(["loadstart","timeout","abort","load","loadend","progress"],{createEventArgs:e=>{return{lengthComputable:(t=e).lengthComputable,loaded:t.loaded,total:t.total};var t}}),h(["touchcancel","touchend","touchmove","touchenter","touchleave","touchstart"],{createEventArgs:e=>{return{detail:(t=e).detail,touches:f(t.touches),targetTouches:f(t.targetTouches),changedTouches:f(t.changedTouches),ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),h(["gotpointercapture","lostpointercapture","pointercancel","pointerdown","pointerenter","pointerleave","pointermove","pointerout","pointerover","pointerup"],{createEventArgs:e=>{return{...m(t=e),pointerId:t.pointerId,width:t.width,height:t.height,pressure:t.pressure,tiltX:t.tiltX,tiltY:t.tiltY,pointerType:t.pointerType,isPrimary:t.isPrimary};var t}}),h(["wheel","mousewheel"],{createEventArgs:e=>{return{...m(t=e),deltaX:t.deltaX,deltaY:t.deltaY,deltaZ:t.deltaZ,deltaMode:t.deltaMode};var t}}),h(["toggle"],c);const p=["date","datetime-local","month","time","week"],v=I(["abort","blur","change","error","focus","load","loadend","loadstart","mouseenter","mouseleave","progress","reset","scroll","submit","unload","toggle","DOMNodeInsertedIntoDocument","DOMNodeRemovedFromDocument"]),g={submit:!0},b=I(["click","dblclick","mousedown","mousemove","mouseup"]);class y{constructor(e){this.browserRendererId=e,this.afterClickCallbacks=[];const t=++y.nextEventDelegatorId;this.eventsCollectionKey=`_blazorEvents_${t}`,this.eventInfoStore=new E(this.onGlobalEvent.bind(this))}setListener(e,t,n,r){const o=this.getEventHandlerInfosForElement(e,!0),a=o.getHandler(t);if(a)this.eventInfoStore.update(a.eventHandlerId,n);else{const a={element:e,eventName:t,eventHandlerId:n,renderingComponentId:r};this.eventInfoStore.add(a),o.setHandler(t,a)}}getHandler(e){return this.eventInfoStore.get(e)}removeListener(e){const t=this.eventInfoStore.remove(e);if(t){const e=t.element,n=this.getEventHandlerInfosForElement(e,!1);n&&n.removeHandler(t.eventName)}}notifyAfterClick(e){this.afterClickCallbacks.push(e),this.eventInfoStore.addGlobalListener("click")}setStopPropagation(e,t,n){this.getEventHandlerInfosForElement(e,!0).stopPropagation(t,n)}setPreventDefault(e,t,n){this.getEventHandlerInfosForElement(e,!0).preventDefault(t,n)}onGlobalEvent(e){if(!(e.target instanceof Element))return;this.dispatchGlobalEventToAllElements(e.type,e);const t=(n=e.type,s.get(n));var n;t&&t.forEach((t=>this.dispatchGlobalEventToAllElements(t,e))),"click"===e.type&&this.afterClickCallbacks.forEach((t=>t(e)))}dispatchGlobalEventToAllElements(e,t){let n=t.target,o=null,i=!1;const s=v.hasOwnProperty(e);let c=!1;for(;n;){const h=this.getEventHandlerInfosForElement(n,!1);if(h){const s=h.getHandler(e);if(s&&(l=n,d=t.type,!((l instanceof HTMLButtonElement||l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)&&b.hasOwnProperty(d)&&l.disabled))){if(!i){const n=u(e);o=(null==n?void 0:n.createEventArgs)?n.createEventArgs(t):{},i=!0}g.hasOwnProperty(t.type)&&t.preventDefault(),a({browserRendererId:this.browserRendererId,eventHandlerId:s.eventHandlerId,eventName:e,eventFieldInfo:r.fromEvent(s.renderingComponentId,t)},o)}h.stopPropagation(e)&&(c=!0),h.preventDefault(e)&&t.preventDefault()}n=s||c?null:n.parentElement}var l,d}getEventHandlerInfosForElement(e,t){return e.hasOwnProperty(this.eventsCollectionKey)?e[this.eventsCollectionKey]:t?e[this.eventsCollectionKey]=new w:null}}y.nextEventDelegatorId=0;class E{constructor(e){this.globalListener=e,this.infosByEventHandlerId={},this.countByEventName={},l.push(this.handleEventNameAliasAdded.bind(this))}add(e){if(this.infosByEventHandlerId[e.eventHandlerId])throw new Error(`Event ${e.eventHandlerId} is already tracked`);this.infosByEventHandlerId[e.eventHandlerId]=e,this.addGlobalListener(e.eventName)}get(e){return this.infosByEventHandlerId[e]}addGlobalListener(e){if(e=d(e),this.countByEventName.hasOwnProperty(e))this.countByEventName[e]++;else{this.countByEventName[e]=1;const t=v.hasOwnProperty(e);document.addEventListener(e,this.globalListener,t)}}update(e,t){if(this.infosByEventHandlerId.hasOwnProperty(t))throw new Error(`Event ${t} is already tracked`);const n=this.infosByEventHandlerId[e];delete this.infosByEventHandlerId[e],n.eventHandlerId=t,this.infosByEventHandlerId[t]=n}remove(e){const t=this.infosByEventHandlerId[e];if(t){delete this.infosByEventHandlerId[e];const n=d(t.eventName);0==--this.countByEventName[n]&&(delete this.countByEventName[n],document.removeEventListener(n,this.globalListener))}return t}handleEventNameAliasAdded(e,t){if(this.countByEventName.hasOwnProperty(e)){const n=this.countByEventName[e];delete this.countByEventName[e],document.removeEventListener(e,this.globalListener),this.addGlobalListener(t),this.countByEventName[t]+=n-1}}}class w{constructor(){this.handlers={},this.preventDefaultFlags=null,this.stopPropagationFlags=null}getHandler(e){return this.handlers.hasOwnProperty(e)?this.handlers[e]:null}setHandler(e,t){this.handlers[e]=t}removeHandler(e){delete this.handlers[e]}preventDefault(e,t){return void 0!==t&&(this.preventDefaultFlags=this.preventDefaultFlags||{},this.preventDefaultFlags[e]=t),!!this.preventDefaultFlags&&this.preventDefaultFlags[e]}stopPropagation(e,t){return void 0!==t&&(this.stopPropagationFlags=this.stopPropagationFlags||{},this.stopPropagationFlags[e]=t),!!this.stopPropagationFlags&&this.stopPropagationFlags[e]}}function I(e){const t={};return e.forEach((e=>{t[e]=!0})),t}const S=B("_blazorLogicalChildren"),D=B("_blazorLogicalParent"),C=B("_blazorLogicalEnd");function T(e,t){if(e.childNodes.length>0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return S in e||(e[S]=[]),e}function N(e,t){const n=document.createComment("!");return A(n,e,t),n}function A(e,t,n){const r=e;if(e instanceof Comment&&_(r)&&_(r).length>0)throw new Error("Not implemented: inserting non-empty logical container");if(R(r))throw new Error("Not implemented: moving existing logical children");const o=_(t);if(n0;)k(n,0)}const r=n;r.parentNode.removeChild(r)}function R(e){return e[D]||null}function F(e,t){return _(e)[t]}function O(e){var t=P(e);return"http://www.w3.org/2000/svg"===t.namespaceURI&&"foreignObject"!==t.tagName}function _(e){return e[S]}function x(e,t){const n=_(e);t.forEach((e=>{e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=M(e.moveRangeStart)})),t.forEach((t=>{const r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):H(r,e)})),t.forEach((e=>{const t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd;let a=r;for(;a;){const e=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=e}n.removeChild(t)})),t.forEach((e=>{n[e.toSiblingIndex]=e.moveRangeStart}))}function P(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}function L(e){const t=_(R(e));return t[Array.prototype.indexOf.call(t,e)+1]||null}function H(e,t){if(t instanceof Element)t.appendChild(e);else{if(!(t instanceof Comment))throw new Error(`Cannot append node because the parent is not a valid logical element. Parent: ${t}`);{const n=L(t);n?n.parentNode.insertBefore(e,n):H(e,R(t))}}}function M(e){if(e instanceof Element)return e;const t=L(e);if(t)return t.previousSibling;{const t=R(e);return t instanceof Element?t.lastChild:M(t)}}function B(e){return"function"==typeof Symbol?Symbol():e}function U(e){return`_bl_${e}`}e.attachReviver(((e,t)=>t&&"object"==typeof t&&t.hasOwnProperty("__internalId")&&"string"==typeof t.__internalId?function(e){const t=`[${U(e)}]`;return document.querySelector(t)}(t.__internalId):t));const j="_blazorSelectValue",J=document.createElement("template"),K=document.createElementNS("http://www.w3.org/2000/svg","g"),$={},z="__internal_",V="preventDefault_",X="stopPropagation_";class Y{constructor(e){this.childComponentLocations={},this.eventDelegator=new y(e),this.eventDelegator.notifyAfterClick((e=>{if(!ee)return;if(0!==e.button||function(e){return e.ctrlKey||e.shiftKey||e.altKey||e.metaKey}(e))return;if(e.defaultPrevented)return;const t=function(e){const t=!window._blazorDisableComposedPath&&e.composedPath&&e.composedPath();if(t){for(let e=0;eie(!1))))},enableNavigationInterception:function(){ee=!0},navigateTo:oe,getBaseURI:()=>document.baseURI,getLocationHref:()=>location.href};function oe(e,t,n=!1){const r=ce(e);if(!t&&ue(r))ae(r,!1,n);else if(t&&location.href===e){const t=e+"?";history.replaceState(null,"",t),location.replace(e)}else n?history.replaceState(null,"",r):location.href=e}function ae(e,t,n=!1){Q=!0,n?history.replaceState(null,"",e):history.pushState(null,"",e),ie(t)}async function ie(e){ne&&await ne(location.href,e)}let se;function ce(e){return se=se||document.createElement("a"),se.href=e,se.href}function le(e,t){return e?e.tagName===t?e:le(e.parentElement,t):null}function ue(e){const t=(n=document.baseURI).substr(0,n.lastIndexOf("/")+1);var n;return e.startsWith(t)}const de={init:function(e,t,n,r=50){const o=fe(t);(o||document.documentElement).style.overflowAnchor="none";const a=new IntersectionObserver((function(r){r.forEach((r=>{var o;if(!r.isIntersecting)return;const a=t.getBoundingClientRect(),i=n.getBoundingClientRect().top-a.bottom,s=null===(o=r.rootBounds)||void 0===o?void 0:o.height;r.target===t?e.invokeMethodAsync("OnSpacerBeforeVisible",r.intersectionRect.top-r.boundingClientRect.top,i,s):r.target===n&&n.offsetHeight>0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,i,s)}))}),{root:o,rootMargin:`${r}px`});a.observe(t),a.observe(n);const i=c(t),s=c(n);function c(e){const t=new MutationObserver((()=>{a.unobserve(e),a.observe(e)}));return t.observe(e,{attributes:!0}),t}he[e._id]={intersectionObserver:a,mutationObserverBefore:i,mutationObserverAfter:s}},dispose:function(e){const t=he[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete he[e._id])}},he={};function fe(e){return e?"visible"!==getComputedStyle(e).overflowY?e:fe(e.parentElement):null}const me={navigateTo:oe,registerCustomEventType:function(e,t){if(!t)throw new Error("The options parameter is required.");if(i.has(e))throw new Error(`The event '${e}' is already registered.`);if(t.browserEventName){const n=s.get(t.browserEventName);n?n.push(e):s.set(t.browserEventName,[e]),l.forEach((n=>n(e,t.browserEventName)))}i.set(e,t)},_internal:{navigationManager:re,domWrapper:{focus:function(e,t){if(!(e instanceof HTMLElement))throw new Error("Unable to focus an invalid element.");e.focus({preventScroll:t})}},Virtualize:de}};window.Blazor=me;let pe=!1;const ve="function"==typeof TextDecoder?new TextDecoder("utf-8"):null,ge=ve?ve.decode.bind(ve):function(e){let t=0;const n=e.length,r=[],o=[];for(;t65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")},be=Math.pow(2,32),ye=Math.pow(2,21)-1;function Ee(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24}function we(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}function Ie(e,t){const n=we(e,t+4);if(n>ye)throw new Error(`Cannot read uint64 with high order part ${n}, because the result would exceed Number.MAX_SAFE_INTEGER.`);return n*be+we(e,t)}class Se{constructor(e){this.batchData=e;const t=new Ne(e);this.arrayRangeReader=new Ae(e),this.arrayBuilderSegmentReader=new ke(e),this.diffReader=new De(e),this.editReader=new Ce(e,t),this.frameReader=new Te(e,t)}updatedComponents(){return Ee(this.batchData,this.batchData.length-20)}referenceFrames(){return Ee(this.batchData,this.batchData.length-16)}disposedComponentIds(){return Ee(this.batchData,this.batchData.length-12)}disposedEventHandlerIds(){return Ee(this.batchData,this.batchData.length-8)}updatedComponentsEntry(e,t){const n=e+4*t;return Ee(this.batchData,n)}referenceFramesEntry(e,t){return e+20*t}disposedComponentIdsEntry(e,t){const n=e+4*t;return Ee(this.batchData,n)}disposedEventHandlerIdsEntry(e,t){const n=e+8*t;return Ie(this.batchData,n)}}class De{constructor(e){this.batchDataUint8=e}componentId(e){return Ee(this.batchDataUint8,e)}edits(e){return e+4}editsEntry(e,t){return e+16*t}}class Ce{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}editType(e){return Ee(this.batchDataUint8,e)}siblingIndex(e){return Ee(this.batchDataUint8,e+4)}newTreeIndex(e){return Ee(this.batchDataUint8,e+8)}moveToSiblingIndex(e){return Ee(this.batchDataUint8,e+8)}removedAttributeName(e){const t=Ee(this.batchDataUint8,e+12);return this.stringReader.readString(t)}}class Te{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}frameType(e){return Ee(this.batchDataUint8,e)}subtreeLength(e){return Ee(this.batchDataUint8,e+4)}elementReferenceCaptureId(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}componentId(e){return Ee(this.batchDataUint8,e+8)}elementName(e){const t=Ee(this.batchDataUint8,e+8);return this.stringReader.readString(t)}textContent(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}markupContent(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeName(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeValue(e){const t=Ee(this.batchDataUint8,e+8);return this.stringReader.readString(t)}attributeEventHandlerId(e){return Ie(this.batchDataUint8,e+12)}}class Ne{constructor(e){this.batchDataUint8=e,this.stringTableStartIndex=Ee(e,e.length-4)}readString(e){if(-1===e)return null;{const n=Ee(this.batchDataUint8,this.stringTableStartIndex+4*e),r=function(e,t){let n=0,r=0;for(let o=0;o<4;o++){const a=e[t+o];if(n|=(127&a)<{!function(e,t,n){const r=document.querySelector(e);if(!r)throw new Error(`Could not find any element matching selector '${e}'.`);!function(e,t,n){let r=Z[0];r||(r=Z[0]=new Y(0)),r.attachRootComponentToLogicalElement(n,t)}(0,T(r,!0),t)}(t,e)},RenderBatch:(e,t)=>{try{const n=function(e){const t=atob(e),n=t.length,r=new Uint8Array(n);for(let e=0;e{Fe=!0,console.error(`${e}\n${t}`),async function(){let e=document.querySelector("#blazor-error-ui");e&&(e.style.display="block"),pe||(pe=!0,document.querySelectorAll("#blazor-error-ui .reload").forEach((e=>{e.onclick=function(e){location.reload(),e.preventDefault()}})),document.querySelectorAll("#blazor-error-ui .dismiss").forEach((e=>{e.onclick=function(e){const t=document.querySelector("#blazor-error-ui");t&&(t.style.display="none"),e.preventDefault()}})))}()},BeginInvokeJS:e.jsCallDispatcher.beginInvokeJSFromDotNet,EndInvokeDotNet:e.jsCallDispatcher.endInvokeDotNetFromJS,Navigate:re.navigateTo};window.external.receiveMessage((e=>{const n=function(e){if(Fe||!e||!e.startsWith(Re))return null;const t=e.substring(Re.length),[n,...r]=JSON.parse(t);return{messageType:n,args:r}}(e);if(n){if(!t.hasOwnProperty(n.messageType))throw new Error(`Unsupported IPC message type '${n.messageType}'`);t[n.messageType].apply(null,n.args)}}))}(),e.attachDispatcher({beginInvokeDotNetFromJS:_e,endInvokeJSFromDotNet:xe}),me._internal.InputFile=He,re.enableNavigationInterception(),re.listenForNavigationEvents(Pe),Le("AttachPage",re.getBaseURI(),re.getLocationHref())}o=function(e,t){Le("DispatchBrowserEvent",e,t)},me.start=je,document&&document.currentScript&&"false"!==document.currentScript.getAttribute("autostart")&&je()})(); \ No newline at end of file +(()=>{"use strict";var e,t,n;!function(e){window.DotNet=e;const t=[];class n{constructor(e){this._jsObject=e,this._cachedFunctions=new Map}findFunction(e){const t=this._cachedFunctions.get(e);if(t)return t;let n,r=this._jsObject;if(e.split(".").forEach((t=>{if(!(t in r))throw new Error(`Could not find '${e}' ('${t}' was undefined).`);n=r,r=r[t]})),r instanceof Function)return r=r.bind(n),this._cachedFunctions.set(e,r),r;throw new Error(`The value '${e}' is not a function.`)}getWrappedObject(){return this._jsObject}}const r="__jsObjectId",o={},a={0:new n(window)};a[0]._cachedFunctions.set("import",(e=>("string"==typeof e&&e.startsWith("./")&&(e=document.baseURI+e.substr(2)),import(e))));let i,s=1,c=1,l=null;function u(e){t.push(e)}function d(e){if(e&&"object"==typeof e){a[c]=new n(e);const t={[r]:c};return c++,t}throw new Error(`Cannot create a JSObjectReference from the value '${e}'.`)}function h(e,n){return e?JSON.parse(e,((e,r)=>t.reduce(((t,r)=>r(e,t,void 0===n?null:n)),r))):null}function f(e,t,n,r){const o=m();if(o.invokeDotNetFromJS){const a=[],i=JSON.stringify(r,((e,t)=>D(0,t,a))),s=o.invokeDotNetFromJS(e,t,n,i,a);return s&&s.ArgsJson?h(s.ArgsJson,s.ByteArrays):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function p(e,t,n,r){if(e&&n)throw new Error(`For instance method calls, assemblyName should be null. Received '${e}'.`);const a=s++,i=new Promise(((e,t)=>{o[a]={resolve:e,reject:t}}));try{const o=[],i=JSON.stringify(r,((e,t)=>D(0,t,o)));m().beginInvokeDotNetFromJS(a,e,t,n,i,o)}catch(e){v(a,!1,e)}return i}function m(){if(null!==l)return l;throw new Error("No .NET call dispatcher has been set.")}function v(e,t,n){if(!o.hasOwnProperty(e))throw new Error(`There is no pending async call with ID ${e}.`);const r=o[e];delete o[e],t?r.resolve(n):r.reject(n)}e.attachDispatcher=function(e){l=e},e.attachReviver=u,e.invokeMethod=function(e,t,...n){return f(e,t,null,n)},e.invokeMethodAsync=function(e,t,...n){return p(e,t,null,n)},e.createJSObjectReference=d,e.disposeJSObjectReference=function(e){const t=e&&e.__jsObjectId;"number"==typeof t&&E(t)},function(e){e[e.Default=0]="Default",e[e.JSObjectReference=1]="JSObjectReference"}(i=e.JSCallResultType||(e.JSCallResultType={}));class g{constructor(e,t){this.ArgsJson=e,this.ByteArrays=t}}function b(e){return e instanceof Error?`${e.message}\n${e.stack}`:e?e.toString():"null"}function y(e,t){let n=a[t];if(n)return n.findFunction(e);throw new Error(`JS object instance with ID ${t} does not exist (has it been disposed?).`)}function E(e){delete a[e]}e.SerializedArgs=g,e.jsCallDispatcher={findJSFunction:y,disposeJSObjectReferenceById:E,invokeJSFromDotNet:(e,t,n,r,o)=>{const a=S(y(e,o).apply(null,h(t,n)),r),i=[];var s=null==a?null:JSON.stringify(a,((e,t)=>D(0,t,i)));return new g(s,i)},beginInvokeJSFromDotNet:(e,t,n,r,o,a)=>{const i=new Promise((e=>{e(y(t,a).apply(null,h(n,r)))}));if(e){const t=[];i.then((n=>m().endInvokeJSFromDotNet(e,!0,JSON.stringify([e,!0,S(n,o)],((e,n)=>D(0,n,t))),t)),(t=>m().endInvokeJSFromDotNet(e,!1,JSON.stringify([e,!1,b(t)]),null)))}},endInvokeDotNetFromJS:(e,t,n,r)=>{const o=t?h(n,r):new Error(n);v(parseInt(e),t,o)}};class w{constructor(e){this._id=e}invokeMethod(e,...t){return f(null,e,this._id,t)}invokeMethodAsync(e,...t){return p(null,e,this._id,t)}dispose(){p(null,"__Dispose",this._id,null).catch((e=>console.error(e)))}serializeAsArg(){return{__dotNetObject:this._id}}}u((function(e,t,n){return t&&"object"==typeof t&&t.hasOwnProperty("__dotNetObject")?new w(t.__dotNetObject):t})),u((function(e,t,n){if(t&&"object"==typeof t&&t.hasOwnProperty(r)){const e=t.__jsObjectId,n=a[e];if(n)return n.getWrappedObject();throw new Error(`JS object instance with ID ${e} does not exist (has it been disposed?).`)}return t}));const I="__byte[]";function S(e,t){switch(t){case i.Default:return e;case i.JSObjectReference:return d(e);default:throw new Error(`Invalid JS call result type '${t}'.`)}}function D(e,t,n){if(t instanceof w)return t.serializeAsArg();if(t instanceof Uint8Array){var r=n.length;return n.push(t),{[I]:r}}return t}u((function(e,t,n){if(t&&"object"==typeof t&&t.hasOwnProperty(I)&&n){const e=t["__byte[]"];if(e>=n.length||e<0)throw new Error(`Byte array index '${e}' does not exist.`);return n[t["__byte[]"]]}return t}))}(e||(e={})),function(e){e[e.prependFrame=1]="prependFrame",e[e.removeFrame=2]="removeFrame",e[e.setAttribute=3]="setAttribute",e[e.removeAttribute=4]="removeAttribute",e[e.updateText=5]="updateText",e[e.stepIn=6]="stepIn",e[e.stepOut=7]="stepOut",e[e.updateMarkup=8]="updateMarkup",e[e.permutationListEntry=9]="permutationListEntry",e[e.permutationListEnd=10]="permutationListEnd"}(t||(t={})),function(e){e[e.element=1]="element",e[e.text=2]="text",e[e.attribute=3]="attribute",e[e.component=4]="component",e[e.region=5]="region",e[e.elementReferenceCapture=6]="elementReferenceCapture",e[e.markup=8]="markup"}(n||(n={}));class r{constructor(e,t){this.componentId=e,this.fieldValue=t}static fromEvent(e,t){const n=t.target;if(n instanceof Element){const t=function(e){return e instanceof HTMLInputElement?e.type&&"checkbox"===e.type.toLowerCase()?{value:e.checked}:{value:e.value}:e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?{value:e.value}:null}(n);if(t)return new r(e,t.value)}return null}}let o;function a(e,t){if(!o)throw new Error("eventDispatcher not initialized. Call 'setEventDispatcher' to configure it.");o(e,t)}const i=new Map,s=new Map,c={createEventArgs:()=>({})},l=[];function u(e){return i.get(e)}function d(e){const t=i.get(e);return(null==t?void 0:t.browserEventName)||e}function h(e,t){e.forEach((e=>i.set(e,t)))}function f(e){const t=[];for(let n=0;n{return{...p(t=e),dataTransfer:t.dataTransfer?{dropEffect:t.dataTransfer.dropEffect,effectAllowed:t.dataTransfer.effectAllowed,files:Array.from(t.dataTransfer.files).map((e=>e.name)),items:Array.from(t.dataTransfer.items).map((e=>({kind:e.kind,type:e.type}))),types:t.dataTransfer.types}:null};var t}}),h(["focus","blur","focusin","focusout"],c),h(["keydown","keyup","keypress"],{createEventArgs:e=>{return{key:(t=e).key,code:t.code,location:t.location,repeat:t.repeat,ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),h(["contextmenu","click","mouseover","mouseout","mousemove","mousedown","mouseup","dblclick"],{createEventArgs:e=>p(e)}),h(["error"],{createEventArgs:e=>{return{message:(t=e).message,filename:t.filename,lineno:t.lineno,colno:t.colno};var t}}),h(["loadstart","timeout","abort","load","loadend","progress"],{createEventArgs:e=>{return{lengthComputable:(t=e).lengthComputable,loaded:t.loaded,total:t.total};var t}}),h(["touchcancel","touchend","touchmove","touchenter","touchleave","touchstart"],{createEventArgs:e=>{return{detail:(t=e).detail,touches:f(t.touches),targetTouches:f(t.targetTouches),changedTouches:f(t.changedTouches),ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey};var t}}),h(["gotpointercapture","lostpointercapture","pointercancel","pointerdown","pointerenter","pointerleave","pointermove","pointerout","pointerover","pointerup"],{createEventArgs:e=>{return{...p(t=e),pointerId:t.pointerId,width:t.width,height:t.height,pressure:t.pressure,tiltX:t.tiltX,tiltY:t.tiltY,pointerType:t.pointerType,isPrimary:t.isPrimary};var t}}),h(["wheel","mousewheel"],{createEventArgs:e=>{return{...p(t=e),deltaX:t.deltaX,deltaY:t.deltaY,deltaZ:t.deltaZ,deltaMode:t.deltaMode};var t}}),h(["toggle"],c);const m=["date","datetime-local","month","time","week"],v=I(["abort","blur","change","error","focus","load","loadend","loadstart","mouseenter","mouseleave","progress","reset","scroll","submit","unload","toggle","DOMNodeInsertedIntoDocument","DOMNodeRemovedFromDocument"]),g={submit:!0},b=I(["click","dblclick","mousedown","mousemove","mouseup"]);class y{constructor(e){this.browserRendererId=e,this.afterClickCallbacks=[];const t=++y.nextEventDelegatorId;this.eventsCollectionKey=`_blazorEvents_${t}`,this.eventInfoStore=new E(this.onGlobalEvent.bind(this))}setListener(e,t,n,r){const o=this.getEventHandlerInfosForElement(e,!0),a=o.getHandler(t);if(a)this.eventInfoStore.update(a.eventHandlerId,n);else{const a={element:e,eventName:t,eventHandlerId:n,renderingComponentId:r};this.eventInfoStore.add(a),o.setHandler(t,a)}}getHandler(e){return this.eventInfoStore.get(e)}removeListener(e){const t=this.eventInfoStore.remove(e);if(t){const e=t.element,n=this.getEventHandlerInfosForElement(e,!1);n&&n.removeHandler(t.eventName)}}notifyAfterClick(e){this.afterClickCallbacks.push(e),this.eventInfoStore.addGlobalListener("click")}setStopPropagation(e,t,n){this.getEventHandlerInfosForElement(e,!0).stopPropagation(t,n)}setPreventDefault(e,t,n){this.getEventHandlerInfosForElement(e,!0).preventDefault(t,n)}onGlobalEvent(e){if(!(e.target instanceof Element))return;this.dispatchGlobalEventToAllElements(e.type,e);const t=(n=e.type,s.get(n));var n;t&&t.forEach((t=>this.dispatchGlobalEventToAllElements(t,e))),"click"===e.type&&this.afterClickCallbacks.forEach((t=>t(e)))}dispatchGlobalEventToAllElements(e,t){let n=t.target,o=null,i=!1;const s=v.hasOwnProperty(e);let c=!1;for(;n;){const h=this.getEventHandlerInfosForElement(n,!1);if(h){const s=h.getHandler(e);if(s&&(l=n,d=t.type,!((l instanceof HTMLButtonElement||l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)&&b.hasOwnProperty(d)&&l.disabled))){if(!i){const n=u(e);o=(null==n?void 0:n.createEventArgs)?n.createEventArgs(t):{},i=!0}g.hasOwnProperty(t.type)&&t.preventDefault(),a({browserRendererId:this.browserRendererId,eventHandlerId:s.eventHandlerId,eventName:e,eventFieldInfo:r.fromEvent(s.renderingComponentId,t)},o)}h.stopPropagation(e)&&(c=!0),h.preventDefault(e)&&t.preventDefault()}n=s||c?null:n.parentElement}var l,d}getEventHandlerInfosForElement(e,t){return e.hasOwnProperty(this.eventsCollectionKey)?e[this.eventsCollectionKey]:t?e[this.eventsCollectionKey]=new w:null}}y.nextEventDelegatorId=0;class E{constructor(e){this.globalListener=e,this.infosByEventHandlerId={},this.countByEventName={},l.push(this.handleEventNameAliasAdded.bind(this))}add(e){if(this.infosByEventHandlerId[e.eventHandlerId])throw new Error(`Event ${e.eventHandlerId} is already tracked`);this.infosByEventHandlerId[e.eventHandlerId]=e,this.addGlobalListener(e.eventName)}get(e){return this.infosByEventHandlerId[e]}addGlobalListener(e){if(e=d(e),this.countByEventName.hasOwnProperty(e))this.countByEventName[e]++;else{this.countByEventName[e]=1;const t=v.hasOwnProperty(e);document.addEventListener(e,this.globalListener,t)}}update(e,t){if(this.infosByEventHandlerId.hasOwnProperty(t))throw new Error(`Event ${t} is already tracked`);const n=this.infosByEventHandlerId[e];delete this.infosByEventHandlerId[e],n.eventHandlerId=t,this.infosByEventHandlerId[t]=n}remove(e){const t=this.infosByEventHandlerId[e];if(t){delete this.infosByEventHandlerId[e];const n=d(t.eventName);0==--this.countByEventName[n]&&(delete this.countByEventName[n],document.removeEventListener(n,this.globalListener))}return t}handleEventNameAliasAdded(e,t){if(this.countByEventName.hasOwnProperty(e)){const n=this.countByEventName[e];delete this.countByEventName[e],document.removeEventListener(e,this.globalListener),this.addGlobalListener(t),this.countByEventName[t]+=n-1}}}class w{constructor(){this.handlers={},this.preventDefaultFlags=null,this.stopPropagationFlags=null}getHandler(e){return this.handlers.hasOwnProperty(e)?this.handlers[e]:null}setHandler(e,t){this.handlers[e]=t}removeHandler(e){delete this.handlers[e]}preventDefault(e,t){return void 0!==t&&(this.preventDefaultFlags=this.preventDefaultFlags||{},this.preventDefaultFlags[e]=t),!!this.preventDefaultFlags&&this.preventDefaultFlags[e]}stopPropagation(e,t){return void 0!==t&&(this.stopPropagationFlags=this.stopPropagationFlags||{},this.stopPropagationFlags[e]=t),!!this.stopPropagationFlags&&this.stopPropagationFlags[e]}}function I(e){const t={};return e.forEach((e=>{t[e]=!0})),t}const S=M("_blazorLogicalChildren"),D=M("_blazorLogicalParent"),C=M("_blazorLogicalEnd");function A(e,t){if(e.childNodes.length>0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return S in e||(e[S]=[]),e}function T(e,t){const n=document.createComment("!");return N(n,e,t),n}function N(e,t,n){const r=e;if(e instanceof Comment&&_(r)&&_(r).length>0)throw new Error("Not implemented: inserting non-empty logical container");if(R(r))throw new Error("Not implemented: moving existing logical children");const o=_(t);if(n0;)k(n,0)}const r=n;r.parentNode.removeChild(r)}function R(e){return e[D]||null}function F(e,t){return _(e)[t]}function O(e){var t=P(e);return"http://www.w3.org/2000/svg"===t.namespaceURI&&"foreignObject"!==t.tagName}function _(e){return e[S]}function x(e,t){const n=_(e);t.forEach((e=>{e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=B(e.moveRangeStart)})),t.forEach((t=>{const r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):H(r,e)})),t.forEach((e=>{const t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd;let a=r;for(;a;){const e=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=e}n.removeChild(t)})),t.forEach((e=>{n[e.toSiblingIndex]=e.moveRangeStart}))}function P(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}function L(e){const t=_(R(e));return t[Array.prototype.indexOf.call(t,e)+1]||null}function H(e,t){if(t instanceof Element)t.appendChild(e);else{if(!(t instanceof Comment))throw new Error(`Cannot append node because the parent is not a valid logical element. Parent: ${t}`);{const n=L(t);n?n.parentNode.insertBefore(e,n):H(e,R(t))}}}function B(e){if(e instanceof Element)return e;const t=L(e);if(t)return t.previousSibling;{const t=R(e);return t instanceof Element?t.lastChild:B(t)}}function M(e){return"function"==typeof Symbol?Symbol():e}function U(e){return`_bl_${e}`}e.attachReviver((function(e,t,n){return t&&"object"==typeof t&&t.hasOwnProperty("__internalId")&&"string"==typeof t.__internalId?function(e){const t=`[${U(e)}]`;return document.querySelector(t)}(t.__internalId):t}));const j="_blazorSelectValue",J=document.createElement("template"),$=document.createElementNS("http://www.w3.org/2000/svg","g"),z={},K="__internal_",V="preventDefault_",X="stopPropagation_";class Y{constructor(e){this.childComponentLocations={},this.eventDelegator=new y(e),this.eventDelegator.notifyAfterClick((e=>{if(!ee)return;if(0!==e.button||function(e){return e.ctrlKey||e.shiftKey||e.altKey||e.metaKey}(e))return;if(e.defaultPrevented)return;const t=function(e){const t=!window._blazorDisableComposedPath&&e.composedPath&&e.composedPath();if(t){for(let e=0;eie(!1))))},enableNavigationInterception:function(){ee=!0},navigateTo:oe,getBaseURI:()=>document.baseURI,getLocationHref:()=>location.href};function oe(e,t,n=!1){const r=ce(e);if(!t&&ue(r))ae(r,!1,n);else if(t&&location.href===e){const t=e+"?";history.replaceState(null,"",t),location.replace(e)}else n?history.replaceState(null,"",r):location.href=e}function ae(e,t,n=!1){Q=!0,n?history.replaceState(null,"",e):history.pushState(null,"",e),ie(t)}async function ie(e){ne&&await ne(location.href,e)}let se;function ce(e){return se=se||document.createElement("a"),se.href=e,se.href}function le(e,t){return e?e.tagName===t?e:le(e.parentElement,t):null}function ue(e){const t=(n=document.baseURI).substr(0,n.lastIndexOf("/")+1);var n;return e.startsWith(t)}const de={init:function(e,t,n,r=50){const o=fe(t);(o||document.documentElement).style.overflowAnchor="none";const a=new IntersectionObserver((function(r){r.forEach((r=>{var o;if(!r.isIntersecting)return;const a=t.getBoundingClientRect(),i=n.getBoundingClientRect().top-a.bottom,s=null===(o=r.rootBounds)||void 0===o?void 0:o.height;r.target===t?e.invokeMethodAsync("OnSpacerBeforeVisible",r.intersectionRect.top-r.boundingClientRect.top,i,s):r.target===n&&n.offsetHeight>0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,i,s)}))}),{root:o,rootMargin:`${r}px`});a.observe(t),a.observe(n);const i=c(t),s=c(n);function c(e){const t=new MutationObserver((()=>{a.unobserve(e),a.observe(e)}));return t.observe(e,{attributes:!0}),t}he[e._id]={intersectionObserver:a,mutationObserverBefore:i,mutationObserverAfter:s}},dispose:function(e){const t=he[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete he[e._id])}},he={};function fe(e){return e?"visible"!==getComputedStyle(e).overflowY?e:fe(e.parentElement):null}const pe={navigateTo:oe,registerCustomEventType:function(e,t){if(!t)throw new Error("The options parameter is required.");if(i.has(e))throw new Error(`The event '${e}' is already registered.`);if(t.browserEventName){const n=s.get(t.browserEventName);n?n.push(e):s.set(t.browserEventName,[e]),l.forEach((n=>n(e,t.browserEventName)))}i.set(e,t)},_internal:{navigationManager:re,domWrapper:{focus:function(e,t){if(!(e instanceof HTMLElement))throw new Error("Unable to focus an invalid element.");e.focus({preventScroll:t})}},Virtualize:de}};window.Blazor=pe;let me=!1;const ve="function"==typeof TextDecoder?new TextDecoder("utf-8"):null,ge=ve?ve.decode.bind(ve):function(e){let t=0;const n=e.length,r=[],o=[];for(;t65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")},be=Math.pow(2,32),ye=Math.pow(2,21)-1;function Ee(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24}function we(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}function Ie(e,t){const n=we(e,t+4);if(n>ye)throw new Error(`Cannot read uint64 with high order part ${n}, because the result would exceed Number.MAX_SAFE_INTEGER.`);return n*be+we(e,t)}class Se{constructor(e){this.batchData=e;const t=new Te(e);this.arrayRangeReader=new Ne(e),this.arrayBuilderSegmentReader=new ke(e),this.diffReader=new De(e),this.editReader=new Ce(e,t),this.frameReader=new Ae(e,t)}updatedComponents(){return Ee(this.batchData,this.batchData.length-20)}referenceFrames(){return Ee(this.batchData,this.batchData.length-16)}disposedComponentIds(){return Ee(this.batchData,this.batchData.length-12)}disposedEventHandlerIds(){return Ee(this.batchData,this.batchData.length-8)}updatedComponentsEntry(e,t){const n=e+4*t;return Ee(this.batchData,n)}referenceFramesEntry(e,t){return e+20*t}disposedComponentIdsEntry(e,t){const n=e+4*t;return Ee(this.batchData,n)}disposedEventHandlerIdsEntry(e,t){const n=e+8*t;return Ie(this.batchData,n)}}class De{constructor(e){this.batchDataUint8=e}componentId(e){return Ee(this.batchDataUint8,e)}edits(e){return e+4}editsEntry(e,t){return e+16*t}}class Ce{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}editType(e){return Ee(this.batchDataUint8,e)}siblingIndex(e){return Ee(this.batchDataUint8,e+4)}newTreeIndex(e){return Ee(this.batchDataUint8,e+8)}moveToSiblingIndex(e){return Ee(this.batchDataUint8,e+8)}removedAttributeName(e){const t=Ee(this.batchDataUint8,e+12);return this.stringReader.readString(t)}}class Ae{constructor(e,t){this.batchDataUint8=e,this.stringReader=t}frameType(e){return Ee(this.batchDataUint8,e)}subtreeLength(e){return Ee(this.batchDataUint8,e+4)}elementReferenceCaptureId(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}componentId(e){return Ee(this.batchDataUint8,e+8)}elementName(e){const t=Ee(this.batchDataUint8,e+8);return this.stringReader.readString(t)}textContent(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}markupContent(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeName(e){const t=Ee(this.batchDataUint8,e+4);return this.stringReader.readString(t)}attributeValue(e){const t=Ee(this.batchDataUint8,e+8);return this.stringReader.readString(t)}attributeEventHandlerId(e){return Ie(this.batchDataUint8,e+12)}}class Te{constructor(e){this.batchDataUint8=e,this.stringTableStartIndex=Ee(e,e.length-4)}readString(e){if(-1===e)return null;{const n=Ee(this.batchDataUint8,this.stringTableStartIndex+4*e),r=function(e,t){let n=0,r=0;for(let o=0;o<4;o++){const a=e[t+o];if(n|=(127&a)<{!function(e,t,n){const r=document.querySelector(e);if(!r)throw new Error(`Could not find any element matching selector '${e}'.`);!function(e,t,n){let r=Z[0];r||(r=Z[0]=new Y(0)),r.attachRootComponentToLogicalElement(n,t)}(0,A(r,!0),t)}(t,e)},RenderBatch:(e,t)=>{try{const n=function(e){const t=atob(e),n=t.length,r=new Uint8Array(n);for(let e=0;e{Fe=!0,console.error(`${e}\n${t}`),async function(){let e=document.querySelector("#blazor-error-ui");e&&(e.style.display="block"),me||(me=!0,document.querySelectorAll("#blazor-error-ui .reload").forEach((e=>{e.onclick=function(e){location.reload(),e.preventDefault()}})),document.querySelectorAll("#blazor-error-ui .dismiss").forEach((e=>{e.onclick=function(e){const t=document.querySelector("#blazor-error-ui");t&&(t.style.display="none"),e.preventDefault()}})))}()},BeginInvokeJS:e.jsCallDispatcher.beginInvokeJSFromDotNet,EndInvokeDotNet:e.jsCallDispatcher.endInvokeDotNetFromJS,Navigate:re.navigateTo};window.external.receiveMessage((e=>{const n=function(e){if(Fe||!e||!e.startsWith(Re))return null;const t=e.substring(Re.length),[n,...r]=JSON.parse(t);return{messageType:n,args:r}}(e);if(n){if(!t.hasOwnProperty(n.messageType))throw new Error(`Unsupported IPC message type '${n.messageType}'`);t[n.messageType].apply(null,n.args)}}))}(),e.attachDispatcher({beginInvokeDotNetFromJS:_e,endInvokeJSFromDotNet:xe}),pe._internal.InputFile=He,re.enableNavigationInterception(),re.listenForNavigationEvents(Pe),Le("AttachPage",re.getBaseURI(),re.getLocationHref())}o=function(e,t){Le("DispatchBrowserEvent",e,t)},pe.start=je,document&&document.currentScript&&"false"!==document.currentScript.getAttribute("autostart")&&je()})(); \ No newline at end of file diff --git a/src/Components/Web.JS/src/Boot.Server.ts b/src/Components/Web.JS/src/Boot.Server.ts index 1ddc3f8728c7..0002d365bf04 100644 --- a/src/Components/Web.JS/src/Boot.Server.ts +++ b/src/Components/Web.JS/src/Boot.Server.ts @@ -128,11 +128,11 @@ async function initializeConnection(options: CircuitStartOptions, logger: Logger } DotNet.attachDispatcher({ - beginInvokeDotNetFromJS: (callId, assemblyName, methodIdentifier, dotNetObjectId, argsJson): void => { - connection.send('BeginInvokeDotNetFromJS', callId ? callId.toString() : null, assemblyName, methodIdentifier, dotNetObjectId || 0, argsJson); + beginInvokeDotNetFromJS: (callId, assemblyName, methodIdentifier, dotNetObjectId, argsJson, byteArrays): void => { + connection.send('BeginInvokeDotNetFromJS', callId ? callId.toString() : null, assemblyName, methodIdentifier, dotNetObjectId || 0, argsJson, byteArrays); }, - endInvokeJSFromDotNet: (asyncHandle, succeeded, argsJson): void => { - connection.send('EndInvokeJSFromDotNet', asyncHandle, succeeded, argsJson); + endInvokeJSFromDotNet: (asyncHandle, succeeded, resultOrError, byteArrays): void => { + connection.send('EndInvokeJSFromDotNet', asyncHandle, succeeded, resultOrError, byteArrays); }, }); diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index 0eb7dc882b9f..2143a7ab0697 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -487,7 +487,7 @@ function attachInteropInvoker(): void { const dotNetDispatcherEndInvokeJSMethodHandle = bindStaticMethod('Microsoft.AspNetCore.Components.WebAssembly', 'Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime', 'EndInvokeJS'); DotNet.attachDispatcher({ - beginInvokeDotNetFromJS: (callId: number, assemblyName: string | null, methodIdentifier: string, dotNetObjectId: any | null, argsJson: string): void => { + beginInvokeDotNetFromJS: (callId: number, assemblyName: string | null, methodIdentifier: string, dotNetObjectId: any | null, argsJson: string, byteArrays: Uint8Array[] | null): void => { assertHeapIsNotLocked(); if (!dotNetObjectId && !assemblyName) { throw new Error('Either assemblyName or dotNetObjectId must have a non null value.'); @@ -503,21 +503,24 @@ function attachInteropInvoker(): void { assemblyNameOrDotNetObjectId, methodIdentifier, argsJson, + byteArrays, ); }, - endInvokeJSFromDotNet: (asyncHandle, succeeded, serializedArgs): void => { + endInvokeJSFromDotNet: (asyncHandle, succeeded, argsJson, byteArrays: Uint8Array[] | null): void => { dotNetDispatcherEndInvokeJSMethodHandle( - serializedArgs + argsJson, + byteArrays, ); }, - invokeDotNetFromJS: (assemblyName, methodIdentifier, dotNetObjectId, argsJson) => { + invokeDotNetFromJS: (assemblyName, methodIdentifier, dotNetObjectId, argsJson, byteArrays: Uint8Array[] | null) => { assertHeapIsNotLocked(); return dotNetDispatcherInvokeMethodHandle( assemblyName ? assemblyName : null, methodIdentifier, dotNetObjectId ? dotNetObjectId.toString() : null, argsJson, - ) as string; + byteArrays, + ) as DotNet.SerializedArgs | null; }, }); } diff --git a/src/Components/Web.JS/src/Platform/WebView/WebViewIpcSender.ts b/src/Components/Web.JS/src/Platform/WebView/WebViewIpcSender.ts index c3412d8edb33..c11b45349f80 100644 --- a/src/Components/Web.JS/src/Platform/WebView/WebViewIpcSender.ts +++ b/src/Components/Web.JS/src/Platform/WebView/WebViewIpcSender.ts @@ -13,12 +13,12 @@ export function sendBrowserEvent(descriptor: EventDescriptor, eventArgs: any) { send('DispatchBrowserEvent', descriptor, eventArgs); } -export function sendBeginInvokeDotNetFromJS(callId: number, assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, argsJson: string): void { - send('BeginInvokeDotNet', callId ? callId.toString() : null, assemblyName, methodIdentifier, dotNetObjectId || 0, argsJson); +export function sendBeginInvokeDotNetFromJS(callId: number, assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, argsJson: string, byteArrays: Uint8Array[] | null): void { + send('BeginInvokeDotNet', callId ? callId.toString() : null, assemblyName, methodIdentifier, dotNetObjectId || 0, argsJson, byteArrays); } -export function sendEndInvokeJSFromDotNet(asyncHandle: number, succeeded: boolean, argsJson: any) { - send('EndInvokeJS', asyncHandle, succeeded, argsJson); +export function sendEndInvokeJSFromDotNet(asyncHandle: number, succeeded: boolean, argsJson: any, byteArrays: Uint8Array[] | null) { + send('EndInvokeJS', asyncHandle, succeeded, argsJson, byteArrays); } export function sendLocationChanged(uri: string, intercepted: boolean) { diff --git a/src/Components/Web.JS/src/Rendering/ElementReferenceCapture.ts b/src/Components/Web.JS/src/Rendering/ElementReferenceCapture.ts index ac965690d0cb..f993152969f4 100644 --- a/src/Components/Web.JS/src/Rendering/ElementReferenceCapture.ts +++ b/src/Components/Web.JS/src/Rendering/ElementReferenceCapture.ts @@ -15,10 +15,11 @@ function getCaptureIdAttributeName(referenceCaptureId: string) { // Support receiving ElementRef instances as args in interop calls const elementRefKey = '__internalId'; // Keep in sync with ElementRef.cs -DotNet.attachReviver((key, value) => { +DotNet.attachReviver(function reviveElementReference(key: any, value: any, byteArrays: Uint8Array[] | null) { if (value && typeof value === 'object' && value.hasOwnProperty(elementRefKey) && typeof value[elementRefKey] === 'string') { return getElementByCaptureId(value[elementRefKey]); - } else { - return value; } + + // Unrecognized - let another reviver handle it + return value; }); diff --git a/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt b/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt index 0ec8f679fc6f..532fc51ba6c0 100644 --- a/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt +++ b/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt @@ -1,7 +1,7 @@ #nullable enable -override Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.BeginInvokeJS(long asyncHandle, string! identifier, string? argsJson, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> void Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1, T2 arg2) -> TResult Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1) -> TResult Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier, T0 arg0) -> TResult Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier) -> TResult -override Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeJS(string! identifier, string? argsJson, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> string! +override Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.BeginInvokeJS(long asyncHandle, string! identifier, string? argsJson, byte[]![]? byteArrays, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> void +override Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeJS(string! identifier, string? argsJson, byte[]![]? byteArrays, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> string! diff --git a/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts b/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts index d2d564147ba3..e21d5f47515a 100644 --- a/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts +++ b/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts @@ -3,7 +3,7 @@ export module DotNet { (window as any).DotNet = DotNet; // Ensure reachable from anywhere - export type JsonReviver = ((key: any, value: any) => any); + export type JsonReviver = ((key: any, value: any, byteArrays: Uint8Array[] | null) => any); const jsonRevivers: JsonReviver[] = []; class JSObject { @@ -154,13 +154,14 @@ export module DotNet { * Parses the given JSON string using revivers to restore args passed from .NET to JS. * * @param json The JSON stirng to parse. + * @param byteArrays The byte array data to revive. */ - function parseJsonWithRevivers(json: string): any { + function parseJsonWithRevivers(json: string, byteArrays?: Uint8Array[] | null): any { return json ? JSON.parse(json, (key, initialValue) => { // Invoke each reviver in order, passing the output from the previous reviver, // so that each one gets a chance to transform the value return jsonRevivers.reduce( - (latestValue, reviver) => reviver(key, latestValue), + (latestValue, reviver) => reviver(key, latestValue, byteArrays === undefined ? null : byteArrays), initialValue ); }) : null; @@ -169,9 +170,10 @@ export module DotNet { function invokePossibleInstanceMethod(assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, args: any[] | null): T { const dispatcher = getRequiredDispatcher(); if (dispatcher.invokeDotNetFromJS) { - const argsJson = JSON.stringify(args, argReplacer); - const resultJson = dispatcher.invokeDotNetFromJS(assemblyName, methodIdentifier, dotNetObjectId, argsJson); - return resultJson ? parseJsonWithRevivers(resultJson) : null; + const byteArrays : Uint8Array[] = []; + const argsJson = JSON.stringify(args, (key, value) => argReplacer(key, value, byteArrays)); + const result = dispatcher.invokeDotNetFromJS(assemblyName, methodIdentifier, dotNetObjectId, argsJson, byteArrays); + return result && result.ArgsJson ? parseJsonWithRevivers(result.ArgsJson, result.ByteArrays) : null; } else { throw new Error('The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.'); } @@ -188,8 +190,9 @@ export module DotNet { }); try { - const argsJson = JSON.stringify(args, argReplacer); - getRequiredDispatcher().beginInvokeDotNetFromJS(asyncCallId, assemblyName, methodIdentifier, dotNetObjectId, argsJson); + const byteArrays : Uint8Array[] = []; + const argsJson = JSON.stringify(args, (key, value) => argReplacer(key, value, byteArrays)); + getRequiredDispatcher().beginInvokeDotNetFromJS(asyncCallId, assemblyName, methodIdentifier, dotNetObjectId, argsJson, byteArrays); } catch (ex) { // Synchronous failure completePendingCall(asyncCallId, false, ex); @@ -206,13 +209,13 @@ export module DotNet { throw new Error('No .NET call dispatcher has been set.'); } - function completePendingCall(asyncCallId: number, success: boolean, resultOrError: any) { - if (!pendingAsyncCalls.hasOwnProperty(asyncCallId)) { - throw new Error(`There is no pending async call with ID ${asyncCallId}.`); + function completePendingCall(callId: number, success: boolean, resultOrError: any) { + if (!pendingAsyncCalls.hasOwnProperty(callId)) { + throw new Error(`There is no pending async call with ID ${callId}.`); } - const asyncCall = pendingAsyncCalls[asyncCallId]; - delete pendingAsyncCalls[asyncCallId]; + const asyncCall = pendingAsyncCalls[callId]; + delete pendingAsyncCalls[callId]; if (success) { asyncCall.resolve(resultOrError); } else { @@ -233,6 +236,19 @@ export module DotNet { JSObjectReference = 1 } + /** + * Represents the type of result expected from a JS interop call. + */ + export class SerializedArgs { + ArgsJson: string | null; + ByteArrays: Uint8Array[] | null; + + constructor(argsJson: string | null, byteArrays: Uint8Array[] | null) { + this.ArgsJson = argsJson; + this.ByteArrays = byteArrays; + } + } + /** * Represents the ability to dispatch calls from JavaScript to a .NET runtime. */ @@ -244,9 +260,10 @@ export module DotNet { * @param methodIdentifier The identifier of the method to invoke. The method must have a [JSInvokable] attribute specifying this identifier. * @param dotNetObjectId If given, the call will be to an instance method on the specified DotNetObject. Pass null or undefined to call static methods. * @param argsJson JSON representation of arguments to pass to the method. - * @returns JSON representation of the result of the invocation. + * @param byteArrays Byte array data extracted from the arguments for direct transfer. + * @returns SerializedArgs containing the string JSON args along with the extracted byte arrays representation of the result of the invocation. */ - invokeDotNetFromJS?(assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, argsJson: string): string | null; + invokeDotNetFromJS?(assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, argsJson: string, byteArrays: Uint8Array[] | null): SerializedArgs | null; /** * Invoked by the runtime to begin an asynchronous call to a .NET method. @@ -256,8 +273,9 @@ export module DotNet { * @param methodIdentifier The identifier of the method to invoke. The method must have a [JSInvokable] attribute specifying this identifier. * @param dotNetObjectId If given, the call will be to an instance method on the specified DotNetObject. Pass null to call static methods. * @param argsJson JSON representation of arguments to pass to the method. + * @param byteArrays Byte array data extracted from the arguments for direct transfer. */ - beginInvokeDotNetFromJS(callId: number, assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, argsJson: string): void; + beginInvokeDotNetFromJS(callId: number, assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, argsJson: string, byteArrays: Uint8Array[] | null): void; /** * Invoked by the runtime to complete an asynchronous JavaScript function call started from .NET @@ -265,8 +283,9 @@ export module DotNet { * @param callId A value identifying the asynchronous operation. * @param succeded Whether the operation succeeded or not. * @param resultOrError The serialized result or the serialized error from the async operation. + * @param byteArrays Byte array data extracted from the arguments for direct transfer. */ - endInvokeJSFromDotNet(callId: number, succeeded: boolean, resultOrError: any): void; + endInvokeJSFromDotNet(callId: number, succeeded: boolean, resultOrError: any, byteArrays: Uint8Array[] | null): void; } /** @@ -294,17 +313,20 @@ export module DotNet { * * @param identifier Identifies the globally-reachable function to invoke. * @param argsJson JSON representation of arguments to be passed to the function. + * @param byteArrays Byte array data extracted from the arguments for direct transfer. * @param resultType The type of result expected from the JS interop call. * @param targetInstanceId The instance ID of the target JS object. - * @returns JSON representation of the invocation result. + * @returns SerializedArgs containing the JSON representation of the invocation result and the associated byte arrays. */ - invokeJSFromDotNet: (identifier: string, argsJson: string, resultType: JSCallResultType, targetInstanceId: number) => { - const returnValue = findJSFunction(identifier, targetInstanceId).apply(null, parseJsonWithRevivers(argsJson)); + invokeJSFromDotNet: (identifier: string, argsJson: string, byteArrays: Uint8Array[], resultType: JSCallResultType, targetInstanceId: number): SerializedArgs => { + const returnValue = findJSFunction(identifier, targetInstanceId).apply(null, parseJsonWithRevivers(argsJson, byteArrays)); const result = createJSCallResult(returnValue, resultType); - return result === null || result === undefined + const returnedByteArrays : Uint8Array[] = []; + var serializedJson = (result === null || result === undefined) ? null - : JSON.stringify(result, argReplacer); + : JSON.stringify(result, (key, value) => argReplacer(key, value, returnedByteArrays)); // TODO; confirm this works for blazor wasm + return new SerializedArgs(serializedJson, returnedByteArrays); }, /** @@ -313,14 +335,15 @@ export module DotNet { * @param asyncHandle A value identifying the asynchronous operation. This value will be passed back in a later call to endInvokeJSFromDotNet. * @param identifier Identifies the globally-reachable function to invoke. * @param argsJson JSON representation of arguments to be passed to the function. + * @param byteArrays Byte array data extracted from the arguments for direct transfer. * @param resultType The type of result expected from the JS interop call. * @param targetInstanceId The ID of the target JS object instance. */ - beginInvokeJSFromDotNet: (asyncHandle: number, identifier: string, argsJson: string, resultType: JSCallResultType, targetInstanceId: number): void => { + beginInvokeJSFromDotNet: (asyncHandle: number, identifier: string, argsJson: string, byteArrays: Uint8Array[], resultType: JSCallResultType, targetInstanceId: number): void => { // Coerce synchronous functions into async ones, plus treat // synchronous exceptions the same as async ones const promise = new Promise(resolve => { - const synchronousResultOrPromise = findJSFunction(identifier, targetInstanceId).apply(null, parseJsonWithRevivers(argsJson)); + const synchronousResultOrPromise = findJSFunction(identifier, targetInstanceId).apply(null, parseJsonWithRevivers(argsJson, byteArrays)); resolve(synchronousResultOrPromise); }); @@ -328,22 +351,24 @@ export module DotNet { if (asyncHandle) { // On completion, dispatch result back to .NET // Not using "await" because it codegens a lot of boilerplate + const byteArrays : Uint8Array[] = []; promise.then( - result => getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, true, JSON.stringify([asyncHandle, true, createJSCallResult(result, resultType)], argReplacer)), - error => getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, false, JSON.stringify([asyncHandle, false, formatError(error)])) + result => getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, true, JSON.stringify([asyncHandle, true, createJSCallResult(result, resultType)], (key, value) => argReplacer(key, value, byteArrays)), byteArrays), + error => getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, false, JSON.stringify([asyncHandle, false, formatError(error)]), null) ); } }, /** * Receives notification that an async call from JS to .NET has completed. - * @param asyncCallId The identifier supplied in an earlier call to beginInvokeDotNetFromJS. + * @param callId The identifier supplied in an earlier call to beginInvokeDotNetFromJS. * @param success A flag to indicate whether the operation completed successfully. * @param resultJsonOrExceptionMessage Either the operation result as JSON, or an error message. + * @param byteArrays Byte array data extracted from the arguments for direct transfer. */ - endInvokeDotNetFromJS: (asyncCallId: string, success: boolean, resultJsonOrExceptionMessage: string): void => { + endInvokeDotNetFromJS: (asyncCallId: string, success: boolean, resultJsonOrExceptionMessage: string, byteArrays: Uint8Array[]): void => { const resultOrError = success - ? parseJsonWithRevivers(resultJsonOrExceptionMessage) + ? parseJsonWithRevivers(resultJsonOrExceptionMessage, byteArrays) : new Error(resultJsonOrExceptionMessage); completePendingCall(parseInt(asyncCallId), success, resultOrError); } @@ -394,7 +419,7 @@ export module DotNet { } const dotNetObjectRefKey = '__dotNetObject'; - attachReviver(function reviveDotNetObject(key: any, value: any) { + attachReviver(function reviveDotNetObject(key: any, value: any, byteArrays: Uint8Array[] | null) { if (value && typeof value === 'object' && value.hasOwnProperty(dotNetObjectRefKey)) { return new DotNetObject(value.__dotNetObject); } @@ -403,7 +428,7 @@ export module DotNet { return value; }); - attachReviver(function reviveJSObjectReference(key: any, value: any) { + attachReviver(function reviveJSObjectReference(key: any, value: any, byteArrays: Uint8Array[] | null) { if (value && typeof value === 'object' && value.hasOwnProperty(jsObjectIdKey)) { const id = value[jsObjectIdKey]; const jsObject = cachedJSObjectsById[id]; @@ -419,6 +444,22 @@ export module DotNet { return value; }); + const byteArrayRefKey = '__byte[]'; + attachReviver(function reviveByteArray(key: any, value: any, byteArrays: Uint8Array[] | null) { + if (value && typeof value === 'object' && value.hasOwnProperty(byteArrayRefKey) && byteArrays) { + const index = value[byteArrayRefKey]; + + if (index >= byteArrays.length || index < 0) { + throw new Error(`Byte array index '${index}' does not exist.`) + } + + return byteArrays[value[byteArrayRefKey]]; + } + + // Unrecognized - let another reviver handle it + return value; + }); + function createJSCallResult(returnValue: any, resultType: JSCallResultType) { switch (resultType) { case JSCallResultType.Default: @@ -430,7 +471,18 @@ export module DotNet { } } - function argReplacer(key: string, value: any) { - return value instanceof DotNetObject ? value.serializeAsArg() : value; + function argReplacer(key: string, value: any, byteArrays: Uint8Array[]) { + if (value instanceof DotNetObject) + { + return value.serializeAsArg(); + } + else if (value instanceof Uint8Array) + { + var index = byteArrays.length; + byteArrays.push(value); + return { [byteArrayRefKey]: index }; + } + + return value; } } diff --git a/src/JSInterop/Microsoft.JSInterop/src/Implementation/JSObjectReferenceJsonWorker.cs b/src/JSInterop/Microsoft.JSInterop/src/Implementation/JSObjectReferenceJsonWorker.cs index c22f60a17056..abef6a927f8c 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/Implementation/JSObjectReferenceJsonWorker.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/Implementation/JSObjectReferenceJsonWorker.cs @@ -35,12 +35,12 @@ public static long ReadJSObjectReferenceIdentifier(ref Utf8JsonReader reader) } else { - throw new JsonException($"Unexcepted JSON property {reader.GetString()}."); + throw new JsonException($"Unexpected JSON property {reader.GetString()}."); } } else { - throw new JsonException($"Unexcepted JSON token {reader.TokenType}"); + throw new JsonException($"Unexpected JSON token {reader.TokenType}"); } } diff --git a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/ByteArrayJsonConverter.cs b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/ByteArrayJsonConverter.cs new file mode 100644 index 000000000000..4acc2e363707 --- /dev/null +++ b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/ByteArrayJsonConverter.cs @@ -0,0 +1,116 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading; + +namespace Microsoft.JSInterop.Infrastructure +{ + internal sealed class ByteArrayJsonConverter : JsonConverter + { + private byte[][]? _byteArraysToDeserialize; + + internal readonly SemaphoreSlim ReadSemaphore = new(initialCount: 1, maxCount: 1); + internal readonly SemaphoreSlim WriteSemaphore = new(initialCount: 1, maxCount: 1); + + internal static readonly JsonEncodedText ByteArrayRefKey = JsonEncodedText.Encode("__byte[]"); + + /// + /// Contains the byte array(s) being serialized. + /// + internal readonly ArrayBuilder ByteArraysToSerialize = new(); + + /// + /// Sets the byte array(s) being deserialized. + /// + internal byte[][]? ByteArraysToDeserialize + { + set + { + if (value is null) + { + _byteArraysToDeserialize = null; + ReadSemaphore.Release(); + return; + } + + if (_byteArraysToDeserialize is not null || + !ReadSemaphore.Wait(millisecondsTimeout: 100)) + { + throw new JsonException("Unable to deserialize arguments, previous deserialization is incomplete."); + } + + _byteArraysToDeserialize = value; + } + } + + public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(byte[]); + + public override byte[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (ReadSemaphore.CurrentCount != 0) + { + throw new JsonException("Must acquire ReadSemaphore before requesting byte array deserialization."); + } + + if (_byteArraysToDeserialize is null) + { + throw new JsonException("ByteArraysToDeserialize not set."); + } + + long? byteArrayIndex = null; + + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType == JsonTokenType.PropertyName) + { + if (byteArrayIndex is null && reader.ValueTextEquals(ByteArrayRefKey.EncodedUtf8Bytes)) + { + reader.Read(); + byteArrayIndex = reader.GetInt64(); + } + else + { + throw new JsonException($"Unexpected JSON property {reader.GetString()}."); + } + } + else + { + throw new JsonException($"Unexpected JSON Token {reader.TokenType}."); + } + } + + if (byteArrayIndex is null) + { + throw new JsonException($"Required property {ByteArrayRefKey} not found."); + } + + if (byteArrayIndex >= _byteArraysToDeserialize.Length || byteArrayIndex < 0) + { + throw new JsonException($"Byte array {byteArrayIndex} not found."); + } + + var value = _byteArraysToDeserialize[byteArrayIndex.Value]; + return value; + } + + public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options) + { + if (WriteSemaphore.CurrentCount != 0) + { + throw new JsonException("Must acquire WriteSemaphore before requesting byte array serialization."); + } + + var id = ByteArraysToSerialize.Count; + + ByteArraysToSerialize.Append(value); + + writer.WriteStartObject(); + writer.WriteNumber(ByteArrayRefKey, id); + writer.WriteEndObject(); + } + } +} diff --git a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs index 45d0a0fef26b..bd59ec2f65b6 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetDispatcher.cs @@ -11,6 +11,7 @@ using System.Text; using System.Text.Json; using System.Threading.Tasks; +using static Microsoft.JSInterop.JSRuntime; [assembly: MetadataUpdateHandler(typeof(Microsoft.JSInterop.Infrastructure.DotNetDispatcher))] @@ -34,9 +35,9 @@ public static class DotNetDispatcher /// /// The . /// The . - /// A JSON representation of the parameters. - /// A JSON representation of the return value, or null. - public static string? Invoke(JSRuntime jsRuntime, in DotNetInvocationInfo invocationInfo, string argsJson) + /// The serialized args containing the JSON representation along with the extracted byte arrays. + /// A record containing the JSON representation of the return value, or null, along with the extracted byte arrays, or null. + public static SerializedArgs Invoke(JSRuntime jsRuntime, in DotNetInvocationInfo invocationInfo, SerializedArgs serializedArgs) { // This method doesn't need [JSInvokable] because the platform is responsible for having // some way to dispatch calls here. The logic inside here is the thing that checks whether @@ -49,13 +50,13 @@ public static class DotNetDispatcher targetInstance = jsRuntime.GetObjectReference(invocationInfo.DotNetObjectId); } - var syncResult = InvokeSynchronously(jsRuntime, invocationInfo, targetInstance, argsJson); + var syncResult = InvokeSynchronously(jsRuntime, invocationInfo, targetInstance, serializedArgs); if (syncResult == null) { - return null; + return new SerializedArgs(null, null); } - return JsonSerializer.Serialize(syncResult, jsRuntime.JsonSerializerOptions); + return SerializeArgs(jsRuntime, syncResult); } /// @@ -63,9 +64,8 @@ public static class DotNetDispatcher /// /// The . /// The . - /// A JSON representation of the parameters. - /// A JSON representation of the return value, or null. - public static void BeginInvokeDotNet(JSRuntime jsRuntime, DotNetInvocationInfo invocationInfo, string argsJson) + /// The serialized args containing the JSON representation along with the extracted byte arrays. + public static void BeginInvokeDotNet(JSRuntime jsRuntime, DotNetInvocationInfo invocationInfo, SerializedArgs serializedArgs) { // This method doesn't need [JSInvokable] because the platform is responsible for having // some way to dispatch calls here. The logic inside here is the thing that checks whether @@ -87,7 +87,7 @@ public static void BeginInvokeDotNet(JSRuntime jsRuntime, DotNetInvocationInfo i targetInstance = jsRuntime.GetObjectReference(invocationInfo.DotNetObjectId); } - syncResult = InvokeSynchronously(jsRuntime, invocationInfo, targetInstance, argsJson); + syncResult = InvokeSynchronously(jsRuntime, invocationInfo, targetInstance, serializedArgs); } catch (Exception ex) { @@ -112,8 +112,8 @@ public static void BeginInvokeDotNet(JSRuntime jsRuntime, DotNetInvocationInfo i } else { - var syncResultJson = JsonSerializer.Serialize(syncResult, jsRuntime.JsonSerializerOptions); - var dispatchResult = new DotNetInvocationResult(syncResultJson); + var serializedReturnArgs = SerializeArgs(jsRuntime, syncResult); + var dispatchResult = new DotNetInvocationResult(serializedReturnArgs); jsRuntime.EndInvokeDotNet(invocationInfo, dispatchResult); } } @@ -128,11 +128,11 @@ private static void EndInvokeDotNetAfterTask(Task task, JSRuntime jsRuntime, in } var result = TaskGenericsUtil.GetTaskResult(task); - var resultJson = JsonSerializer.Serialize(result, jsRuntime.JsonSerializerOptions); - jsRuntime.EndInvokeDotNet(invocationInfo, new DotNetInvocationResult(resultJson)); + var serializedArgs = SerializeArgs(jsRuntime, result); + jsRuntime.EndInvokeDotNet(invocationInfo, new DotNetInvocationResult(serializedArgs)); } - private static object? InvokeSynchronously(JSRuntime jsRuntime, in DotNetInvocationInfo callInfo, IDotNetObjectReference? objectReference, string argsJson) + private static object? InvokeSynchronously(JSRuntime jsRuntime, in DotNetInvocationInfo callInfo, IDotNetObjectReference? objectReference, SerializedArgs serializedArgs) { var assemblyName = callInfo.AssemblyName; var methodIdentifier = callInfo.MethodIdentifier; @@ -162,7 +162,7 @@ private static void EndInvokeDotNetAfterTask(Task task, JSRuntime jsRuntime, in (methodInfo, parameterTypes) = GetCachedMethodInfo(objectReference, methodIdentifier); } - var suppliedArgs = ParseArguments(jsRuntime, methodIdentifier, argsJson, parameterTypes); + var suppliedArgs = ParseArguments(jsRuntime, methodIdentifier, serializedArgs, parameterTypes); try { @@ -181,14 +181,14 @@ private static void EndInvokeDotNetAfterTask(Task task, JSRuntime jsRuntime, in } } - internal static object?[] ParseArguments(JSRuntime jsRuntime, string methodIdentifier, string arguments, Type[] parameterTypes) + internal static object?[] ParseArguments(JSRuntime jsRuntime, string methodIdentifier, SerializedArgs serializedArgs, Type[] parameterTypes) { if (parameterTypes.Length == 0) { return Array.Empty(); } - var utf8JsonBytes = Encoding.UTF8.GetBytes(arguments); + var utf8JsonBytes = Encoding.UTF8.GetBytes(serializedArgs.ArgsJson ?? string.Empty); var reader = new Utf8JsonReader(utf8JsonBytes); if (!reader.Read() || reader.TokenType != JsonTokenType.StartArray) { @@ -197,6 +197,8 @@ private static void EndInvokeDotNetAfterTask(Task task, JSRuntime jsRuntime, in var suppliedArgs = new object?[parameterTypes.Length]; + jsRuntime.ByteArrayJsonConverter.ByteArraysToDeserialize = serializedArgs.ByteArrays; + var index = 0; while (index < parameterTypes.Length && reader.Read() && reader.TokenType != JsonTokenType.EndArray) { @@ -222,6 +224,8 @@ private static void EndInvokeDotNetAfterTask(Task task, JSRuntime jsRuntime, in throw new JsonException($"Unexpected JSON token {reader.TokenType}. Ensure that the call to `{methodIdentifier}' is supplied with exactly '{parameterTypes.Length}' parameters."); } + jsRuntime.ByteArrayJsonConverter.ByteArraysToDeserialize = null; + return suppliedArgs; // Note that the JsonReader instance is intentionally not passed by ref (or an in parameter) since we want a copy of the original reader. @@ -256,14 +260,14 @@ static bool IsIncorrectDotNetObjectRefUse(Type parameterType, Utf8JsonReader jso /// passed in as parameters. /// /// The . - /// The serialized arguments for the callback completion. + /// The serialized args containing the JSON representation along with the extracted byte arrays. /// /// This method can throw any exception either from the argument received or as a result /// of executing any callback synchronously upon completion. /// - public static void EndInvokeJS(JSRuntime jsRuntime, string arguments) + public static void EndInvokeJS(JSRuntime jsRuntime, SerializedArgs serializedArgs) { - var utf8JsonBytes = Encoding.UTF8.GetBytes(arguments); + var utf8JsonBytes = Encoding.UTF8.GetBytes(serializedArgs.ArgsJson ?? string.Empty); // The payload that we're trying to parse is of the format // [ taskId: long, success: boolean, value: string? | object ] @@ -284,7 +288,7 @@ public static void EndInvokeJS(JSRuntime jsRuntime, string arguments) var success = reader.GetBoolean(); reader.Read(); - jsRuntime.EndInvokeJS(taskId, success, ref reader); + jsRuntime.EndInvokeJS(taskId, success, ref reader, serializedArgs.ByteArrays); if (!reader.Read() || reader.TokenType != JsonTokenType.EndArray) { @@ -292,6 +296,34 @@ public static void EndInvokeJS(JSRuntime jsRuntime, string arguments) } } + /// + /// Serialize the args to a json string, with the byte arrays + /// extracted out for seperate transmission. + /// + /// The . + /// Arguments to be converted to json. + /// + /// A tuple of the json string and an array containing the extracted + /// byte arrays from the args. + /// + internal static SerializedArgs SerializeArgs(JSRuntime jsRuntime, object? args) + { + if (jsRuntime.ByteArrayJsonConverter.ByteArraysToSerialize.Count != 0 || + !jsRuntime.ByteArrayJsonConverter.WriteSemaphore.Wait(millisecondsTimeout: 100)) + { + throw new JsonException("Unable to serialize arguments, previous serialization is incomplete."); + } + + var serializedArgs = JsonSerializer.Serialize(args, jsRuntime.JsonSerializerOptions); + var numByteArrays = jsRuntime.ByteArrayJsonConverter.ByteArraysToSerialize.Count; + var byteArrays = new byte[numByteArrays][]; + Array.Copy(jsRuntime.ByteArrayJsonConverter.ByteArraysToSerialize.Buffer, byteArrays, numByteArrays); + jsRuntime.ByteArrayJsonConverter.ByteArraysToSerialize.Clear(); + jsRuntime.ByteArrayJsonConverter.WriteSemaphore.Release(); + + return new(serializedArgs, byteArrays); + } + private static (MethodInfo, Type[]) GetCachedMethodInfo(AssemblyKey assemblyKey, string methodIdentifier) { if (string.IsNullOrWhiteSpace(assemblyKey.AssemblyName)) @@ -421,7 +453,7 @@ private static Assembly GetRequiredLoadedAssembly(AssemblyKey assemblyKey) // In most ordinary scenarios, we wouldn't have two instances of the same Assembly in the AppDomain // so this doesn't change the outcome. Assembly? assembly = null; - foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) + foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { if (new AssemblyKey(a).Equals(assemblyKey)) { diff --git a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetInvocationResult.cs b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetInvocationResult.cs index 1d1bb6184369..797119304657 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetInvocationResult.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetInvocationResult.cs @@ -15,6 +15,7 @@ public readonly struct DotNetInvocationResult internal DotNetInvocationResult(Exception exception, string? errorKind) { ResultJson = default; + ByteArrays = default; Exception = exception ?? throw new ArgumentNullException(nameof(exception)); ErrorKind = errorKind; Success = false; @@ -23,10 +24,11 @@ internal DotNetInvocationResult(Exception exception, string? errorKind) /// /// Constructor for a successful invocation. /// - /// The JSON representation of the result. - internal DotNetInvocationResult(string? resultJson) + /// Serialized JSON representation of the result with the extracted byte arrays. + internal DotNetInvocationResult(SerializedArgs args) { - ResultJson = resultJson; + ResultJson = args.ArgsJson; + ByteArrays = args.ByteArrays; Exception = default; ErrorKind = default; Success = true; @@ -47,6 +49,11 @@ internal DotNetInvocationResult(string? resultJson) /// public string? ResultJson { get; } + /// + /// Gets the byte array data extracted from the result for direct transfer. + /// + public byte[][]? ByteArrays { get; } + /// /// if the invocation succeeded, otherwise . /// diff --git a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetObjectReferenceJsonConverter.cs b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetObjectReferenceJsonConverter.cs index 7658bbc2c355..a10bbd16347f 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetObjectReferenceJsonConverter.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/Infrastructure/DotNetObjectReferenceJsonConverter.cs @@ -33,12 +33,12 @@ public override DotNetObjectReference Read(ref Utf8JsonReader reader, Ty } else { - throw new JsonException($"Unexcepted JSON property {reader.GetString()}."); + throw new JsonException($"Unexpected JSON property {reader.GetString()}."); } } else { - throw new JsonException($"Unexcepted JSON Token {reader.TokenType}."); + throw new JsonException($"Unexpected JSON Token {reader.TokenType}."); } } diff --git a/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntime.cs b/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntime.cs index 5ff4804880c3..fb48b171b1ce 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntime.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntime.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Microsoft.JSInterop.Infrastructure; using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.JSInterop @@ -15,9 +16,12 @@ public abstract class JSInProcessRuntime : JSRuntime, IJSInProcessRuntime [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")] internal TValue Invoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, long targetInstanceId, params object?[]? args) { + var serializedArgs = DotNetDispatcher.SerializeArgs(this, args); + var resultJson = InvokeJS( identifier, - JsonSerializer.Serialize(args, JsonSerializerOptions), + serializedArgs.ArgsJson, + serializedArgs.ByteArrays, JSCallResultTypeHelper.FromGeneric(), targetInstanceId); @@ -48,18 +52,20 @@ public abstract class JSInProcessRuntime : JSRuntime, IJSInProcessRuntime /// /// The identifier for the function to invoke. /// A JSON representation of the arguments. + /// Byte array data extracted from the arguments for direct transfer. /// A JSON representation of the result. - protected virtual string? InvokeJS(string identifier, string? argsJson) - => InvokeJS(identifier, argsJson, JSCallResultType.Default, 0); + protected virtual string? InvokeJS(string identifier, string? argsJson, byte[][]? byteArrays) + => InvokeJS(identifier, argsJson, byteArrays, JSCallResultType.Default, 0); /// /// Performs a synchronous function invocation. /// /// The identifier for the function to invoke. /// A JSON representation of the arguments. + /// Byte array data extracted from the arguments for direct transfer. /// The type of result expected from the invocation. /// The instance ID of the target JS object. /// A JSON representation of the result. - protected abstract string? InvokeJS(string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId); + protected abstract string? InvokeJS(string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId); } } diff --git a/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs b/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs index d92fd66f3f46..a378d08e3180 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs @@ -20,16 +20,16 @@ public abstract partial class JSRuntime : IJSRuntime { private long _nextObjectReferenceId = 0; // 0 signals no object, but we increment prior to assignment. The first tracked object should have id 1 private long _nextPendingTaskId = 1; // Start at 1 because zero signals "no response needed" - private readonly ConcurrentDictionary _pendingTasks = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _trackedRefsById = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _cancellationRegistrations = - new ConcurrentDictionary(); + private readonly ConcurrentDictionary _pendingTasks = new(); + private readonly ConcurrentDictionary _trackedRefsById = new(); + private readonly ConcurrentDictionary _cancellationRegistrations = new(); /// /// Initializes a new instance of . /// protected JSRuntime() { + ByteArrayJsonConverter = new ByteArrayJsonConverter(); JsonSerializerOptions = new JsonSerializerOptions { MaxDepth = 32, @@ -39,6 +39,7 @@ protected JSRuntime() { new DotNetObjectReferenceJsonConverterFactory(this), new JSObjectReferenceJsonConverter(this), + ByteArrayJsonConverter, } }; } @@ -48,6 +49,11 @@ protected JSRuntime() /// protected internal JsonSerializerOptions JsonSerializerOptions { get; } + /// + /// Gets the used to serialize and deserialize byte arrays from the interop payloads. + /// + internal ByteArrayJsonConverter ByteArrayJsonConverter { get; } + /// /// Gets or sets the default timeout for asynchronous JavaScript calls. /// @@ -121,12 +127,13 @@ protected JSRuntime() return new ValueTask(tcs.Task); } - var argsJson = args is not null && args.Length != 0 ? - JsonSerializer.Serialize(args, JsonSerializerOptions) : - null; + var serializedArgs = args is not null && args.Length != 0 ? + DotNetDispatcher.SerializeArgs(this, args) : + new SerializedArgs(null, null); var resultType = JSCallResultTypeHelper.FromGeneric(); - BeginInvokeJS(taskId, identifier, argsJson, resultType, targetInstanceId); + + BeginInvokeJS(taskId, identifier, serializedArgs, resultType, targetInstanceId); return new ValueTask(tcs.Task); } @@ -151,19 +158,19 @@ private void CleanupTasksAndRegistrations(long taskId) /// /// The identifier for the function invocation, or zero if no async callback is required. /// The identifier for the function to invoke. - /// A JSON representation of the arguments. - protected virtual void BeginInvokeJS(long taskId, string identifier, string? argsJson) - => BeginInvokeJS(taskId, identifier, argsJson, JSCallResultType.Default, 0); + /// The serialized args containing the JSON representation along with the extracted byte arrays. + protected virtual void BeginInvokeJS(long taskId, string identifier, SerializedArgs serializedArgs) + => BeginInvokeJS(taskId, identifier, serializedArgs, JSCallResultType.Default, 0); /// /// Begins an asynchronous function invocation. /// /// The identifier for the function invocation, or zero if no async callback is required. /// The identifier for the function to invoke. - /// A JSON representation of the arguments. + /// The serialized args containing the JSON representation along with the extracted byte arrays. /// The type of result expected from the invocation. /// The instance ID of the target JS object. - protected abstract void BeginInvokeJS(long taskId, string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId); + protected abstract void BeginInvokeJS(long taskId, string identifier, SerializedArgs serializedArgs, JSCallResultType resultType, long targetInstanceId); /// /// Completes an async JS interop call from JavaScript to .NET @@ -175,7 +182,7 @@ protected internal abstract void EndInvokeDotNet( in DotNetInvocationResult invocationResult); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:RequiresUnreferencedCode", Justification = "We enforce trimmer attributes for JSON deserialized types on InvokeAsync.")] - internal void EndInvokeJS(long taskId, bool succeeded, ref Utf8JsonReader jsonReader) + internal void EndInvokeJS(long taskId, bool succeeded, ref Utf8JsonReader jsonReader, byte[][]? byteArrays) { if (!_pendingTasks.TryRemove(taskId, out var tcs)) { @@ -192,8 +199,10 @@ internal void EndInvokeJS(long taskId, bool succeeded, ref Utf8JsonReader jsonRe { var resultType = TaskGenericsUtil.GetTaskCompletionSourceResultType(tcs); + ByteArrayJsonConverter.ByteArraysToDeserialize = byteArrays; var result = JsonSerializer.Deserialize(ref jsonReader, resultType, JsonSerializerOptions); TaskGenericsUtil.SetTaskCompletionSourceResult(tcs, result); + ByteArrayJsonConverter.ByteArraysToDeserialize = null; } else { diff --git a/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.csproj b/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.csproj index 892f64884a5d..b275126eca44 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.csproj +++ b/src/JSInterop/Microsoft.JSInterop/src/Microsoft.JSInterop.csproj @@ -8,11 +8,13 @@ true enable true + $(DefineConstants);JS_INTEROP + diff --git a/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Shipped.txt b/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Shipped.txt index 11b328fa0b55..2ce6cf0ff29e 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Shipped.txt +++ b/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Shipped.txt @@ -71,13 +71,8 @@ Microsoft.JSInterop.JSRuntime.InvokeAsync(string! identifier, object?[]? Microsoft.JSInterop.JSRuntime.JSRuntime() -> void Microsoft.JSInterop.JSRuntime.JsonSerializerOptions.get -> System.Text.Json.JsonSerializerOptions! Microsoft.JSInterop.JSRuntimeExtensions -abstract Microsoft.JSInterop.JSInProcessRuntime.InvokeJS(string! identifier, string? argsJson, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> string? -abstract Microsoft.JSInterop.JSRuntime.BeginInvokeJS(long taskId, string! identifier, string? argsJson, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> void abstract Microsoft.JSInterop.JSRuntime.EndInvokeDotNet(Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, in Microsoft.JSInterop.Infrastructure.DotNetInvocationResult invocationResult) -> void static Microsoft.JSInterop.DotNetObjectReference.Create(TValue! value) -> Microsoft.JSInterop.DotNetObjectReference! -static Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(Microsoft.JSInterop.JSRuntime! jsRuntime, Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string! argsJson) -> void -static Microsoft.JSInterop.Infrastructure.DotNetDispatcher.EndInvokeJS(Microsoft.JSInterop.JSRuntime! jsRuntime, string! arguments) -> void -static Microsoft.JSInterop.Infrastructure.DotNetDispatcher.Invoke(Microsoft.JSInterop.JSRuntime! jsRuntime, in Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, string! argsJson) -> string? static Microsoft.JSInterop.JSInProcessObjectReferenceExtensions.InvokeVoid(this Microsoft.JSInterop.IJSInProcessObjectReference! jsObjectReference, string! identifier, params object?[]! args) -> void static Microsoft.JSInterop.JSInProcessRuntimeExtensions.InvokeVoid(this Microsoft.JSInterop.IJSInProcessRuntime! jsRuntime, string! identifier, params object?[]! args) -> void static Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeAsync(this Microsoft.JSInterop.IJSObjectReference! jsObjectReference, string! identifier, System.Threading.CancellationToken cancellationToken, params object?[]! args) -> System.Threading.Tasks.ValueTask @@ -92,6 +87,4 @@ static Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync(this Microsof static Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, System.Threading.CancellationToken cancellationToken, params object![]! args) -> System.Threading.Tasks.ValueTask static Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, System.TimeSpan timeout, params object![]! args) -> System.Threading.Tasks.ValueTask static Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, params object![]! args) -> System.Threading.Tasks.ValueTask -virtual Microsoft.JSInterop.JSInProcessRuntime.InvokeJS(string! identifier, string? argsJson) -> string? -virtual Microsoft.JSInterop.JSRuntime.BeginInvokeJS(long taskId, string! identifier, string? argsJson) -> void ~Microsoft.JSInterop.DotNetObjectReference diff --git a/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt b/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt index 1a47a75ae77a..cc60439d3e20 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt +++ b/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt @@ -1,12 +1,22 @@ #nullable enable Microsoft.JSInterop.Implementation.JSObjectReferenceJsonWorker +Microsoft.JSInterop.Infrastructure.DotNetInvocationResult.ByteArrays.get -> byte[]![]? Microsoft.JSInterop.Infrastructure.DotNetInvocationResult.ResultJson.get -> string? +Microsoft.JSInterop.SerializedArgs +Microsoft.JSInterop.SerializedArgs.SerializedArgs(string? argsJson, byte[]![]? byteArrays) -> void +abstract Microsoft.JSInterop.JSInProcessRuntime.InvokeJS(string! identifier, string? argsJson, byte[]![]? byteArrays, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> string? +abstract Microsoft.JSInterop.JSRuntime.BeginInvokeJS(long taskId, string! identifier, Microsoft.JSInterop.SerializedArgs serializedArgs, Microsoft.JSInterop.JSCallResultType resultType, long targetInstanceId) -> void +readonly Microsoft.JSInterop.SerializedArgs.ArgsJson -> string? +readonly Microsoft.JSInterop.SerializedArgs.ByteArrays -> byte[]![]? static Microsoft.JSInterop.Implementation.JSObjectReferenceJsonWorker.ReadJSObjectReferenceIdentifier(ref System.Text.Json.Utf8JsonReader reader) -> long static Microsoft.JSInterop.Implementation.JSObjectReferenceJsonWorker.WriteJSObjectReference(System.Text.Json.Utf8JsonWriter! writer, Microsoft.JSInterop.Implementation.JSObjectReference! objectReference) -> void *REMOVED*Microsoft.JSInterop.Infrastructure.DotNetInvocationResult.DotNetInvocationResult(System.Exception! exception, string? errorKind) -> void *REMOVED*Microsoft.JSInterop.Infrastructure.DotNetInvocationResult.DotNetInvocationResult(object? result) -> void *REMOVED*Microsoft.JSInterop.Infrastructure.DotNetInvocationResult.Result.get -> object? *REMOVED*static Microsoft.JSInterop.JSInProcessObjectReferenceExtensions.InvokeVoid(this Microsoft.JSInterop.IJSInProcessObjectReference! jsObjectReference, string! identifier, params object?[]! args) -> void +static Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(Microsoft.JSInterop.JSRuntime! jsRuntime, Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, Microsoft.JSInterop.SerializedArgs serializedArgs) -> void +static Microsoft.JSInterop.Infrastructure.DotNetDispatcher.EndInvokeJS(Microsoft.JSInterop.JSRuntime! jsRuntime, Microsoft.JSInterop.SerializedArgs serializedArgs) -> void +static Microsoft.JSInterop.Infrastructure.DotNetDispatcher.Invoke(Microsoft.JSInterop.JSRuntime! jsRuntime, in Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, Microsoft.JSInterop.SerializedArgs serializedArgs) -> Microsoft.JSInterop.SerializedArgs static Microsoft.JSInterop.JSInProcessObjectReferenceExtensions.InvokeVoid(this Microsoft.JSInterop.IJSInProcessObjectReference! jsObjectReference, string! identifier, params object?[]? args) -> void *REMOVED*static Microsoft.JSInterop.JSInProcessRuntimeExtensions.InvokeVoid(this Microsoft.JSInterop.IJSInProcessRuntime! jsRuntime, string! identifier, params object?[]! args) -> void static Microsoft.JSInterop.JSInProcessRuntimeExtensions.InvokeVoid(this Microsoft.JSInterop.IJSInProcessRuntime! jsRuntime, string! identifier, params object?[]? args) -> void @@ -28,3 +38,5 @@ static Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(this Microsoft.JS static Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, System.TimeSpan timeout, params object?[]? args) -> System.Threading.Tasks.ValueTask *REMOVED*static Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, params object![]! args) -> System.Threading.Tasks.ValueTask static Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, params object?[]? args) -> System.Threading.Tasks.ValueTask +virtual Microsoft.JSInterop.JSInProcessRuntime.InvokeJS(string! identifier, string? argsJson, byte[]![]? byteArrays) -> string? +virtual Microsoft.JSInterop.JSRuntime.BeginInvokeJS(long taskId, string! identifier, Microsoft.JSInterop.SerializedArgs serializedArgs) -> void diff --git a/src/JSInterop/Microsoft.JSInterop/src/SerializedArgs.cs b/src/JSInterop/Microsoft.JSInterop/src/SerializedArgs.cs new file mode 100644 index 000000000000..f7417c83391d --- /dev/null +++ b/src/JSInterop/Microsoft.JSInterop/src/SerializedArgs.cs @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.JSInterop +{ + /// + /// Combined json string and extracted byte arrays for an + /// interop message. + /// + public readonly struct SerializedArgs + { + /// + /// json string representing the arguments + /// + public readonly string? ArgsJson; + + /// + /// Byte arrays extracted from the arguments during serialization + /// + public readonly byte[][]? ByteArrays; + + /// + /// Struct containing the json args and extracted byte arrays + /// + /// json string representing the arguments + /// Byte arrays extracted from the arguments during serialization + public SerializedArgs(string? argsJson, byte[][]? byteArrays) + { + ArgsJson = argsJson; + ByteArrays = byteArrays; + } + } +} diff --git a/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs b/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs index e8211e8c0fed..a14ed9073b1c 100644 --- a/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs +++ b/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/DotNetDispatcherTest.cs @@ -20,7 +20,7 @@ public void CannotInvokeWithEmptyAssemblyName() { var ex = Assert.Throws(() => { - DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo(" ", "SomeMethod", default, default), "[]"); + DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo(" ", "SomeMethod", default, default), "[]", byteArrays: null); }); Assert.StartsWith("Cannot be null, empty, or whitespace.", ex.Message); @@ -32,7 +32,7 @@ public void CannotInvokeWithEmptyMethodIdentifier() { var ex = Assert.Throws(() => { - DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo("SomeAssembly", " ", default, default), "[]"); + DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo("SomeAssembly", " ", default, default), "[]", byteArrays: null); }); Assert.StartsWith("Cannot be null, empty, or whitespace.", ex.Message); @@ -45,7 +45,7 @@ public void CannotInvokeMethodsOnUnloadedAssembly() var assemblyName = "Some.Fake.Assembly"; var ex = Assert.Throws(() => { - DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo(assemblyName, "SomeMethod", default, default), null); + DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo(assemblyName, "SomeMethod", default, default), null, byteArrays: null); }); Assert.Equal($"There is no loaded assembly with the name '{assemblyName}'.", ex.Message); @@ -67,7 +67,7 @@ public void CannotInvokeUnsuitableMethods(string methodIdentifier) { var ex = Assert.Throws(() => { - DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo(thisAssemblyName, methodIdentifier, default, default), null); + DotNetDispatcher.Invoke(new TestJSRuntime(), new DotNetInvocationInfo(thisAssemblyName, methodIdentifier, default, default), null, byteArrays: null); }); Assert.Equal($"The assembly '{thisAssemblyName}' does not contain a public invokable method with [JSInvokableAttribute(\"{methodIdentifier}\")].", ex.Message); @@ -79,10 +79,11 @@ public void CanInvokeStaticVoidMethod() // Arrange/Act var jsRuntime = new TestJSRuntime(); SomePublicType.DidInvokeMyInvocableStaticVoid = false; - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticVoid", default, default), null); + var (resultJson, byteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticVoid", default, default), null, byteArrays: null); // Assert Assert.Null(resultJson); + Assert.Null(byteArrays); Assert.True(SomePublicType.DidInvokeMyInvocableStaticVoid); } @@ -91,8 +92,10 @@ public void CanInvokeStaticNonVoidMethod() { // Arrange/Act var jsRuntime = new TestJSRuntime(); - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticNonVoid", default, default), null); + var (resultJson, byteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticNonVoid", default, default), null, byteArrays: null); + jsRuntime.ByteArraysToDeserialize = byteArrays; var result = JsonSerializer.Deserialize(resultJson, jsRuntime.JsonSerializerOptions); + jsRuntime.ByteArraysToDeserialize = null; // Assert Assert.Equal("Test", result.StringVal); @@ -104,8 +107,10 @@ public void CanInvokeStaticNonVoidMethodWithoutCustomIdentifier() { // Arrange/Act var jsRuntime = new TestJSRuntime(); - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, nameof(SomePublicType.InvokableMethodWithoutCustomIdentifier), default, default), null); + var (resultJson, byteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, nameof(SomePublicType.InvokableMethodWithoutCustomIdentifier), default, default), null, byteArrays: null); + jsRuntime.ByteArraysToDeserialize = byteArrays; var result = JsonSerializer.Deserialize(resultJson, jsRuntime.JsonSerializerOptions); + jsRuntime.ByteArraysToDeserialize = null; // Assert Assert.Equal("InvokableMethodWithoutCustomIdentifier", result.StringVal); @@ -122,20 +127,22 @@ public void CanInvokeStaticWithParams() jsRuntime.Invoke("unimportant", objectRef); // Arrange: Remaining args - var argsJson = JsonSerializer.Serialize(new object[] + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { new TestDTO { StringVal = "Another string", IntVal = 456 }, new[] { 100, 200 }, objectRef - }, jsRuntime.JsonSerializerOptions); + }); // Act - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, default), argsJson); + var (resultJson, returnedByteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, default), argsJson, byteArrays); var result = JsonDocument.Parse(resultJson); var root = result.RootElement; // Assert: First result value marshalled via JSON + jsRuntime.ByteArraysToDeserialize = returnedByteArrays; var resultDto1 = JsonSerializer.Deserialize(root[0].GetRawText(), jsRuntime.JsonSerializerOptions); + jsRuntime.ByteArraysToDeserialize = null; Assert.Equal("ANOTHER STRING", resultDto1.StringVal); Assert.Equal(756, resultDto1.IntVal); @@ -151,6 +158,45 @@ public void CanInvokeStaticWithParams() Assert.Equal(1299, resultDto2.IntVal); } + [Fact] + public void CanInvokeWithByteArrayParams() + { + // Arrange: Track a .NET object to use as an arg + var jsRuntime = new TestJSRuntime(); + + // Arrange: Remaining args + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] + { + new TestDTO { StringVal = "Another string", IntVal = 456, ByteArrayVal = new byte[] { 0x1, 0x12, 0x17 } }, + new[] { 100, 200 }, + new byte[] { 0x2, 0x4, 0x7, 0x11 } + }); + + // Act + var (resultJson, returnedByteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableWithByteArrayParams", default, default), argsJson, byteArrays); + var result = JsonDocument.Parse(resultJson); + var root = result.RootElement; + + // Assert: First result value marshalled via JSON + jsRuntime.ByteArraysToDeserialize = returnedByteArrays; + var resultDto1 = JsonSerializer.Deserialize(root[0].GetRawText(), jsRuntime.JsonSerializerOptions); + jsRuntime.ByteArraysToDeserialize = null; + + Assert.Equal("ANOTHER STRING", resultDto1.StringVal); + Assert.Equal(756, resultDto1.IntVal); + Assert.Equal(new byte[] { 0x17, 0x12, 0x1 }, resultDto1.ByteArrayVal); + + // Assert: Second result value marshalled by ref + var resultDto2Ref = root[1]; + Assert.False(resultDto2Ref.TryGetProperty(nameof(TestDTO.StringVal), out _)); + Assert.False(resultDto2Ref.TryGetProperty(nameof(TestDTO.IntVal), out _)); + Assert.False(resultDto2Ref.TryGetProperty(nameof(TestDTO.ByteArrayVal), out _)); + + Assert.True(resultDto2Ref.TryGetProperty(ByteArrayJsonConverter.ByteArrayRefKey.EncodedUtf8Bytes, out var property)); + var index = property.GetInt64(); + Assert.Equal(new byte[] { 0x11, 0x7, 0x4, 0x2 }, returnedByteArrays[index]); + } + [Fact] public void InvokingWithIncorrectUseOfDotNetObjectRefThrows() { @@ -162,16 +208,16 @@ public void InvokingWithIncorrectUseOfDotNetObjectRefThrows() jsRuntime.Invoke("unimportant", objectRef); // Arrange: Remaining args - var argsJson = JsonSerializer.Serialize(new object[] + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { new TestDTO { StringVal = "Another string", IntVal = 456 }, new[] { 100, 200 }, objectRef - }, jsRuntime.JsonSerializerOptions); + }); // Act & Assert var ex = Assert.Throws(() => - DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, method, default, default), argsJson)); + DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, method, default, default), argsJson, byteArrays)); Assert.Equal($"In call to '{method}', parameter of type '{nameof(TestDTO)}' at index 3 must be declared as type 'DotNetObjectRef' to receive the incoming value.", ex.Message); } @@ -185,10 +231,11 @@ public void CanInvokeInstanceVoidMethod() jsRuntime.Invoke("unimportant", objectRef); // Act - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, default), null); + var (resultJson, returnedByteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, default), null, byteArrays: null); // Assert Assert.Null(resultJson); + Assert.Null(returnedByteArrays); Assert.True(targetInstance.DidInvokeMyInvocableInstanceVoid); } @@ -202,10 +249,11 @@ public void CanInvokeBaseInstanceVoidMethod() jsRuntime.Invoke("unimportant", objectRef); // Act - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "BaseClassInvokableInstanceVoid", 1, default), null); + var (resultJson, returnedByteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "BaseClassInvokableInstanceVoid", 1, default), null, byteArrays: null); // Assert Assert.Null(resultJson); + Assert.Null(returnedByteArrays); Assert.True(targetInstance.DidInvokeMyBaseClassInvocableInstanceVoid); } @@ -219,7 +267,7 @@ public void DotNetObjectReferencesCanBeDisposed() jsRuntime.Invoke("unimportant", objectRef); // Act - DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null, "__Dispose", objectRef.ObjectId, default), null); + DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null, "__Dispose", objectRef.ObjectId, default), null, byteArrays: null); // Assert Assert.True(objectRef.Disposed); @@ -240,7 +288,7 @@ public void CannotUseDotNetObjectRefAfterDisposal() // Act/Assert var ex = Assert.Throws( - () => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, default), null)); + () => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, default), null, byteArrays: null)); Assert.StartsWith("There is no tracked object with id '1'.", ex.Message); } @@ -259,7 +307,7 @@ public void CannotUseDotNetObjectRefAfterReleaseDotNetObject() // Act/Assert var ex = Assert.Throws( - () => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, default), null)); + () => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, default), null, byteArrays: null)); Assert.StartsWith("There is no tracked object with id '1'.", ex.Message); } @@ -268,12 +316,13 @@ public void EndInvoke_WithSuccessValue() { // Arrange var jsRuntime = new TestJSRuntime(); - var testDTO = new TestDTO { StringVal = "Hello", IntVal = 4 }; + var byteArray = new byte[] { 0x2, 0x4, 0x7, 0x10, 0x15 }; + var testDTO = new TestDTO { StringVal = "Hello", IntVal = 4, ByteArrayVal = byteArray }; var task = jsRuntime.InvokeAsync("unimportant"); - var argsJson = JsonSerializer.Serialize(new object[] { jsRuntime.LastInvocationAsyncHandle, true, testDTO }, jsRuntime.JsonSerializerOptions); + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { jsRuntime.LastInvocationAsyncHandle, true, testDTO }); // Act - DotNetDispatcher.EndInvokeJS(jsRuntime, argsJson); + DotNetDispatcher.EndInvokeJS(jsRuntime, argsJson, byteArrays); // Assert Assert.True(task.IsCompletedSuccessfully); @@ -289,10 +338,10 @@ public async Task EndInvoke_WithErrorString() var jsRuntime = new TestJSRuntime(); var expected = "Some error"; var task = jsRuntime.InvokeAsync("unimportant"); - var argsJson = JsonSerializer.Serialize(new object[] { jsRuntime.LastInvocationAsyncHandle, false, expected }, jsRuntime.JsonSerializerOptions); + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { jsRuntime.LastInvocationAsyncHandle, false, expected }); // Act - DotNetDispatcher.EndInvokeJS(jsRuntime, argsJson); + DotNetDispatcher.EndInvokeJS(jsRuntime, argsJson, byteArrays); // Assert var ex = await Assert.ThrowsAsync(async () => await task); @@ -305,10 +354,10 @@ public async Task EndInvoke_WithNullError() // Arrange var jsRuntime = new TestJSRuntime(); var task = jsRuntime.InvokeAsync("unimportant"); - var argsJson = JsonSerializer.Serialize(new object[] { jsRuntime.LastInvocationAsyncHandle, false, null }, jsRuntime.JsonSerializerOptions); + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { jsRuntime.LastInvocationAsyncHandle, false, null }); // Act - DotNetDispatcher.EndInvokeJS(jsRuntime, argsJson); + DotNetDispatcher.EndInvokeJS(jsRuntime, argsJson, byteArrays); // Assert var ex = await Assert.ThrowsAsync(async () => await task); @@ -328,13 +377,14 @@ public void CanInvokeInstanceMethodWithParams() var argsJson = "[\"myvalue\",{\"__dotNetObject\":2}]"; // Act - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceMethod", 1, default), argsJson); + var (resultJson, byteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceMethod", 1, default), argsJson, byteArrays: null); // Assert Assert.Equal("[\"You passed myvalue\",{\"__dotNetObject\":3}]", resultJson); var resultDto = ((DotNetObjectReference)jsRuntime.GetObjectReference(3)).Value; Assert.Equal(1235, resultDto.IntVal); Assert.Equal("MY STRING", resultDto.StringVal); + Assert.Empty(byteArrays); } [Fact] @@ -347,10 +397,11 @@ public void CanInvokeNonGenericInstanceMethodOnGenericType() var argsJson = "[\"hello world\"]"; // Act - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, nameof(GenericType.EchoStringParameter), 1, default), argsJson); + var (resultJson, byteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, nameof(GenericType.EchoStringParameter), 1, default), argsJson, byteArrays: null); // Assert Assert.Equal("\"hello world\"", resultJson); + Assert.Empty(byteArrays); } [Fact] @@ -363,10 +414,11 @@ public void CanInvokeMethodsThatAcceptGenericParametersOnGenericTypes() var argsJson = "[\"hello world\"]"; // Act - var resultJson = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, nameof(GenericType.EchoParameter), 1, default), argsJson); + var (resultJson, byteArrays) = DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, nameof(GenericType.EchoParameter), 1, default), argsJson, byteArrays: null); // Assert Assert.Equal("\"hello world\"", resultJson); + Assert.Empty(byteArrays); } [Fact] @@ -376,7 +428,7 @@ public void CannotInvokeStaticOpenGenericMethods() var jsRuntime = new TestJSRuntime(); // Act - var ex = Assert.Throws(() => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, methodIdentifier, 0, default), "[7]")); + var ex = Assert.Throws(() => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, methodIdentifier, 0, default), "[7]", byteArrays: null)); Assert.Contains($"The assembly '{thisAssemblyName}' does not contain a public invokable method with [{nameof(JSInvokableAttribute)}(\"{methodIdentifier}\")].", ex.Message); } @@ -391,7 +443,7 @@ public void CannotInvokeInstanceOpenGenericMethods() var argsJson = "[\"hello world\"]"; // Act - var ex = Assert.Throws(() => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, methodIdentifier, 1, default), argsJson)); + var ex = Assert.Throws(() => DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, methodIdentifier, 1, default), argsJson, byteArrays: null)); Assert.Contains($"The type 'GenericType`1' does not contain a public invokable method with [{nameof(JSInvokableAttribute)}(\"{methodIdentifier}\")].", ex.Message); } @@ -406,7 +458,7 @@ public void CannotInvokeMethodsWithGenericParameters_IfTypesDoNotMatch() // Act & Assert Assert.Throws(() => - DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, nameof(GenericType.EchoParameter), 1, default), argsJson)); + DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(null, nameof(GenericType.EchoParameter), 1, default), argsJson, byteArrays: null)); } [Fact] @@ -414,16 +466,16 @@ public void CannotInvokeWithFewerNumberOfParameters() { // Arrange var jsRuntime = new TestJSRuntime(); - var argsJson = JsonSerializer.Serialize(new object[] + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { new TestDTO { StringVal = "Another string", IntVal = 456 }, - new[] { 100, 200 }, - }, jsRuntime.JsonSerializerOptions); + new[] { 100, 200 } + }); // Act/Assert var ex = Assert.Throws(() => { - DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, default), argsJson); + DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, default), argsJson, byteArrays); }); Assert.Equal("The call to 'InvocableStaticWithParams' expects '3' parameters, but received '2'.", ex.Message); @@ -435,18 +487,18 @@ public void CannotInvokeWithMoreParameters() // Arrange var jsRuntime = new TestJSRuntime(); var objectRef = DotNetObjectReference.Create(new TestDTO { IntVal = 4 }); - var argsJson = JsonSerializer.Serialize(new object[] + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { new TestDTO { StringVal = "Another string", IntVal = 456 }, new[] { 100, 200 }, objectRef, 7, - }, jsRuntime.JsonSerializerOptions); + }); // Act/Assert var ex = Assert.Throws(() => { - DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, default), argsJson); + DotNetDispatcher.Invoke(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, default), argsJson, byteArrays); }); Assert.Equal("Unexpected JSON token Number. Ensure that the call to `InvocableStaticWithParams' is supplied with exactly '3' parameters.", ex.Message); @@ -458,22 +510,23 @@ public async Task CanInvokeAsyncMethod() // Arrange: Track some instance plus another object we'll pass as a param var jsRuntime = new TestJSRuntime(); var targetInstance = new SomePublicType(); - var arg2 = new TestDTO { IntVal = 1234, StringVal = "My string" }; + var byteArray = new byte[] { 0x2, 0x4, 0x7, 0x10, 0x15 }; + var arg2 = new TestDTO { IntVal = 1234, StringVal = "My string", ByteArrayVal = byteArray }; var arg1Ref = DotNetObjectReference.Create(targetInstance); var arg2Ref = DotNetObjectReference.Create(arg2); jsRuntime.Invoke("unimportant", arg1Ref, arg2Ref); // Arrange: all args - var argsJson = JsonSerializer.Serialize(new object[] + var (argsJson, byteArrays) = jsRuntime.SerializeArgs(new object[] { new TestDTO { IntVal = 1000, StringVal = "String via JSON" }, arg2Ref, - }, jsRuntime.JsonSerializerOptions); + }); // Act var callId = "123"; var resultTask = jsRuntime.NextInvocationTask; - DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null, "InvokableAsyncMethod", 1, callId), argsJson); + DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null, "InvokableAsyncMethod", 1, callId), argsJson, byteArrays); await resultTask; // Assert: Correct completion information @@ -500,7 +553,7 @@ public async Task CanInvokeSyncThrowingMethod() // Act var callId = "123"; var resultTask = jsRuntime.NextInvocationTask; - DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, nameof(ThrowingClass.ThrowingMethod), default, callId), default); + DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, nameof(ThrowingClass.ThrowingMethod), default, callId), default, byteArrays: null); await resultTask; // This won't throw, it sets properties on the jsRuntime. @@ -522,7 +575,7 @@ public async Task CanInvokeAsyncThrowingMethod() // Act var callId = "123"; var resultTask = jsRuntime.NextInvocationTask; - DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, nameof(ThrowingClass.AsyncThrowingMethod), default, callId), default); + DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, nameof(ThrowingClass.AsyncThrowingMethod), default, callId), default, byteArrays: null); await resultTask; // This won't throw, it sets properties on the jsRuntime. @@ -542,7 +595,7 @@ public async Task BeginInvoke_ThrowsWithInvalidArgsJson_WithCallId() var jsRuntime = new TestJSRuntime(); var callId = "123"; var resultTask = jsRuntime.NextInvocationTask; - DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, callId), "not json"); + DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(thisAssemblyName, "InvocableStaticWithParams", default, callId), "not json", byteArrays: null); await resultTask; // This won't throw, it sets properties on the jsRuntime. @@ -560,7 +613,7 @@ public void BeginInvoke_ThrowsWithInvalid_DotNetObjectRef() var jsRuntime = new TestJSRuntime(); var callId = "123"; var resultTask = jsRuntime.NextInvocationTask; - DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, callId), null); + DotNetDispatcher.BeginInvokeDotNet(jsRuntime, new DotNetInvocationInfo(null, "InvokableInstanceVoid", 1, callId), null, byteArrays: null); // Assert Assert.Equal(callId, jsRuntime.LastCompletionCallId); @@ -574,7 +627,7 @@ public void BeginInvoke_ThrowsWithInvalid_DotNetObjectRef() [InlineData("")] public void ParseArguments_ThrowsIfJsonIsInvalid(string arguments) { - Assert.ThrowsAny(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, new[] { typeof(string) })); + Assert.ThrowsAny(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, byteArrays: null, new[] { typeof(string) })); } [Theory] @@ -583,7 +636,7 @@ public void ParseArguments_ThrowsIfJsonIsInvalid(string arguments) public void ParseArguments_ThrowsIfTheArgsJsonIsNotArray(string arguments) { // Act & Assert - Assert.ThrowsAny(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, new[] { typeof(string) })); + Assert.ThrowsAny(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, byteArrays: null, new[] { typeof(string) })); } [Theory] @@ -592,7 +645,7 @@ public void ParseArguments_ThrowsIfTheArgsJsonIsNotArray(string arguments) public void ParseArguments_ThrowsIfTheArgsJsonIsInvalidArray(string arguments) { // Act & Assert - Assert.ThrowsAny(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, new[] { typeof(string) })); + Assert.ThrowsAny(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, byteArrays: null, new[] { typeof(string) })); } [Fact] @@ -602,7 +655,7 @@ public void ParseArguments_Works() var arguments = "[\"Hello\", 2]"; // Act - var result = DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, new[] { typeof(string), typeof(int), }); + var result = DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, byteArrays: null, new[] { typeof(string), typeof(int), }); // Assert Assert.Equal(new object[] { "Hello", 2 }, result); @@ -615,7 +668,7 @@ public void ParseArguments_SingleArgument() var arguments = "[{\"IntVal\": 7}]"; // Act - var result = DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, new[] { typeof(TestDTO), }); + var result = DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, byteArrays: null, new[] { typeof(TestDTO), }); // Assert var value = Assert.IsType(Assert.Single(result)); @@ -630,7 +683,7 @@ public void ParseArguments_NullArgument() var arguments = "[4, null]"; // Act - var result = DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, new[] { typeof(int), typeof(TestDTO), }); + var result = DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, byteArrays: null, new[] { typeof(int), typeof(TestDTO), }); // Assert Assert.Collection( @@ -639,6 +692,20 @@ public void ParseArguments_NullArgument() v => Assert.Null(v)); } + [Fact] + public void ParseArguments_SingleByteArrayArgument() + { + // Arrange + var arguments = "[{\"__byte[]\": 0}]"; + + // Act + var result = DotNetDispatcher.ParseArguments(new TestJSRuntime(), "SomeMethod", arguments, byteArrays: new[] { new byte[] { 0x1, 0x2 } }, new[] { typeof(byte[]), }); + + // Assert + var value = Assert.IsType(Assert.Single(result)); + Assert.Equal(new byte[] { 0x1, 0x2 }, value); + } + [Fact] public void ParseArguments_Throws_WithIncorrectDotNetObjectRefUsage() { @@ -647,34 +714,48 @@ public void ParseArguments_Throws_WithIncorrectDotNetObjectRefUsage() var arguments = "[4, {\"__dotNetObject\": 7}]"; // Act - var ex = Assert.Throws(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), method, arguments, new[] { typeof(int), typeof(TestDTO), })); + var ex = Assert.Throws(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), method, arguments, byteArrays: null, new[] { typeof(int), typeof(TestDTO), })); // Assert Assert.Equal($"In call to '{method}', parameter of type '{nameof(TestDTO)}' at index 2 must be declared as type 'DotNetObjectRef' to receive the incoming value.", ex.Message); } + [Fact] + public void ParseArguments_Throws_WithByteArrayInArgsButNoByteArraysProvided() + { + // Arrange + var method = "SomeMethod"; + var arguments = "[4, {\"__byte[]\": 7}]"; + + // Act + var ex = Assert.Throws(() => DotNetDispatcher.ParseArguments(new TestJSRuntime(), method, arguments, byteArrays: null, new[] { typeof(int), typeof(byte[]), })); + + // Assert + Assert.Equal("ByteArraysToDeserialize not set.", ex.Message); + } + [Fact] public void EndInvokeJS_ThrowsIfJsonIsEmptyString() { - Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "")); + Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "", byteArrays: null)); } [Fact] public void EndInvokeJS_ThrowsIfJsonIsNotArray() { - Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "{\"key\": \"value\"}")); + Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "{\"key\": \"value\"}", byteArrays: null)); } [Fact] public void EndInvokeJS_ThrowsIfJsonArrayIsInComplete() { - Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "[7, false")); + Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "[7, false", byteArrays: null)); } [Fact] public void EndInvokeJS_ThrowsIfJsonArrayHasMoreThan3Arguments() { - Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "[7, false, \"Hello\", 5]")); + Assert.ThrowsAny(() => DotNetDispatcher.EndInvokeJS(new TestJSRuntime(), "[7, false, \"Hello\", 5]", byteArrays: null)); } [Fact] @@ -683,7 +764,7 @@ public void EndInvokeJS_Works() var jsRuntime = new TestJSRuntime(); var task = jsRuntime.InvokeAsync("somemethod"); - DotNetDispatcher.EndInvokeJS(jsRuntime, $"[{jsRuntime.LastInvocationAsyncHandle}, true, {{\"intVal\": 7}}]"); + DotNetDispatcher.EndInvokeJS(jsRuntime, $"[{jsRuntime.LastInvocationAsyncHandle}, true, {{\"intVal\": 7}}]", byteArrays: null); Assert.True(task.IsCompletedSuccessfully); Assert.Equal(7, task.Result.IntVal); @@ -695,19 +776,31 @@ public void EndInvokeJS_WithArrayValue() var jsRuntime = new TestJSRuntime(); var task = jsRuntime.InvokeAsync("somemethod"); - DotNetDispatcher.EndInvokeJS(jsRuntime, $"[{jsRuntime.LastInvocationAsyncHandle}, true, [1, 2, 3]]"); + DotNetDispatcher.EndInvokeJS(jsRuntime, $"[{jsRuntime.LastInvocationAsyncHandle}, true, [1, 2, 3]]", byteArrays: null); Assert.True(task.IsCompletedSuccessfully); Assert.Equal(new[] { 1, 2, 3 }, task.Result); } + [Fact] + public void EndInvokeJS_WithByteArrayValue() + { + var jsRuntime = new TestJSRuntime(); + var task = jsRuntime.InvokeAsync("somemethod"); + + DotNetDispatcher.EndInvokeJS(jsRuntime, $"[{jsRuntime.LastInvocationAsyncHandle}, true, {{ \"__byte[]\": 0 }}]", byteArrays: new[] { new byte[] { 0x1, 0x2 } }); + + Assert.True(task.IsCompletedSuccessfully); + Assert.Equal(new byte[] { 0x1, 0x2 }, task.Result); + } + [Fact] public void EndInvokeJS_WithNullValue() { var jsRuntime = new TestJSRuntime(); var task = jsRuntime.InvokeAsync("somemethod"); - DotNetDispatcher.EndInvokeJS(jsRuntime, $"[{jsRuntime.LastInvocationAsyncHandle}, true, null]"); + DotNetDispatcher.EndInvokeJS(jsRuntime, $"[{jsRuntime.LastInvocationAsyncHandle}, true, null]", byteArrays: null); Assert.True(task.IsCompletedSuccessfully); Assert.Null(task.Result); @@ -754,6 +847,19 @@ public static object[] MyInvocableWithParams(TestDTO dtoViaJson, int[] increment }) }; + [JSInvokable("InvocableWithByteArrayParams")] + public static object[] MyInvocableWithByteArrayParams(TestDTO dtoViaJson, int[] incrementAmounts, byte[] byteArray) + => new object[] + { + new TestDTO // Return via JSON marshalling + { + StringVal = dtoViaJson.StringVal.ToUpperInvariant(), + IntVal = dtoViaJson.IntVal + incrementAmounts.Sum(), + ByteArrayVal = dtoViaJson.ByteArrayVal.Reverse().ToArray() + }, + byteArray.Reverse().ToArray() + }; + [JSInvokable(nameof(IncorrectDotNetObjectRefUsage))] public static object[] IncorrectDotNetObjectRefUsage(TestDTO dtoViaJson, int[] incrementAmounts, TestDTO dtoByRef) => throw new InvalidOperationException("Shouldn't be called"); @@ -831,6 +937,7 @@ public class TestDTO { public string StringVal { get; set; } public int IntVal { get; set; } + public byte[] ByteArrayVal { get; set; } } public class ThrowingClass @@ -872,7 +979,7 @@ public class TestJSRuntime : JSInProcessRuntime public string LastCompletionCallId { get; private set; } public DotNetInvocationResult LastCompletionResult { get; private set; } - protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson, JSCallResultType resultType, long targetInstanceId) + protected override void BeginInvokeJS(long asyncHandle, string identifier, string argsJson, byte[][] byteArrays, JSCallResultType resultType, long targetInstanceId) { LastInvocationAsyncHandle = asyncHandle; LastInvocationIdentifier = identifier; diff --git a/src/JSInterop/Microsoft.JSInterop/test/JSInProcessRuntimeTest.cs b/src/JSInterop/Microsoft.JSInterop/test/JSInProcessRuntimeTest.cs index 475752aa6fd3..356c144da800 100644 --- a/src/JSInterop/Microsoft.JSInterop/test/JSInProcessRuntimeTest.cs +++ b/src/JSInterop/Microsoft.JSInterop/test/JSInProcessRuntimeTest.cs @@ -99,7 +99,7 @@ class TestJSInProcessRuntime : JSInProcessRuntime public string? NextResultJson { get; set; } - protected override string? InvokeJS(string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId) + protected override string? InvokeJS(string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId) { InvokeCalls.Add(new InvokeArgs { Identifier = identifier, ArgsJson = argsJson }); return NextResultJson; @@ -111,7 +111,7 @@ public class InvokeArgs public string? ArgsJson { get; set; } } - protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId) + protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId) => throw new NotImplementedException("This test only covers sync calls"); protected internal override void EndInvokeDotNet(DotNetInvocationInfo invocationInfo, in DotNetInvocationResult invocationResult) diff --git a/src/JSInterop/Microsoft.JSInterop/test/JSObjectReferenceTest.cs b/src/JSInterop/Microsoft.JSInterop/test/JSObjectReferenceTest.cs index b142fb0caf5b..33e9548eb381 100644 --- a/src/JSInterop/Microsoft.JSInterop/test/JSObjectReferenceTest.cs +++ b/src/JSInterop/Microsoft.JSInterop/test/JSObjectReferenceTest.cs @@ -73,7 +73,7 @@ class TestJSRuntime : JSRuntime { public int BeginInvokeJSInvocationCount { get; private set; } - protected override void BeginInvokeJS(long taskId, string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId) + protected override void BeginInvokeJS(long taskId, string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId) { BeginInvokeJSInvocationCount++; } @@ -87,11 +87,11 @@ class TestJSInProcessRuntime : JSInProcessRuntime { public int InvokeJSInvocationCount { get; private set; } - protected override void BeginInvokeJS(long taskId, string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId) + protected override void BeginInvokeJS(long taskId, string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId) { } - protected override string? InvokeJS(string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId) + protected override string? InvokeJS(string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId) { InvokeJSInvocationCount++; diff --git a/src/JSInterop/Microsoft.JSInterop/test/JSRuntimeTest.cs b/src/JSInterop/Microsoft.JSInterop/test/JSRuntimeTest.cs index 353d7dce1ab9..3ec6e2646c3c 100644 --- a/src/JSInterop/Microsoft.JSInterop/test/JSRuntimeTest.cs +++ b/src/JSInterop/Microsoft.JSInterop/test/JSRuntimeTest.cs @@ -66,7 +66,7 @@ public void InvokeAsync_CompletesSuccessfullyBeforeTimeout() // Act var task = runtime.InvokeAsync("test identifier 1", "arg1", 123, true); - runtime.EndInvokeJS(2, succeeded: true, ref reader); + runtime.EndInvokeJS(2, succeeded: true, ref reader, byteArrays: null); Assert.True(task.IsCompletedSuccessfully); } @@ -122,8 +122,9 @@ public void CanCompleteAsyncCallsAsSuccess() // Act/Assert: Task can be completed runtime.EndInvokeJS( runtime.BeginInvokeCalls[1].AsyncHandle, - /* succeeded: */ true, - ref reader); + succeeded: true, + ref reader, + byteArrays: null); Assert.False(unrelatedTask.IsCompleted); Assert.True(task.IsCompleted); Assert.Equal("my result", task.Result); @@ -136,19 +137,21 @@ public void CanCompleteAsyncCallsWithComplexType() var runtime = new TestJSRuntime(); var task = runtime.InvokeAsync("test identifier", Array.Empty()); - var bytes = Encoding.UTF8.GetBytes("{\"id\":10, \"name\": \"Test\"}"); + var bytes = Encoding.UTF8.GetBytes("{\"id\":10, \"name\": \"Test\", \"bytes\": { \"__byte[]\": 0 }}"); var reader = new Utf8JsonReader(bytes); // Act/Assert: Task can be completed runtime.EndInvokeJS( runtime.BeginInvokeCalls[0].AsyncHandle, - /* succeeded: */ true, - ref reader); + succeeded: true, + ref reader, + byteArrays: new[] { new byte[] { 0x1, 0x2 } }); Assert.True(task.IsCompleted); var poco = task.Result; Debug.Assert(poco != null); Assert.Equal(10, poco.Id); Assert.Equal("Test", poco.Name); + Assert.Equal(new byte[] { 0x1, 0x2 }, poco.Bytes); } [Fact] @@ -165,8 +168,9 @@ public void CanCompleteAsyncCallsWithComplexTypeUsingPropertyCasing() // Act/Assert: Task can be completed runtime.EndInvokeJS( runtime.BeginInvokeCalls[0].AsyncHandle, - /* succeeded: */ true, - ref reader); + succeeded: true, + ref reader, + byteArrays: null); Assert.True(task.IsCompleted); var poco = task.Result; Debug.Assert(poco != null); @@ -192,8 +196,9 @@ public void CanCompleteAsyncCallsAsFailure() // Act/Assert: Task can be failed runtime.EndInvokeJS( runtime.BeginInvokeCalls[1].AsyncHandle, - /* succeeded: */ false, - ref reader); + succeeded: false, + ref reader, + byteArrays: null); Assert.False(unrelatedTask.IsCompleted); Assert.True(task.IsCompleted); @@ -219,8 +224,9 @@ public Task CanCompleteAsyncCallsWithErrorsDuringDeserialization() // Act/Assert: Task can be failed runtime.EndInvokeJS( runtime.BeginInvokeCalls[1].AsyncHandle, - /* succeeded: */ true, - ref reader); + succeeded: true, + ref reader, + byteArrays: null); Assert.False(unrelatedTask.IsCompleted); return AssertTask(); @@ -244,8 +250,8 @@ public Task CompletingSameAsyncCallMoreThanOnce_IgnoresSecondResultAsync() var firstReader = new Utf8JsonReader(Encoding.UTF8.GetBytes("\"Some data\"")); var secondReader = new Utf8JsonReader(Encoding.UTF8.GetBytes("\"Exception\"")); - runtime.EndInvokeJS(asyncHandle, true, ref firstReader); - runtime.EndInvokeJS(asyncHandle, false, ref secondReader); + runtime.EndInvokeJS(asyncHandle, true, ref firstReader, byteArrays: null); + runtime.EndInvokeJS(asyncHandle, false, ref secondReader, byteArrays: null); return AssertTask(); @@ -332,6 +338,8 @@ private class TestPoco public int Id { get; set; } public string? Name { get; set; } + + public byte[]? Bytes { get; set; } } class TestJSRuntime : JSRuntime @@ -373,7 +381,7 @@ protected internal override void EndInvokeDotNet(DotNetInvocationInfo invocation }); } - protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId) + protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId) { BeginInvokeCalls.Add(new BeginInvokeAsyncArgs { diff --git a/src/JSInterop/Microsoft.JSInterop/test/TestJSRuntime.cs b/src/JSInterop/Microsoft.JSInterop/test/TestJSRuntime.cs index b0e694c6f920..94c2ac77b9a0 100644 --- a/src/JSInterop/Microsoft.JSInterop/test/TestJSRuntime.cs +++ b/src/JSInterop/Microsoft.JSInterop/test/TestJSRuntime.cs @@ -8,7 +8,7 @@ namespace Microsoft.JSInterop { internal class TestJSRuntime : JSRuntime { - protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson, JSCallResultType resultType, long targetInstanceId) + protected override void BeginInvokeJS(long asyncHandle, string identifier, string? argsJson, byte[][]? byteArrays, JSCallResultType resultType, long targetInstanceId) { throw new NotImplementedException(); }