diff --git a/src/Components/Blazor/Build/src/ReferenceFromSource.props b/src/Components/Blazor/Build/src/ReferenceFromSource.props index 209519e93213..c98b209ff8ca 100644 --- a/src/Components/Blazor/Build/src/ReferenceFromSource.props +++ b/src/Components/Blazor/Build/src/ReferenceFromSource.props @@ -11,7 +11,7 @@ true - $(RepositoryRoot)src\Components\Browser.JS\dist\$(Configuration)\blazor.*.js + $(RepositoryRoot)src\Components\Browser.JS\dist\$(Configuration)\blazor.*.js.* diff --git a/src/Components/Browser.JS/dist/Debug/blazor.server.js b/src/Components/Browser.JS/dist/Debug/blazor.server.js index 51fade0f26f1..b8f0eb6fb45e 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.server.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.server.js @@ -13263,7 +13263,13 @@ var BrowserRenderer = /** @class */ (function () { clearBetween(rootElementToClear, rootElementToClearEnd); } } + var ownerDocument = LogicalElements_1.getClosestDomElement(element).ownerDocument; + var activeElementBefore = ownerDocument && ownerDocument.activeElement; this.applyEdits(batch, element, 0, edits, referenceFrames); + // Try to restore focus in case it was lost due to an element move + if ((activeElementBefore instanceof HTMLElement) && ownerDocument && ownerDocument.activeElement !== activeElementBefore) { + activeElementBefore.focus(); + } }; BrowserRenderer.prototype.disposeComponent = function (componentId) { delete this.childComponentLocations[componentId]; @@ -13277,6 +13283,7 @@ var BrowserRenderer = /** @class */ (function () { BrowserRenderer.prototype.applyEdits = function (batch, parent, childIndex, edits, referenceFrames) { var currentDepth = 0; var childIndexAtCurrentDepth = childIndex; + var permutationList; var arraySegmentReader = batch.arraySegmentReader; var editReader = batch.editReader; var frameReader = batch.frameReader; @@ -13365,6 +13372,19 @@ var BrowserRenderer = /** @class */ (function () { childIndexAtCurrentDepth = currentDepth === 0 ? childIndex : 0; // The childIndex is only ever nonzero at zero depth break; } + case RenderBatch_1.EditType.permutationListEntry: { + permutationList = permutationList || []; + permutationList.push({ + fromSiblingIndex: childIndexAtCurrentDepth + editReader.siblingIndex(edit), + toSiblingIndex: childIndexAtCurrentDepth + editReader.moveToSiblingIndex(edit), + }); + break; + } + case RenderBatch_1.EditType.permutationListEnd: { + LogicalElements_1.permuteLogicalChildren(parent, permutationList); + permutationList = undefined; + break; + } default: { var unknownType = editType; // Compile-time verification that the switch was exhaustive throw new Error("Unknown edit type: " + unknownType); @@ -14169,11 +14189,54 @@ function getLogicalChildrenArray(element) { return element[logicalChildrenPropname]; } exports.getLogicalChildrenArray = getLogicalChildrenArray; -function getLogicalNextSibling(element) { - var siblings = getLogicalChildrenArray(getLogicalParent(element)); - var siblingIndex = Array.prototype.indexOf.call(siblings, element); - return siblings[siblingIndex + 1] || null; +function permuteLogicalChildren(parent, permutationList) { + // The permutationList must represent a valid permutation, i.e., the list of 'from' indices + // is distinct, and the list of 'to' indices is a permutation of it. The algorithm here + // relies on that assumption. + // Each of the phases here has to happen separately, because each one is designed not to + // interfere with the indices or DOM entries used by subsequent phases. + // Phase 1: track which nodes we will move + var siblings = getLogicalChildrenArray(parent); + permutationList.forEach(function (listEntry) { + listEntry.moveRangeStart = siblings[listEntry.fromSiblingIndex]; + listEntry.moveRangeEnd = findLastDomNodeInRange(listEntry.moveRangeStart); + }); + // Phase 2: insert markers + permutationList.forEach(function (listEntry) { + var marker = listEntry.moveToBeforeMarker = document.createComment('marker'); + var insertBeforeNode = siblings[listEntry.toSiblingIndex + 1]; + if (insertBeforeNode) { + insertBeforeNode.parentNode.insertBefore(marker, insertBeforeNode); + } + else { + appendDomNode(marker, parent); + } + }); + // Phase 3: move descendants & remove markers + permutationList.forEach(function (listEntry) { + var insertBefore = listEntry.moveToBeforeMarker; + var parentDomNode = insertBefore.parentNode; + var elementToMove = listEntry.moveRangeStart; + var moveEndNode = listEntry.moveRangeEnd; + var nextToMove = elementToMove; + while (nextToMove) { + var nextNext = nextToMove.nextSibling; + parentDomNode.insertBefore(nextToMove, insertBefore); + if (nextToMove === moveEndNode) { + break; + } + else { + nextToMove = nextNext; + } + } + parentDomNode.removeChild(insertBefore); + }); + // Phase 4: update siblings index + permutationList.forEach(function (listEntry) { + siblings[listEntry.toSiblingIndex] = listEntry.moveRangeStart; + }); } +exports.permuteLogicalChildren = permuteLogicalChildren; function getClosestDomElement(logicalElement) { if (logicalElement instanceof Element) { return logicalElement; @@ -14185,6 +14248,12 @@ function getClosestDomElement(logicalElement) { throw new Error('Not a valid logical element'); } } +exports.getClosestDomElement = getClosestDomElement; +function getLogicalNextSibling(element) { + var siblings = getLogicalChildrenArray(getLogicalParent(element)); + var siblingIndex = Array.prototype.indexOf.call(siblings, element); + return siblings[siblingIndex + 1] || null; +} function appendDomNode(child, parent) { // This function only puts 'child' into the DOM in the right place relative to 'parent' // It does not update the logical children array of anything @@ -14208,6 +14277,26 @@ function appendDomNode(child, parent) { throw new Error("Cannot append node because the parent is not a valid logical element. Parent: " + parent); } } +// Returns the final node (in depth-first evaluation order) that is a descendant of the logical element. +// As such, the entire subtree is between 'element' and 'findLastDomNodeInRange(element)' inclusive. +function findLastDomNodeInRange(element) { + if (element instanceof Element) { + return element; + } + var nextSibling = getLogicalNextSibling(element); + if (nextSibling) { + // Simple case: not the last logical sibling, so take the node before the next sibling + return nextSibling.previousSibling; + } + else { + // Harder case: there's no logical next-sibling, so recurse upwards until we find + // a logical ancestor that does have one, or a physical element + var logicalParent = getLogicalParent(element); + return logicalParent instanceof Element + ? logicalParent.lastChild + : findLastDomNodeInRange(logicalParent); + } +} function createSymbolOrFallback(fallback) { return typeof Symbol === 'function' ? Symbol() : fallback; } @@ -14303,6 +14392,9 @@ var OutOfProcessRenderTreeEditReader = /** @class */ (function () { OutOfProcessRenderTreeEditReader.prototype.newTreeIndex = function (edit) { return readInt32LE(this.batchDataUint8, edit + 8); // 3rd int }; + OutOfProcessRenderTreeEditReader.prototype.moveToSiblingIndex = function (edit) { + return readInt32LE(this.batchDataUint8, edit + 8); // 3rd int + }; OutOfProcessRenderTreeEditReader.prototype.removedAttributeName = function (edit) { var stringIndex = readInt32LE(this.batchDataUint8, edit + 12); // 4th int return this.stringReader.readString(stringIndex); @@ -14458,6 +14550,8 @@ var EditType; EditType[EditType["stepIn"] = 6] = "stepIn"; EditType[EditType["stepOut"] = 7] = "stepOut"; EditType[EditType["updateMarkup"] = 8] = "updateMarkup"; + EditType[EditType["permutationListEntry"] = 9] = "permutationListEntry"; + EditType[EditType["permutationListEnd"] = 10] = "permutationListEnd"; })(EditType = exports.EditType || (exports.EditType = {})); var FrameType; (function (FrameType) { diff --git a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js index bae138186598..7df07ee7b40d 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js @@ -1023,7 +1023,13 @@ var BrowserRenderer = /** @class */ (function () { clearBetween(rootElementToClear, rootElementToClearEnd); } } + var ownerDocument = LogicalElements_1.getClosestDomElement(element).ownerDocument; + var activeElementBefore = ownerDocument && ownerDocument.activeElement; this.applyEdits(batch, element, 0, edits, referenceFrames); + // Try to restore focus in case it was lost due to an element move + if ((activeElementBefore instanceof HTMLElement) && ownerDocument && ownerDocument.activeElement !== activeElementBefore) { + activeElementBefore.focus(); + } }; BrowserRenderer.prototype.disposeComponent = function (componentId) { delete this.childComponentLocations[componentId]; @@ -1037,6 +1043,7 @@ var BrowserRenderer = /** @class */ (function () { BrowserRenderer.prototype.applyEdits = function (batch, parent, childIndex, edits, referenceFrames) { var currentDepth = 0; var childIndexAtCurrentDepth = childIndex; + var permutationList; var arraySegmentReader = batch.arraySegmentReader; var editReader = batch.editReader; var frameReader = batch.frameReader; @@ -1125,6 +1132,19 @@ var BrowserRenderer = /** @class */ (function () { childIndexAtCurrentDepth = currentDepth === 0 ? childIndex : 0; // The childIndex is only ever nonzero at zero depth break; } + case RenderBatch_1.EditType.permutationListEntry: { + permutationList = permutationList || []; + permutationList.push({ + fromSiblingIndex: childIndexAtCurrentDepth + editReader.siblingIndex(edit), + toSiblingIndex: childIndexAtCurrentDepth + editReader.moveToSiblingIndex(edit), + }); + break; + } + case RenderBatch_1.EditType.permutationListEnd: { + LogicalElements_1.permuteLogicalChildren(parent, permutationList); + permutationList = undefined; + break; + } default: { var unknownType = editType; // Compile-time verification that the switch was exhaustive throw new Error("Unknown edit type: " + unknownType); @@ -1929,11 +1949,54 @@ function getLogicalChildrenArray(element) { return element[logicalChildrenPropname]; } exports.getLogicalChildrenArray = getLogicalChildrenArray; -function getLogicalNextSibling(element) { - var siblings = getLogicalChildrenArray(getLogicalParent(element)); - var siblingIndex = Array.prototype.indexOf.call(siblings, element); - return siblings[siblingIndex + 1] || null; +function permuteLogicalChildren(parent, permutationList) { + // The permutationList must represent a valid permutation, i.e., the list of 'from' indices + // is distinct, and the list of 'to' indices is a permutation of it. The algorithm here + // relies on that assumption. + // Each of the phases here has to happen separately, because each one is designed not to + // interfere with the indices or DOM entries used by subsequent phases. + // Phase 1: track which nodes we will move + var siblings = getLogicalChildrenArray(parent); + permutationList.forEach(function (listEntry) { + listEntry.moveRangeStart = siblings[listEntry.fromSiblingIndex]; + listEntry.moveRangeEnd = findLastDomNodeInRange(listEntry.moveRangeStart); + }); + // Phase 2: insert markers + permutationList.forEach(function (listEntry) { + var marker = listEntry.moveToBeforeMarker = document.createComment('marker'); + var insertBeforeNode = siblings[listEntry.toSiblingIndex + 1]; + if (insertBeforeNode) { + insertBeforeNode.parentNode.insertBefore(marker, insertBeforeNode); + } + else { + appendDomNode(marker, parent); + } + }); + // Phase 3: move descendants & remove markers + permutationList.forEach(function (listEntry) { + var insertBefore = listEntry.moveToBeforeMarker; + var parentDomNode = insertBefore.parentNode; + var elementToMove = listEntry.moveRangeStart; + var moveEndNode = listEntry.moveRangeEnd; + var nextToMove = elementToMove; + while (nextToMove) { + var nextNext = nextToMove.nextSibling; + parentDomNode.insertBefore(nextToMove, insertBefore); + if (nextToMove === moveEndNode) { + break; + } + else { + nextToMove = nextNext; + } + } + parentDomNode.removeChild(insertBefore); + }); + // Phase 4: update siblings index + permutationList.forEach(function (listEntry) { + siblings[listEntry.toSiblingIndex] = listEntry.moveRangeStart; + }); } +exports.permuteLogicalChildren = permuteLogicalChildren; function getClosestDomElement(logicalElement) { if (logicalElement instanceof Element) { return logicalElement; @@ -1945,6 +2008,12 @@ function getClosestDomElement(logicalElement) { throw new Error('Not a valid logical element'); } } +exports.getClosestDomElement = getClosestDomElement; +function getLogicalNextSibling(element) { + var siblings = getLogicalChildrenArray(getLogicalParent(element)); + var siblingIndex = Array.prototype.indexOf.call(siblings, element); + return siblings[siblingIndex + 1] || null; +} function appendDomNode(child, parent) { // This function only puts 'child' into the DOM in the right place relative to 'parent' // It does not update the logical children array of anything @@ -1968,6 +2037,26 @@ function appendDomNode(child, parent) { throw new Error("Cannot append node because the parent is not a valid logical element. Parent: " + parent); } } +// Returns the final node (in depth-first evaluation order) that is a descendant of the logical element. +// As such, the entire subtree is between 'element' and 'findLastDomNodeInRange(element)' inclusive. +function findLastDomNodeInRange(element) { + if (element instanceof Element) { + return element; + } + var nextSibling = getLogicalNextSibling(element); + if (nextSibling) { + // Simple case: not the last logical sibling, so take the node before the next sibling + return nextSibling.previousSibling; + } + else { + // Harder case: there's no logical next-sibling, so recurse upwards until we find + // a logical ancestor that does have one, or a physical element + var logicalParent = getLogicalParent(element); + return logicalParent instanceof Element + ? logicalParent.lastChild + : findLastDomNodeInRange(logicalParent); + } +} function createSymbolOrFallback(fallback) { return typeof Symbol === 'function' ? Symbol() : fallback; } @@ -1996,6 +2085,8 @@ var EditType; EditType[EditType["stepIn"] = 6] = "stepIn"; EditType[EditType["stepOut"] = 7] = "stepOut"; EditType[EditType["updateMarkup"] = 8] = "updateMarkup"; + EditType[EditType["permutationListEntry"] = 9] = "permutationListEntry"; + EditType[EditType["permutationListEnd"] = 10] = "permutationListEnd"; })(EditType = exports.EditType || (exports.EditType = {})); var FrameType; (function (FrameType) { @@ -2089,15 +2180,16 @@ var diffReader = { }; // Keep in sync with memory layout in RenderTreeEdit.cs var editReader = { - structLength: 16, + structLength: 20, editType: function (edit) { return Environment_1.platform.readInt32Field(edit, 0); }, siblingIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 4); }, newTreeIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 8); }, - removedAttributeName: function (edit) { return Environment_1.platform.readStringField(edit, 12); }, + moveToSiblingIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 8); }, + removedAttributeName: function (edit) { return Environment_1.platform.readStringField(edit, 16); }, }; // Keep in sync with memory layout in RenderTreeFrame.cs var frameReader = { - structLength: 28, + structLength: 36, frameType: function (frame) { return Environment_1.platform.readInt32Field(frame, 4); }, subtreeLength: function (frame) { return Environment_1.platform.readInt32Field(frame, 8); }, elementReferenceCaptureId: function (frame) { return Environment_1.platform.readStringField(frame, 16); }, diff --git a/src/Components/Browser.JS/dist/Release/blazor.server.js b/src/Components/Browser.JS/dist/Release/blazor.server.js index a9f6e4c9755c..785cfa613a8d 100644 --- a/src/Components/Browser.JS/dist/Release/blazor.server.js +++ b/src/Components/Browser.JS/dist/Release/blazor.server.js @@ -1,15 +1,15 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=46)}([function(e,t,n){"use strict";var r;n.d(t,"a",function(){return r}),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"}(r||(r={}))},function(e,t,n){"use strict";n.d(t,"a",function(){return s}),n.d(t,"e",function(){return u}),n.d(t,"f",function(){return c}),n.d(t,"g",function(){return l}),n.d(t,"d",function(){return f}),n.d(t,"c",function(){return h}),n.d(t,"b",function(){return d});var r=n(0),o=n(3),i=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},a=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback().catch(function(e){})},e}(),d=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:console.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:console.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:console.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}()},function(e,t,n){"use strict";n.r(t);var r,o,i=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),a=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return i(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),u=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=200&&o.status<300?n(new l(o.status,o.statusText,o.response||o.responseText)):r(new a(o.statusText,o.status))},o.onerror=function(){t.logger.log(h.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new a(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(h.a.Warning,"Timeout from HTTP request."),r(new s)},o.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(f),g=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();if("undefined"==typeof XMLHttpRequest){var y=require;o=y("./NodeHttpClient")}var v,b=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof XMLHttpRequest)n.httpClient=new d(t);else{if(void 0===o)throw new Error("No HttpClient could be created.");n.httpClient=new o.NodeHttpClient(t)}return n}return g(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new u):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(f),m=n(41);!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"}(v||(v={}));var w,E=n(1),S=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},_=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=0){if((r!==C.WebSockets||this.options.WebSocket)&&(r!==C.ServerSentEvents||this.options.EventSource))return this.logger.log(h.a.Debug,"Selecting transport '"+C[r]+"'."),r;this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it is not supported in your environment.'")}else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it does not support the requested transfer format '"+I[n]+"'.");else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it was disabled by the client.")}return null},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.changeState=function(e,t){return this.connectionState===e&&(this.connectionState=t,!0)},e.prototype.stopConnection=function(e){this.transport=void 0,(e=this.stopError||e)?this.logger.log(h.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(h.a.Information,"Connection disconnected."),this.connectionState=2,this.onclose&&this.onclose(e)},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if("undefined"==typeof window||!window||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(h.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t)},e}();var Y=n(3),K=n(4),J="json",X=function(){function e(){this.name=J,this.version=1,this.transferFormat=I.Text}return e.prototype.parseMessages=function(e,t){if("string"!=typeof e)throw new Error("Invalid input for JSON hub protocol. Expected a string.");if(!e)return[];null===t&&(t=Y.a.instance);for(var n=[],r=0,o=K.a.parse(e);r0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=c},function(e,t,n){"use strict";var r=n(18),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(15);i.inherits=n(7);var a=n(33),s=n(37);i.inherits(f,a);for(var u=o(s.prototype),c=0;c0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback().catch(function(e){})},e}(),d=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:console.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:console.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:console.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}()},function(e,t,n){"use strict";n.r(t);var r,o,i=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),a=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return i(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),u=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=200&&o.status<300?n(new l(o.status,o.statusText,o.response||o.responseText)):r(new a(o.statusText,o.status))},o.onerror=function(){t.logger.log(h.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new a(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(h.a.Warning,"Timeout from HTTP request."),r(new s)},o.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(f),g=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();if("undefined"==typeof XMLHttpRequest){var y=require;o=y("./NodeHttpClient")}var v,m=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof XMLHttpRequest)n.httpClient=new d(t);else{if(void 0===o)throw new Error("No HttpClient could be created.");n.httpClient=new o.NodeHttpClient(t)}return n}return g(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new u):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(f),b=n(41);!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"}(v||(v={}));var w,E=n(1),S=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},_=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=0){if((r!==C.WebSockets||this.options.WebSocket)&&(r!==C.ServerSentEvents||this.options.EventSource))return this.logger.log(h.a.Debug,"Selecting transport '"+C[r]+"'."),r;this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it is not supported in your environment.'")}else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it does not support the requested transfer format '"+I[n]+"'.");else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it was disabled by the client.")}return null},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.changeState=function(e,t){return this.connectionState===e&&(this.connectionState=t,!0)},e.prototype.stopConnection=function(e){this.transport=void 0,(e=this.stopError||e)?this.logger.log(h.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(h.a.Information,"Connection disconnected."),this.connectionState=2,this.onclose&&this.onclose(e)},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if("undefined"==typeof window||!window||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(h.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t)},e}();var Y=n(3),K=n(4),J="json",X=function(){function e(){this.name=J,this.version=1,this.transferFormat=I.Text}return e.prototype.parseMessages=function(e,t){if("string"!=typeof e)throw new Error("Invalid input for JSON hub protocol. Expected a string.");if(!e)return[];null===t&&(t=Y.a.instance);for(var n=[],r=0,o=K.a.parse(e);r0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=u(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):h(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=l},function(e,t,n){"use strict";var r=n(18),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(15);i.inherits=n(7);var a=n(33),s=n(37);i.inherits(f,a);for(var u=o(s.prototype),c=0;c * @license MIT */ -var r=n(47),o=n(48),i=n(31);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function T(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return R(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return T(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},u.prototype.equals=function(e){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===u.compare(this,e)},u.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return m(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return _(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var C=4096;function I(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function A(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function B(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function D(e,t,n,r,i){return i||B(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||B(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||P(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||P(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||P(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||P(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||P(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||P(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||P(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||P(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||P(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||P(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return D(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return D(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(5))},function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function s(e,t){for(var n=[],r=2;r1)for(var n=1;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.length||e<0)){var t=this._offset(e);return this._bufs[t[0]][t[1]]}},a.prototype.slice=function(e,t){return"number"==typeof e&&e<0&&(e+=this.length),"number"==typeof t&&t<0&&(t+=this.length),this.copy(null,0,e,t)},a.prototype.copy=function(e,t,n,r){if(("number"!=typeof n||n<0)&&(n=0),("number"!=typeof r||r>this.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,u=this._offset(n),c=r-n,l=c,f=s&&t||0,h=u[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){if(e=e||0,t="number"!=typeof t?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return new a;var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;ethis.length?this.length:t;for(var r=this._offset(t),o=r[0],s=r[1];o=e.length){var c=u.indexOf(e,s);if(-1!==c)return this._reverseOffset([o,c]);s=u.length-e.length+1}else{var l=this._reverseOffset([o,s]);if(this._match(l,e))return l;s++}}s=0}return-1},a.prototype._match=function(e,t){if(this.length-e=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16),o=n(22),i=n(8);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:i.attachRootComponentToElement,http:o.internalFunctions,uriHelper:r.internalFunctions}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),u=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),b(r.showHidden)&&(r.showHidden=!1),b(r.depth)&&(r.depth=2),b(r.colors)&&(r.colors=!1),b(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=u),l(r,e,r.depth)}function u(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function c(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&_(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(b(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(_(n)){var u=n.name?": "+n.name:"";return e.stylize("[Function"+u+"]","special")}if(m(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var c,w="",T=!1,k=["{","}"];(p(n)&&(T=!0,k=["[","]"]),_(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return m(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||T&&0!=n.length?r<0?m(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),c=T?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(c,w,k)):k[0]+w+k[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,u;if((u=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=u.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):u.set&&(s=e.stylize("[Setter]","special")),I(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(u.value)<0?(s=g(n)?l(e,u.value,null):l(e,u.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),b(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function b(e){return void 0===e}function m(e){return w(e)&&"[object RegExp]"===T(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===T(e)}function S(e){return w(e)&&("[object Error]"===T(e)||e instanceof Error)}function _(e){return"function"==typeof e}function T(e){return Object.prototype.toString.call(e)}function k(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(b(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=b,t.isRegExp=m,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=_,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(50);var C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[k(e.getHours()),k(e.getMinutes()),k(e.getSeconds())].join(":"),[e.getDate(),C[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(7),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var x="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function R(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(x&&e[x]){var t;if("function"!=typeof(t=e[x]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,x,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===c.prototype||(t=function(e){return c.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):C(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function T(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(k,e):k(e))}function k(e){p("emit readable"),e.emit("readable"),O(e)}function C(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(I,e,t))}function I(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=c.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function M(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?M(this):T(this),null;if(0===(e=_(e,t))&&t.ended)return 0===t.length&&M(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?P(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&M(this)),null!==r&&this.emit("data",r),r},m.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},m.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var u=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:m;function c(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",b),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",c),n.removeListener("end",l),n.removeListener("end",m),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(u):n.once("end",u),e.on("unpipe",c);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,O(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==A(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),m(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",b),m()}function b(){p("onfinish"),e.removeListener("close",v),m()}function m(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",b),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},m.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=a.length,s=u,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=o[e];if(void 0===u)return!1;if("function"==typeof u)i(u,this,t);else{var c=u.length,l=d(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(34).EventEmitter},function(e,t,n){"use strict";var r=n(18);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";(function(t,r,o){var i=n(18);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=b;var s,u=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;b.WritableState=v;var c=n(15);c.inherits=n(7);var l={deprecate:n(56)},f=n(35),h=n(6).Buffer,p=o.Uint8Array||function(){};var d,g=n(36);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,c=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(c||0===c)?c:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(T,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),T(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?u(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function b(e){if(s=s||n(10),!(d.call(b,this)||this instanceof s))return new b(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function m(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),T(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,u=!0;n;)o[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;o.allBuffers=u,m(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,f=n.callback;if(m(e,t,!1,t.objectMode?1:c.length,c,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),T(e,t)})}function T(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(_,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}c.inherits(b,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(b,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===b&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},b.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},b.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var u=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(b.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),b.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},b.prototype._writev=null,b.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(b.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),b.prototype.destroy=g.destroy,b.prototype._undestroy=g.undestroy,b.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(14),n(54).setImmediate,n(5))},function(e,t,n){"use strict";var r=n(6).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=c,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function u(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function c(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(15);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]s?a.slice(s).buffer:null}else{var u,c=t;if(-1===(u=c.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=u+1;n=c.substring(0,s),i=c.length>s?c.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(11).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?r-4:r,f=0;f>16&255,s[u++]=t>>8&255,s[u++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[u++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[u++]=t>>8&255,s[u++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,u=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=c}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,u,c=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+f>=1?h/u:h*Math.pow(2,1-f))*u>=2&&(a++,u/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*u-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,c-=8);e[n+p-d]|=128*g}},function(e,t,n){"use strict";(function(t){ +var r=n(47),o=n(48),i=n(31);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function T(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return R(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return T(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},u.prototype.equals=function(e){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===u.compare(this,e)},u.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return b(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return _(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var C=4096;function I(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function A(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function B(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function D(e,t,n,r,i){return i||B(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||B(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||P(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||P(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||P(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||P(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||P(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||P(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||P(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||P(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||P(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||P(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return D(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return D(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(5))},function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function s(e,t){for(var n=[],r=2;r1)for(var n=1;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.length||e<0)){var t=this._offset(e);return this._bufs[t[0]][t[1]]}},a.prototype.slice=function(e,t){return"number"==typeof e&&e<0&&(e+=this.length),"number"==typeof t&&t<0&&(t+=this.length),this.copy(null,0,e,t)},a.prototype.copy=function(e,t,n,r){if(("number"!=typeof n||n<0)&&(n=0),("number"!=typeof r||r>this.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,u=this._offset(n),c=r-n,l=c,f=s&&t||0,h=u[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){if(e=e||0,t="number"!=typeof t?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return new a;var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;ethis.length?this.length:t;for(var r=this._offset(t),o=r[0],s=r[1];o=e.length){var c=u.indexOf(e,s);if(-1!==c)return this._reverseOffset([o,c]);s=u.length-e.length+1}else{var l=this._reverseOffset([o,s]);if(this._match(l,e))return l;s++}}s=0}return-1},a.prototype._match=function(e,t){if(this.length-e=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16),o=n(22),i=n(8);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:i.attachRootComponentToElement,http:o.internalFunctions,uriHelper:r.internalFunctions}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),u=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),m(r.showHidden)&&(r.showHidden=!1),m(r.depth)&&(r.depth=2),m(r.colors)&&(r.colors=!1),m(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=u),l(r,e,r.depth)}function u(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function c(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&_(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(m(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(_(n)){var u=n.name?": "+n.name:"";return e.stylize("[Function"+u+"]","special")}if(b(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var c,w="",T=!1,k=["{","}"];(p(n)&&(T=!0,k=["[","]"]),_(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return b(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||T&&0!=n.length?r<0?b(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),c=T?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(c,w,k)):k[0]+w+k[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,u;if((u=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=u.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):u.set&&(s=e.stylize("[Setter]","special")),I(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(u.value)<0?(s=g(n)?l(e,u.value,null):l(e,u.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),m(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function m(e){return void 0===e}function b(e){return w(e)&&"[object RegExp]"===T(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===T(e)}function S(e){return w(e)&&("[object Error]"===T(e)||e instanceof Error)}function _(e){return"function"==typeof e}function T(e){return Object.prototype.toString.call(e)}function k(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(m(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=m,t.isRegExp=b,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=_,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(50);var C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[k(e.getHours()),k(e.getMinutes()),k(e.getSeconds())].join(":"),[e.getDate(),C[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(7),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var x="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function R(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(x&&e[x]){var t;if("function"!=typeof(t=e[x]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,x,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===c.prototype||(t=function(e){return c.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):C(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function T(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(k,e):k(e))}function k(e){p("emit readable"),e.emit("readable"),O(e)}function C(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(I,e,t))}function I(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=c.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function M(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?M(this):T(this),null;if(0===(e=_(e,t))&&t.ended)return 0===t.length&&M(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?P(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&M(this)),null!==r&&this.emit("data",r),r},b.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},b.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var u=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:b;function c(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",m),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",c),n.removeListener("end",l),n.removeListener("end",b),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(u):n.once("end",u),e.on("unpipe",c);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,O(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==A(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),b(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",m),b()}function m(){p("onfinish"),e.removeListener("close",v),b()}function b(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",m),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},b.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=a.length,s=u,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=o[e];if(void 0===u)return!1;if("function"==typeof u)i(u,this,t);else{var c=u.length,l=d(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(34).EventEmitter},function(e,t,n){"use strict";var r=n(18);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";(function(t,r,o){var i=n(18);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=m;var s,u=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;m.WritableState=v;var c=n(15);c.inherits=n(7);var l={deprecate:n(56)},f=n(35),h=n(6).Buffer,p=o.Uint8Array||function(){};var d,g=n(36);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,c=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(c||0===c)?c:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(T,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),T(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?u(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function m(e){if(s=s||n(10),!(d.call(m,this)||this instanceof s))return new m(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function b(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),T(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,u=!0;n;)o[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;o.allBuffers=u,b(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,f=n.callback;if(b(e,t,!1,t.objectMode?1:c.length,c,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),T(e,t)})}function T(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(_,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}c.inherits(m,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(m,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===m&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},m.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},m.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var u=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(m.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),m.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},m.prototype._writev=null,m.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(m.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),m.prototype.destroy=g.destroy,m.prototype._undestroy=g.undestroy,m.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(14),n(54).setImmediate,n(5))},function(e,t,n){"use strict";var r=n(6).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=c,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function u(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function c(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(15);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]s?a.slice(s).buffer:null}else{var u,c=t;if(-1===(u=c.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=u+1;n=c.substring(0,s),i=c.length>s?c.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(11).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?r-4:r,f=0;f>16&255,s[u++]=t>>8&255,s[u++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[u++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[u++]=t>>8&255,s[u++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,u=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=c}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,u,c=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+f>=1?h/u:h*Math.pow(2,1-f))*u>=2&&(a++,u/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*u-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,c-=8);e[n+p-d]|=128*g}},function(e,t,n){"use strict";(function(t){ /*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh * @license MIT */ -function r(e,t){if(e===t)return 0;for(var n=e.length,r=t.length,o=0,i=Math.min(n,r);o=0;c--)if(l[c]!==f[c])return!1;for(c=l.length-1;c>=0;c--)if(u=l[c],!b(e[u],t[u],n,r))return!1;return!0}(e,t,n,a))}return n?e===t:e==t}function m(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function w(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function E(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&y(o,n,"Missing expected exception"+r);var a="string"==typeof r,s=!e&&o&&!n;if((!e&&i.isError(o)&&a&&w(o,n)||s)&&y(o,n,"Got unwanted exception"+r),e&&o&&n&&!w(o,n)||!e&&o)throw o}f.AssertionError=function(e){var t;this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=d(g((t=this).actual),128)+" "+t.operator+" "+d(g(t.expected),128),this.generatedMessage=!0);var n=e.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var o=r.stack,i=p(n),a=o.indexOf("\n"+i);if(a>=0){var s=o.indexOf("\n",a+1);o=o.substring(s+1)}this.stack=o}}},i.inherits(f.AssertionError,Error),f.fail=y,f.ok=v,f.equal=function(e,t,n){e!=t&&y(e,t,n,"==",f.equal)},f.notEqual=function(e,t,n){e==t&&y(e,t,n,"!=",f.notEqual)},f.deepEqual=function(e,t,n){b(e,t,!1)||y(e,t,n,"deepEqual",f.deepEqual)},f.deepStrictEqual=function(e,t,n){b(e,t,!0)||y(e,t,n,"deepStrictEqual",f.deepStrictEqual)},f.notDeepEqual=function(e,t,n){b(e,t,!1)&&y(e,t,n,"notDeepEqual",f.notDeepEqual)},f.notDeepStrictEqual=function e(t,n,r){b(t,n,!0)&&y(t,n,r,"notDeepStrictEqual",e)},f.strictEqual=function(e,t,n){e!==t&&y(e,t,n,"===",f.strictEqual)},f.notStrictEqual=function(e,t,n){e===t&&y(e,t,n,"!==",f.notStrictEqual)},f.throws=function(e,t,n){E(!0,e,t,n)},f.doesNotThrow=function(e,t,n){E(!1,e,t,n)},f.ifError=function(e){if(e)throw e};var S=Object.keys||function(e){var t=[];for(var n in e)a.call(e,n)&&t.push(n);return t}}).call(this,n(5))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){},function(e,t,n){"use strict";var r=n(6).Buffer,o=n(53);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,n=i,o=s,t.copy(n,o),s+=a.data.length,a=a.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(55),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(5))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,s,u=1,c={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick(function(){d(e)})}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&d(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(a+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=u,e.exports.encoder=s},function(e,t,n){"use strict";var r=n(17);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(30).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var a=e.readUInt32BE(t+0),s=e.readUInt32BE(t+4);return(4294967296*a+s)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),a(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),a(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),s(e,r,i,3);case 223:return i=e.readUInt32BE(r+1),s(e,r,i,5);case 212:return u(e,r,1);case 213:return u(e,r,2);case 214:return u(e,r,4);case 215:return u(e,r,8);case 216:return u(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?c(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?c(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?c(e,r,l,i,6):null}if(144==(240&h))return a(e,r,i=15&h,1);if(128==(240&h))return s(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function a(e,t,r,o){var a,s=[],u=0;for(t+=o,a=0;a0&&l.write(u,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(u,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(u,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(u,5));else if(u&&(u.readUInt32LE||u instanceof Uint8Array))u instanceof Uint8Array&&(u=r.from(u)),u.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=u.length):u.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(u.length,1)),l=o([l,u]);else if(Array.isArray(u))u.length<16?(l=r.allocUnsafe(1))[0]=144|u.length:u.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(u.length,1)),l=u.reduce(function(e,t){return e.append(s(t,!0)),e},o().append(l));else{if(!a&&"function"==typeof u.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),a=1e6*(n-1e3*i);if(a||i>4294967295){(t=r.allocUnsafe(10))[0]=215,t[1]=-1;var s=4*a,u=i/Math.pow(2,32),c=s+u&4294967295,l=4294967295&i;t.writeInt32BE(c,2),t.writeInt32BE(l,6)}else(t=r.allocUnsafe(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(u);if("object"==typeof u)l=function(t){var n,i,a=-1,s=[];for(n=0;n>8),s.push(255&a)):(s.push(201),s.push(a>>24),s.push(a>>16&255),s.push(a>>8&255),s.push(255&a));return o().append(r.from(s)).append(i)}(u)||function(e){var t,n,i=[],a=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++a,i.push(s(t,!0)),i.push(s(e[t],!0)));a<16?(n=r.allocUnsafe(1))[0]=128|a:a<65535?((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(a,1)):((n=r.allocUnsafe(5))[0]=223,n.writeUInt32BE(a,1));return i.unshift(n),i.reduce(function(e,t){return e.append(t)},o())}(u);else if("number"==typeof u){if(function(e){return e%1!=0}(u))return i(u,t);if(u>=0)if(u<128)(l=r.allocUnsafe(1))[0]=u;else if(u<256)(l=r.allocUnsafe(2))[0]=204,l[1]=u;else if(u<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(u,1);else if(u<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(u,1);else{if(!(u<=9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,u)}else if(u>=-32)(l=r.allocUnsafe(1))[0]=256+u;else if(u>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(u,1);else if(u>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(u,1);else if(u>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(u,1);else{if(!(u>=-9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var a=1,s=t+7;s>=t;s--){var u=(255^e[s])+a;e[s]=255&u,a=u>>8}}(l,1,u)}}}if(!l)throw new Error("not implemented yet");return c?l:l.slice()}return s}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.dialog=e}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(40),o=function(){function e(e){this.document=e,this.addedToDom=!1,this.modal=this.document.createElement("div"),this.modal.id=r.AutoReconnectCircuitHandler.DialogId;this.modal.style.cssText=["position: fixed","top: 0","right: 0","bottom: 0","left: 0","z-index: 1000","display: none","overflow: hidden","background-color: #fff","opacity: 0.8","text-align: center","font-weight: bold"].join(";"),this.modal.innerHTML='
',this.message=this.modal.querySelector("h5"),this.button=this.modal.querySelector("button"),this.button.addEventListener("click",function(){return window.Blazor.reconnect()})}return e.prototype.show=function(){this.addedToDom||(this.addedToDom=!0,this.document.body.appendChild(this.modal)),this.modal.style.display="block",this.button.style.display="none",this.message.textContent="Attempting to reconnect to the server..."},e.prototype.hide=function(){this.modal.style.display="none"},e.prototype.failed=function(){this.button.style.display="block",this.message.textContent="Failed to reconnect to the server."},e}();t.DefaultReconnectDisplay=o},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId)this.logger.log(s.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed.");else try{this.nextBatchId++,this.logger.log(s.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new a.OutOfProcessRenderBatch(t)),this.completeBatch(n,e)}catch(t){throw this.logger.log(s.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,t.toString()),t}},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,function(){return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(s.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}})})},e.renderQueues=new Map,e}();t.default=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(65),o=function(){function e(e){this.batchData=e;var t=new u(e);this.arrayRangeReader=new c(e),this.arraySegmentReader=new l(e),this.diffReader=new i(e),this.editReader=new a(e,t),this.frameReader=new s(e,t)}return e.prototype.updatedComponents=function(){return f(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return f(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return f(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return f(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+16*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e}();t.OutOfProcessRenderBatch=o;var i=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return f(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),a=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return f(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return f(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return f(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=f(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),s=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return f(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return f(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return f(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return f(this.batchDataUint8,e+12)},e}(),u=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=f(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t,n=f(this.batchDataUint8,this.stringTableStartIndex+4*e),o=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(19),o=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}();t.NullLogger=o;var i=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}},a=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a};Object.defineProperty(t,"__esModule",{value:!0});var s=n(16),u=n(68),c=function(){function e(e,t){this.circuitId=e,this.components=t}return e.prototype.reconnect=function(e){return e.invoke("ConnectCircuit",this.circuitId)},e}();function l(e){if(e.nodeType===Node.COMMENT_NODE&&e.textContent){var t=/\W+M.A.C.Component:[^{]*(.*)$/.exec(e.textContent),n=t&&t[1];if(n)try{var r=JSON.parse(n),o=r.componentId,i=r.circuitId,a=r.rendererId;if(!!o&&!!i&&!!a)return{node:e,circuitId:i,rendererId:Number.parseInt(a),componentId:Number.parseInt(o)};throw new Error("Found malformed start component comment at "+e.textContent)}catch(t){throw new Error("Found malformed start component comment at "+e.textContent)}}}function f(e,t,n,r){for(var o=n;o>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+a):n.subarray(o+i,o+i+a)),o=o+i+a}return t},e}();var s=new Uint8Array([145,i.MessageType.Ping]),u=function(){function e(){this.name="messagepack",this.version=1,this.transferFormat=i.TransferFormat.Binary}return e.prototype.parseMessages=function(e,t){if(!(e instanceof r.Buffer||(n=e,n&&"undefined"!=typeof ArrayBuffer&&(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer or Buffer.");var n;null===t&&(t=i.NullLogger.instance);for(var o=[],s=0,u=a.parse(e);s=0;c--)if(l[c]!==f[c])return!1;for(c=l.length-1;c>=0;c--)if(u=l[c],!m(e[u],t[u],n,r))return!1;return!0}(e,t,n,a))}return n?e===t:e==t}function b(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function w(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function E(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&y(o,n,"Missing expected exception"+r);var a="string"==typeof r,s=!e&&o&&!n;if((!e&&i.isError(o)&&a&&w(o,n)||s)&&y(o,n,"Got unwanted exception"+r),e&&o&&n&&!w(o,n)||!e&&o)throw o}f.AssertionError=function(e){var t;this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=d(g((t=this).actual),128)+" "+t.operator+" "+d(g(t.expected),128),this.generatedMessage=!0);var n=e.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var o=r.stack,i=p(n),a=o.indexOf("\n"+i);if(a>=0){var s=o.indexOf("\n",a+1);o=o.substring(s+1)}this.stack=o}}},i.inherits(f.AssertionError,Error),f.fail=y,f.ok=v,f.equal=function(e,t,n){e!=t&&y(e,t,n,"==",f.equal)},f.notEqual=function(e,t,n){e==t&&y(e,t,n,"!=",f.notEqual)},f.deepEqual=function(e,t,n){m(e,t,!1)||y(e,t,n,"deepEqual",f.deepEqual)},f.deepStrictEqual=function(e,t,n){m(e,t,!0)||y(e,t,n,"deepStrictEqual",f.deepStrictEqual)},f.notDeepEqual=function(e,t,n){m(e,t,!1)&&y(e,t,n,"notDeepEqual",f.notDeepEqual)},f.notDeepStrictEqual=function e(t,n,r){m(t,n,!0)&&y(t,n,r,"notDeepStrictEqual",e)},f.strictEqual=function(e,t,n){e!==t&&y(e,t,n,"===",f.strictEqual)},f.notStrictEqual=function(e,t,n){e===t&&y(e,t,n,"!==",f.notStrictEqual)},f.throws=function(e,t,n){E(!0,e,t,n)},f.doesNotThrow=function(e,t,n){E(!1,e,t,n)},f.ifError=function(e){if(e)throw e};var S=Object.keys||function(e){var t=[];for(var n in e)a.call(e,n)&&t.push(n);return t}}).call(this,n(5))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){},function(e,t,n){"use strict";var r=n(6).Buffer,o=n(53);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,n=i,o=s,t.copy(n,o),s+=a.data.length,a=a.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(55),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(5))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,s,u=1,c={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick(function(){d(e)})}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&d(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(a+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=u,e.exports.encoder=s},function(e,t,n){"use strict";var r=n(17);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(30).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var a=e.readUInt32BE(t+0),s=e.readUInt32BE(t+4);return(4294967296*a+s)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),a(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),a(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),s(e,r,i,3);case 223:return i=e.readUInt32BE(r+1),s(e,r,i,5);case 212:return u(e,r,1);case 213:return u(e,r,2);case 214:return u(e,r,4);case 215:return u(e,r,8);case 216:return u(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?c(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?c(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?c(e,r,l,i,6):null}if(144==(240&h))return a(e,r,i=15&h,1);if(128==(240&h))return s(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function a(e,t,r,o){var a,s=[],u=0;for(t+=o,a=0;a0&&l.write(u,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(u,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(u,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(u,5));else if(u&&(u.readUInt32LE||u instanceof Uint8Array))u instanceof Uint8Array&&(u=r.from(u)),u.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=u.length):u.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(u.length,1)),l=o([l,u]);else if(Array.isArray(u))u.length<16?(l=r.allocUnsafe(1))[0]=144|u.length:u.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(u.length,1)),l=u.reduce(function(e,t){return e.append(s(t,!0)),e},o().append(l));else{if(!a&&"function"==typeof u.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),a=1e6*(n-1e3*i);if(a||i>4294967295){(t=r.allocUnsafe(10))[0]=215,t[1]=-1;var s=4*a,u=i/Math.pow(2,32),c=s+u&4294967295,l=4294967295&i;t.writeInt32BE(c,2),t.writeInt32BE(l,6)}else(t=r.allocUnsafe(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(u);if("object"==typeof u)l=function(t){var n,i,a=-1,s=[];for(n=0;n>8),s.push(255&a)):(s.push(201),s.push(a>>24),s.push(a>>16&255),s.push(a>>8&255),s.push(255&a));return o().append(r.from(s)).append(i)}(u)||function(e){var t,n,i=[],a=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++a,i.push(s(t,!0)),i.push(s(e[t],!0)));a<16?(n=r.allocUnsafe(1))[0]=128|a:a<65535?((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(a,1)):((n=r.allocUnsafe(5))[0]=223,n.writeUInt32BE(a,1));return i.unshift(n),i.reduce(function(e,t){return e.append(t)},o())}(u);else if("number"==typeof u){if(function(e){return e%1!=0}(u))return i(u,t);if(u>=0)if(u<128)(l=r.allocUnsafe(1))[0]=u;else if(u<256)(l=r.allocUnsafe(2))[0]=204,l[1]=u;else if(u<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(u,1);else if(u<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(u,1);else{if(!(u<=9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,u)}else if(u>=-32)(l=r.allocUnsafe(1))[0]=256+u;else if(u>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(u,1);else if(u>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(u,1);else if(u>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(u,1);else{if(!(u>=-9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var a=1,s=t+7;s>=t;s--){var u=(255^e[s])+a;e[s]=255&u,a=u>>8}}(l,1,u)}}}if(!l)throw new Error("not implemented yet");return c?l:l.slice()}return s}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.dialog=e}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(40),o=function(){function e(e){this.document=e,this.addedToDom=!1,this.modal=this.document.createElement("div"),this.modal.id=r.AutoReconnectCircuitHandler.DialogId;this.modal.style.cssText=["position: fixed","top: 0","right: 0","bottom: 0","left: 0","z-index: 1000","display: none","overflow: hidden","background-color: #fff","opacity: 0.8","text-align: center","font-weight: bold"].join(";"),this.modal.innerHTML='
',this.message=this.modal.querySelector("h5"),this.button=this.modal.querySelector("button"),this.button.addEventListener("click",function(){return window.Blazor.reconnect()})}return e.prototype.show=function(){this.addedToDom||(this.addedToDom=!0,this.document.body.appendChild(this.modal)),this.modal.style.display="block",this.button.style.display="none",this.message.textContent="Attempting to reconnect to the server..."},e.prototype.hide=function(){this.modal.style.display="none"},e.prototype.failed=function(){this.button.style.display="block",this.message.textContent="Failed to reconnect to the server."},e}();t.DefaultReconnectDisplay=o},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId)this.logger.log(s.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed.");else try{this.nextBatchId++,this.logger.log(s.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new a.OutOfProcessRenderBatch(t)),this.completeBatch(n,e)}catch(t){throw this.logger.log(s.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,t.toString()),t}},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,function(){return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(s.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}})})},e.renderQueues=new Map,e}();t.default=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(65),o=function(){function e(e){this.batchData=e;var t=new u(e);this.arrayRangeReader=new c(e),this.arraySegmentReader=new l(e),this.diffReader=new i(e),this.editReader=new a(e,t),this.frameReader=new s(e,t)}return e.prototype.updatedComponents=function(){return f(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return f(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return f(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return f(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+16*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e}();t.OutOfProcessRenderBatch=o;var i=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return f(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),a=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return f(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return f(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return f(this.batchDataUint8,e+8)},e.prototype.moveToSiblingIndex=function(e){return f(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=f(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),s=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return f(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return f(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return f(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return f(this.batchDataUint8,e+12)},e}(),u=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=f(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t,n=f(this.batchDataUint8,this.stringTableStartIndex+4*e),o=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(19),o=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}();t.NullLogger=o;var i=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)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 a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}},a=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a};Object.defineProperty(t,"__esModule",{value:!0});var s=n(16),u=n(68),c=function(){function e(e,t){this.circuitId=e,this.components=t}return e.prototype.reconnect=function(e){return e.invoke("ConnectCircuit",this.circuitId)},e}();function l(e){if(e.nodeType===Node.COMMENT_NODE&&e.textContent){var t=/\W+M.A.C.Component:[^{]*(.*)$/.exec(e.textContent),n=t&&t[1];if(n)try{var r=JSON.parse(n),o=r.componentId,i=r.circuitId,a=r.rendererId;if(!!o&&!!i&&!!a)return{node:e,circuitId:i,rendererId:Number.parseInt(a),componentId:Number.parseInt(o)};throw new Error("Found malformed start component comment at "+e.textContent)}catch(t){throw new Error("Found malformed start component comment at "+e.textContent)}}}function f(e,t,n,r){for(var o=n;o>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+a):n.subarray(o+i,o+i+a)),o=o+i+a}return t},e}();var s=new Uint8Array([145,i.MessageType.Ping]),u=function(){function e(){this.name="messagepack",this.version=1,this.transferFormat=i.TransferFormat.Binary}return e.prototype.parseMessages=function(e,t){if(!(e instanceof r.Buffer||(n=e,n&&"undefined"!=typeof ArrayBuffer&&(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer or Buffer.");var n;null===t&&(t=i.NullLogger.instance);for(var o=[],s=0,u=a.parse(e);s0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===c(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):d(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=c},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l, referenceFrames: ArrayValues) { let currentDepth = 0; let childIndexAtCurrentDepth = childIndex; + let permutationList: PermutationListEntry[] | undefined; const arraySegmentReader = batch.arraySegmentReader; const editReader = batch.editReader; @@ -152,6 +161,19 @@ export class BrowserRenderer { childIndexAtCurrentDepth = currentDepth === 0 ? childIndex : 0; // The childIndex is only ever nonzero at zero depth break; } + case EditType.permutationListEntry: { + permutationList = permutationList || []; + permutationList.push({ + fromSiblingIndex: childIndexAtCurrentDepth + editReader.siblingIndex(edit), + toSiblingIndex: childIndexAtCurrentDepth + editReader.moveToSiblingIndex(edit), + }); + break; + } + case EditType.permutationListEnd: { + permuteLogicalChildren(parent, permutationList!); + permutationList = undefined; + break; + } default: { const unknownType: never = editType; // Compile-time verification that the switch was exhaustive throw new Error(`Unknown edit type: ${unknownType}`); diff --git a/src/Components/Browser.JS/src/Rendering/LogicalElements.ts b/src/Components/Browser.JS/src/Rendering/LogicalElements.ts index f52e170fa424..dee2e78e2538 100644 --- a/src/Components/Browser.JS/src/Rendering/LogicalElements.ts +++ b/src/Components/Browser.JS/src/Rendering/LogicalElements.ts @@ -155,13 +155,60 @@ export function getLogicalChildrenArray(element: LogicalElement) { return element[logicalChildrenPropname] as LogicalElement[]; } -function getLogicalNextSibling(element: LogicalElement): LogicalElement | null { - const siblings = getLogicalChildrenArray(getLogicalParent(element)!); - const siblingIndex = Array.prototype.indexOf.call(siblings, element); - return siblings[siblingIndex + 1] || null; +export function permuteLogicalChildren(parent: LogicalElement, permutationList: PermutationListEntry[]) { + // The permutationList must represent a valid permutation, i.e., the list of 'from' indices + // is distinct, and the list of 'to' indices is a permutation of it. The algorithm here + // relies on that assumption. + + // Each of the phases here has to happen separately, because each one is designed not to + // interfere with the indices or DOM entries used by subsequent phases. + + // Phase 1: track which nodes we will move + const siblings = getLogicalChildrenArray(parent); + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + listEntry.moveRangeStart = siblings[listEntry.fromSiblingIndex]; + listEntry.moveRangeEnd = findLastDomNodeInRange(listEntry.moveRangeStart); + }); + + // Phase 2: insert markers + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + const marker = listEntry.moveToBeforeMarker = document.createComment('marker'); + const insertBeforeNode = siblings[listEntry.toSiblingIndex + 1] as any as Node; + if (insertBeforeNode) { + insertBeforeNode.parentNode!.insertBefore(marker, insertBeforeNode); + } else { + appendDomNode(marker, parent); + } + }); + + // Phase 3: move descendants & remove markers + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + const insertBefore = listEntry.moveToBeforeMarker!; + const parentDomNode = insertBefore.parentNode!; + const elementToMove = listEntry.moveRangeStart!; + const moveEndNode = listEntry.moveRangeEnd!; + let nextToMove = elementToMove as any as Node | null; + while (nextToMove) { + const nextNext = nextToMove.nextSibling; + parentDomNode.insertBefore(nextToMove, insertBefore); + + if (nextToMove === moveEndNode) { + break; + } else { + nextToMove = nextNext; + } + } + + parentDomNode.removeChild(insertBefore); + }); + + // Phase 4: update siblings index + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + siblings[listEntry.toSiblingIndex] = listEntry.moveRangeStart!; + }); } -function getClosestDomElement(logicalElement: LogicalElement) { +export function getClosestDomElement(logicalElement: LogicalElement) { if (logicalElement instanceof Element) { return logicalElement; } else if (logicalElement instanceof Comment) { @@ -171,6 +218,24 @@ function getClosestDomElement(logicalElement: LogicalElement) { } } +export interface PermutationListEntry { + fromSiblingIndex: number, + toSiblingIndex: number, +} + +interface PermutationListEntryWithTrackingData extends PermutationListEntry { + // These extra properties are used internally when processing the permutation list + moveRangeStart?: LogicalElement, + moveRangeEnd?: Node, + moveToBeforeMarker?: Node, +} + +function getLogicalNextSibling(element: LogicalElement): LogicalElement | null { + const siblings = getLogicalChildrenArray(getLogicalParent(element)!); + const siblingIndex = Array.prototype.indexOf.call(siblings, element); + return siblings[siblingIndex + 1] || null; +} + function appendDomNode(child: Node, parent: LogicalElement) { // This function only puts 'child' into the DOM in the right place relative to 'parent' // It does not update the logical children array of anything @@ -192,6 +257,27 @@ function appendDomNode(child: Node, parent: LogicalElement) { } } +// Returns the final node (in depth-first evaluation order) that is a descendant of the logical element. +// As such, the entire subtree is between 'element' and 'findLastDomNodeInRange(element)' inclusive. +function findLastDomNodeInRange(element: LogicalElement) { + if (element instanceof Element) { + return element; + } + + const nextSibling = getLogicalNextSibling(element); + if (nextSibling) { + // Simple case: not the last logical sibling, so take the node before the next sibling + return (nextSibling as any as Node).previousSibling; + } else { + // Harder case: there's no logical next-sibling, so recurse upwards until we find + // a logical ancestor that does have one, or a physical element + const logicalParent = getLogicalParent(element)!; + return logicalParent instanceof Element + ? logicalParent.lastChild + : findLastDomNodeInRange(logicalParent); + } +} + function createSymbolOrFallback(fallback: string): symbol | string { return typeof Symbol === 'function' ? Symbol() : fallback; } diff --git a/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts b/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts index dde028624f4d..b33025e55d6f 100644 --- a/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts +++ b/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts @@ -100,6 +100,10 @@ class OutOfProcessRenderTreeEditReader implements RenderTreeEditReader { return readInt32LE(this.batchDataUint8, edit as any + 8); // 3rd int } + moveToSiblingIndex(edit: RenderTreeEdit) { + return readInt32LE(this.batchDataUint8, edit as any + 8); // 3rd int + } + removedAttributeName(edit: RenderTreeEdit) { const stringIndex = readInt32LE(this.batchDataUint8, edit as any + 12); // 4th int return this.stringReader.readString(stringIndex); diff --git a/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts b/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts index 3faddab664e0..88a162a447c2 100644 --- a/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts +++ b/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts @@ -37,6 +37,7 @@ export interface RenderTreeEditReader { editType(edit: RenderTreeEdit): EditType; siblingIndex(edit: RenderTreeEdit): number; newTreeIndex(edit: RenderTreeEdit): number; + moveToSiblingIndex(edit: RenderTreeEdit): number; removedAttributeName(edit: RenderTreeEdit): string | null; } @@ -71,6 +72,8 @@ export enum EditType { stepIn = 6, stepOut = 7, updateMarkup = 8, + permutationListEntry = 9, + permutationListEnd = 10, } export enum FrameType { diff --git a/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts b/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts index 4eb5792bdaed..2173cb1ecfc6 100644 --- a/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts +++ b/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts @@ -83,16 +83,17 @@ const diffReader = { // Keep in sync with memory layout in RenderTreeEdit.cs const editReader = { - structLength: 16, + structLength: 20, editType: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 0) as EditType, siblingIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 4), newTreeIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 8), - removedAttributeName: (edit: RenderTreeEdit) => platform.readStringField(edit as any, 12), + moveToSiblingIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 8), + removedAttributeName: (edit: RenderTreeEdit) => platform.readStringField(edit as any, 16), }; // Keep in sync with memory layout in RenderTreeFrame.cs const frameReader = { - structLength: 28, + structLength: 36, frameType: (frame: RenderTreeFrame) => platform.readInt32Field(frame as any, 4) as FrameType, subtreeLength: (frame: RenderTreeFrame) => platform.readInt32Field(frame as any, 8), elementReferenceCaptureId: (frame: RenderTreeFrame) => platform.readStringField(frame as any, 16), diff --git a/src/Components/Browser/src/RendererRegistryEventDispatcher.cs b/src/Components/Browser/src/RendererRegistryEventDispatcher.cs index 469a0dcae022..1ddc01f33590 100644 --- a/src/Components/Browser/src/RendererRegistryEventDispatcher.cs +++ b/src/Components/Browser/src/RendererRegistryEventDispatcher.cs @@ -2,6 +2,7 @@ // 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.Threading.Tasks; using Microsoft.AspNetCore.Components.Rendering; using Microsoft.JSInterop; @@ -13,6 +14,10 @@ namespace Microsoft.AspNetCore.Components.Browser /// public static class RendererRegistryEventDispatcher { + private static bool isDispatchingEvent; + private static Queue deferredIncomingEvents + = new Queue(); + /// /// For framework use only. /// @@ -20,9 +25,62 @@ public static class RendererRegistryEventDispatcher public static Task DispatchEvent( BrowserEventDescriptor eventDescriptor, string eventArgsJson) { - var eventArgs = ParseEventArgsJson(eventDescriptor.EventArgsType, eventArgsJson); - var renderer = RendererRegistry.Current.Find(eventDescriptor.BrowserRendererId); - return renderer.DispatchEventAsync(eventDescriptor.EventHandlerId, eventArgs); + // Be sure we only run one event handler at once. Although they couldn't run + // simultaneously anyway (there's only one thread), they could run nested on + // the stack if somehow one event handler triggers another event synchronously. + // We need event handlers not to overlap because (a) that's consistent with + // server-side Blazor which uses a sync context, and (b) the rendering logic + // relies completely on the idea that within a given scope it's only building + // or processing one batch at a time. + // + // The only currently known case where this makes a difference is in the E2E + // tests in ReorderingFocusComponent, where we hit what seems like a Chrome bug + // where mutating the DOM cause an element's "change" to fire while its "input" + // handler is still running (i.e., nested on the stack) -- this doesn't happen + // in Firefox. Possibly a future version of Chrome may fix this, but even then, + // it's conceivable that DOM mutation events could trigger this too. + + if (isDispatchingEvent) + { + var info = new IncomingEventInfo(eventDescriptor, eventArgsJson); + deferredIncomingEvents.Enqueue(info); + return info.TaskCompletionSource.Task; + } + else + { + isDispatchingEvent = true; + try + { + var eventArgs = ParseEventArgsJson(eventDescriptor.EventArgsType, eventArgsJson); + var renderer = RendererRegistry.Current.Find(eventDescriptor.BrowserRendererId); + return renderer.DispatchEventAsync(eventDescriptor.EventHandlerId, eventArgs); + } + finally + { + isDispatchingEvent = false; + if (deferredIncomingEvents.Count > 0) + { + ProcessNextDeferredEvent(); + } + } + } + } + + private static void ProcessNextDeferredEvent() + { + var info = deferredIncomingEvents.Dequeue(); + var task = DispatchEvent(info.EventDescriptor, info.EventArgsJson); + task.ContinueWith(_ => + { + if (task.Exception != null) + { + info.TaskCompletionSource.SetException(task.Exception); + } + else + { + info.TaskCompletionSource.SetResult(null); + } + }); } private static UIEventArgs ParseEventArgsJson(string eventArgsType, string eventArgsJson) @@ -78,5 +136,19 @@ public class BrowserEventDescriptor /// public string EventArgsType { get; set; } } + + readonly struct IncomingEventInfo + { + public readonly BrowserEventDescriptor EventDescriptor; + public readonly string EventArgsJson; + public readonly TaskCompletionSource TaskCompletionSource; + + public IncomingEventInfo(BrowserEventDescriptor eventDescriptor, string eventArgsJson) + { + EventDescriptor = eventDescriptor; + EventArgsJson = eventArgsJson; + TaskCompletionSource = new TaskCompletionSource(); + } + } } } diff --git a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs index 37431bbb5695..95c356e520e7 100644 --- a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs +++ b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs @@ -771,12 +771,18 @@ public readonly partial struct RenderTreeDiff public readonly int ComponentId; public readonly System.ArraySegment Edits; } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] + [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)] public readonly partial struct RenderTreeEdit { + [System.Runtime.InteropServices.FieldOffsetAttribute(8)] + public readonly int MoveToSiblingIndex; + [System.Runtime.InteropServices.FieldOffsetAttribute(8)] public readonly int ReferenceFrameIndex; + [System.Runtime.InteropServices.FieldOffsetAttribute(16)] public readonly string RemovedAttributeName; + [System.Runtime.InteropServices.FieldOffsetAttribute(4)] public readonly int SiblingIndex; + [System.Runtime.InteropServices.FieldOffsetAttribute(0)] public readonly Microsoft.AspNetCore.Components.RenderTree.RenderTreeEditType Type; } public enum RenderTreeEditType @@ -789,6 +795,8 @@ public enum RenderTreeEditType StepIn = 6, StepOut = 7, UpdateMarkup = 8, + PermutationListEntry = 9, + PermutationListEnd = 10, } public enum RenderTreeFrameType { diff --git a/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs index 24f07042c43d..78a174885bf3 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs @@ -454,13 +454,30 @@ public void OpenComponent(int sequence, Type componentType) /// The value for the key. public void SetKey(object value) { - // This is just a placeholder to enable work in parallel in the - // aspnetcore-tooling repo. - // - // The real implementation will involve multiple overloads, likely: - // SetKey(int value) -- underlying logic - // SetKey(T value) where T: struct -- avoids boxing 'value' before calling .GetHashCode() - // SetKey(object value) -- performs null check before calling .GetHashCode() + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + var parentFrameIndex = GetCurrentParentFrameIndex(); + if (!parentFrameIndex.HasValue) + { + throw new InvalidOperationException("Cannot set a key outside the scope of a component or element."); + } + + var parentFrameIndexValue = parentFrameIndex.Value; + ref var parentFrame = ref _entries.Buffer[parentFrameIndexValue]; + switch (parentFrame.FrameType) + { + case RenderTreeFrameType.Element: + parentFrame = parentFrame.WithElementKey(value); // It's a ref var, so this writes to the array + break; + case RenderTreeFrameType.Component: + parentFrame = parentFrame.WithComponentKey(value); // It's a ref var, so this writes to the array + break; + default: + throw new InvalidOperationException($"Cannot set a key on a frame of type {parentFrame.FrameType}."); + } } private void OpenComponentUnchecked(int sequence, Type componentType) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 6a0514462dea..baaf6097de20 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -3,13 +3,14 @@ using System; using System.Collections.Generic; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; namespace Microsoft.AspNetCore.Components.RenderTree { internal static class RenderTreeDiffBuilder { + enum DiffAction { Match, Insert, Delete } + public static RenderTreeDiff ComputeDiff( Renderer renderer, RenderBatchBuilder batchBuilder, @@ -35,107 +36,302 @@ private static void AppendDiffEntriesForRange( int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl) { + // This is deliberately a very large method. Parts of it could be factored out + // into other private methods, but doing so comes at a consequential perf cost, + // because it involves so much parameter passing. You can think of the code here + // as being several private methods (delimited by #region) pre-inlined. + // + // A naive "extract methods"-type refactoring will worsen perf by about 10%. So, + // if you plan to refactor this, be sure to benchmark the old and new versions + // on Mono WebAssembly. + var hasMoreOld = oldEndIndexExcl > oldStartIndex; var hasMoreNew = newEndIndexExcl > newStartIndex; var prevOldSeq = -1; var prevNewSeq = -1; var oldTree = diffContext.OldTree; var newTree = diffContext.NewTree; - while (hasMoreOld || hasMoreNew) - { - var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue; - var newSeq = hasMoreNew ? newTree[newStartIndex].Sequence : int.MaxValue; + var matchWithNewTreeIndex = -1; // Only used when action == DiffAction.Match + Dictionary keyedItemInfos = null; - if (oldSeq == newSeq) - { - AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, newStartIndex); - oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); - newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); - hasMoreOld = oldEndIndexExcl > oldStartIndex; - hasMoreNew = newEndIndexExcl > newStartIndex; - prevOldSeq = oldSeq; - prevNewSeq = newSeq; - } - else + try + { + while (hasMoreOld || hasMoreNew) { - bool treatAsInsert; - var oldLoopedBack = oldSeq <= prevOldSeq; - var newLoopedBack = newSeq <= prevNewSeq; - if (oldLoopedBack == newLoopedBack) + DiffAction action; + + #region "Read keys and sequence numbers" + int oldSeq, newSeq; + object oldKey, newKey; + if (hasMoreOld) { - // Both sequences are proceeding through the same loop block, so do a simple - // preordered merge join (picking from whichever side brings us closer to being - // back in sync) - treatAsInsert = newSeq < oldSeq; + ref var oldFrame = ref oldTree[oldStartIndex]; + oldSeq = oldFrame.Sequence; + oldKey = KeyValue(ref oldFrame); + } + else + { + oldSeq = int.MaxValue; + oldKey = null; + } - if (oldLoopedBack) - { - // If both old and new have now looped back, we must reset their 'looped back' - // tracker so we can treat them as proceeding through the same loop block - prevOldSeq = prevNewSeq = -1; - } + if (hasMoreNew) + { + ref var newFrame = ref newTree[newStartIndex]; + newSeq = newFrame.Sequence; + newKey = KeyValue(ref newFrame); } - else if (oldLoopedBack) + else + { + newSeq = int.MaxValue; + newKey = null; + } + #endregion + + // If there's a key on either side, prefer matching by key not sequence + if (oldKey != null || newKey != null) { - // Old sequence looped back but new one didn't - // The new sequence either has some extra trailing elements in the current loop block - // which we should insert, or omits some old trailing loop blocks which we should delete - // TODO: Find a way of not recomputing this next flag on every iteration - var newLoopsBackLater = false; - for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) + #region "Get diff action by matching on key" + if (Equals(oldKey, newKey)) + { + // Keys match + action = DiffAction.Match; + matchWithNewTreeIndex = newStartIndex; + } + else { - if (newTree[testIndex].Sequence < newSeq) + // Keys don't match + if (keyedItemInfos == null) { - newLoopsBackLater = true; - break; + keyedItemInfos = BuildKeyToInfoLookup(diffContext, oldStartIndex, oldEndIndexExcl, newStartIndex, newEndIndexExcl); } - } - // If the new sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be inserted). - // If not, then it's unrelated to the previous loop block (so we should treat - // the old items as trailing loop blocks to be removed). - treatAsInsert = newLoopsBackLater; + var oldKeyItemInfo = oldKey != null ? keyedItemInfos[oldKey] : new KeyedItemInfo(-1, -1, false); + var newKeyItemInfo = newKey != null ? keyedItemInfos[newKey] : new KeyedItemInfo(-1, -1, false); + var oldKeyIsInNewTree = oldKeyItemInfo.NewIndex >= 0 && oldKeyItemInfo.IsUnique; + var newKeyIsInOldTree = newKeyItemInfo.OldIndex >= 0 && newKeyItemInfo.IsUnique; + + // If either key is not in the other tree, we can handle it as an insert or a delete + // on this iteration. We're only forced to use the move logic that's not the case + // (i.e., both keys are in both trees) + if (oldKeyIsInNewTree && newKeyIsInOldTree) + { + // It's a move + // Since the recipient of the diff script already has the old frame (the one with oldKey) + // at the current siblingIndex, recurse into oldKey and update its descendants in place. + // We re-order the frames afterwards. + action = DiffAction.Match; + matchWithNewTreeIndex = oldKeyItemInfo.NewIndex; + + // Track the post-edit sibling indices of the moved items + // Since diffContext.SiblingIndex only increases, we can be sure the values we + // write at this point will remain correct, because there won't be any further + // insertions/deletions at smaller sibling indices. + keyedItemInfos[oldKey] = oldKeyItemInfo.WithOldSiblingIndex(diffContext.SiblingIndex); + keyedItemInfos[newKey] = newKeyItemInfo.WithNewSiblingIndex(diffContext.SiblingIndex); + } + else if (!hasMoreNew) + { + // If we've run out of new items, we must be looking at just an old item, so delete it + action = DiffAction.Delete; + } + else + { + // It's an insertion or a deletion, or both + // If the new key is in both trees, but the old key isn't, then the old item was deleted + // Otherwise, it's either an insertion or *both* insertion+deletion, so pick insertion and get the deletion on the next iteration if needed + action = newKeyIsInOldTree ? DiffAction.Delete : DiffAction.Insert; + } + } + #endregion } else { - // New sequence looped back but old one didn't - // The old sequence either has some extra trailing elements in the current loop block - // which we should delete, or the new sequence has extra trailing loop blocks which we - // should insert - // TODO: Find a way of not recomputing this next flag on every iteration - var oldLoopsBackLater = false; - for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) + #region "Get diff action by matching on sequence number" + // Neither side is keyed, so match by sequence number + if (oldSeq == newSeq) { - if (oldTree[testIndex].Sequence < oldSeq) + // Sequences match + action = DiffAction.Match; + matchWithNewTreeIndex = newStartIndex; + } + else + { + // Sequences don't match + var oldLoopedBack = oldSeq <= prevOldSeq; + var newLoopedBack = newSeq <= prevNewSeq; + if (oldLoopedBack == newLoopedBack) { - oldLoopsBackLater = true; - break; + // Both sequences are proceeding through the same loop block, so do a simple + // preordered merge join (picking from whichever side brings us closer to being + // back in sync) + action = newSeq < oldSeq ? DiffAction.Insert : DiffAction.Delete; + + if (oldLoopedBack) + { + // If both old and new have now looped back, we must reset their 'looped back' + // tracker so we can treat them as proceeding through the same loop block + prevOldSeq = -1; + prevNewSeq = -1; + } + } + else if (oldLoopedBack) + { + // Old sequence looped back but new one didn't + // The new sequence either has some extra trailing elements in the current loop block + // which we should insert, or omits some old trailing loop blocks which we should delete + // TODO: Find a way of not recomputing this next flag on every iteration + var newLoopsBackLater = false; + for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) + { + if (newTree[testIndex].Sequence < newSeq) + { + newLoopsBackLater = true; + break; + } + } + + // If the new sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be inserted). + // If not, then it's unrelated to the previous loop block (so we should treat + // the old items as trailing loop blocks to be removed). + action = newLoopsBackLater ? DiffAction.Insert : DiffAction.Delete; + } + else + { + // New sequence looped back but old one didn't + // The old sequence either has some extra trailing elements in the current loop block + // which we should delete, or the new sequence has extra trailing loop blocks which we + // should insert + // TODO: Find a way of not recomputing this next flag on every iteration + var oldLoopsBackLater = false; + for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) + { + if (oldTree[testIndex].Sequence < oldSeq) + { + oldLoopsBackLater = true; + break; + } + } + + // If the old sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be removed). + // If not, then it's unrelated to the previous loop block (so we should treat + // the new items as trailing loop blocks to be inserted). + action = oldLoopsBackLater ? DiffAction.Delete : DiffAction.Insert; } } + #endregion + } - // If the old sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be removed). - // If not, then it's unrelated to the previous loop block (so we should treat - // the new items as trailing loop blocks to be inserted). - treatAsInsert = !oldLoopsBackLater; + #region "Apply diff action" + switch (action) + { + case DiffAction.Match: + AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, matchWithNewTreeIndex); + oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); + newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); + hasMoreOld = oldEndIndexExcl > oldStartIndex; + hasMoreNew = newEndIndexExcl > newStartIndex; + prevOldSeq = oldSeq; + prevNewSeq = newSeq; + break; + case DiffAction.Insert: + InsertNewFrame(ref diffContext, newStartIndex); + newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); + hasMoreNew = newEndIndexExcl > newStartIndex; + prevNewSeq = newSeq; + break; + case DiffAction.Delete: + RemoveOldFrame(ref diffContext, oldStartIndex); + oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); + hasMoreOld = oldEndIndexExcl > oldStartIndex; + prevOldSeq = oldSeq; + break; } + #endregion + } - if (treatAsInsert) + #region "Write permutations list" + if (keyedItemInfos != null) + { + var hasPermutations = false; + foreach (var keyValuePair in keyedItemInfos) { - InsertNewFrame(ref diffContext, newStartIndex); - newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); - hasMoreNew = newEndIndexExcl > newStartIndex; - prevNewSeq = newSeq; + var value = keyValuePair.Value; + if (value.OldSiblingIndex >= 0 && value.NewSiblingIndex >= 0) + { + // This item moved + hasPermutations = true; + diffContext.Edits.Append( + RenderTreeEdit.PermutationListEntry(value.OldSiblingIndex, value.NewSiblingIndex)); + } } - else + + if (hasPermutations) { - RemoveOldFrame(ref diffContext, oldStartIndex); - oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); - hasMoreOld = oldEndIndexExcl > oldStartIndex; - prevOldSeq = oldSeq; + // It's much easier for the recipient to handle if we're explicit about + // when the list is finished + diffContext.Edits.Append(RenderTreeEdit.PermutationListEnd()); } } + #endregion + } + finally + { + if (keyedItemInfos != null) + { + keyedItemInfos.Clear(); + diffContext.KeyedItemInfoDictionaryPool.Return(keyedItemInfos); + } + } + } + + private static Dictionary BuildKeyToInfoLookup(DiffContext diffContext, int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl) + { + var result = diffContext.KeyedItemInfoDictionaryPool.Get(); + var oldTree = diffContext.OldTree; + var newTree = diffContext.NewTree; + + while (oldStartIndex < oldEndIndexExcl) + { + ref var frame = ref oldTree[oldStartIndex]; + var key = KeyValue(ref frame); + if (key != null) + { + result[key] = new KeyedItemInfo(oldStartIndex, -1, isUnique: !result.ContainsKey(key)); + } + + oldStartIndex = NextSiblingIndex(frame, oldStartIndex); + } + + while (newStartIndex < newEndIndexExcl) + { + ref var frame = ref newTree[newStartIndex]; + var key = KeyValue(ref frame); + if (key != null) + { + result[key] = result.TryGetValue(key, out var existingEntry) + ? new KeyedItemInfo(existingEntry.OldIndex, newStartIndex, isUnique: existingEntry.NewIndex < 0) + : new KeyedItemInfo(-1, newStartIndex, isUnique: true); + } + + newStartIndex = NextSiblingIndex(frame, newStartIndex); + } + + return result; + } + + private static object KeyValue(ref RenderTreeFrame frame) + { + switch (frame.FrameType) + { + case RenderTreeFrameType.Element: + return frame.ElementKey; + case RenderTreeFrameType.Component: + return frame.ComponentKey; + default: + return null; } } @@ -315,11 +511,21 @@ private static void AppendDiffEntriesForFramesWithSameSequence( ref var oldFrame = ref oldTree[oldFrameIndex]; ref var newFrame = ref newTree[newFrameIndex]; + // This can't happen for sequence-matched frames from .razor components, but it can happen if you write your + // builder logic manually or if two dissimilar frames matched by key. Treat as completely unrelated. + var newFrameType = newFrame.FrameType; + if (oldFrame.FrameType != newFrameType) + { + InsertNewFrame(ref diffContext, newFrameIndex); + RemoveOldFrame(ref diffContext, oldFrameIndex); + return; + } + // We can assume that the old and new frames are of the same type, because they correspond // to the same sequence number (and if not, the behaviour is undefined). // TODO: Consider supporting dissimilar types at same sequence for custom IComponent implementations. // It should only be a matter of calling RemoveOldFrame+InsertNewFrame - switch (newFrame.FrameType) + switch (newFrameType) { case RenderTreeFrameType.Text: { @@ -718,6 +924,7 @@ private struct DiffContext public readonly ArrayBuilder Edits; public readonly ArrayBuilder ReferenceFrames; public readonly Dictionary AttributeDiffSet; + public readonly StackObjectPool> KeyedItemInfoDictionaryPool; public readonly int ComponentId; public int SiblingIndex; @@ -736,6 +943,7 @@ public DiffContext( Edits = batchBuilder.EditsBuffer; ReferenceFrames = batchBuilder.ReferenceFramesBuffer; AttributeDiffSet = batchBuilder.AttributeDiffSet; + KeyedItemInfoDictionaryPool = batchBuilder.KeyedItemInfoDictionaryPool; SiblingIndex = 0; } } diff --git a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs index d7c0daa7b160..96f661924bbb 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs @@ -1,37 +1,47 @@ // 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.Runtime.InteropServices; namespace Microsoft.AspNetCore.Components.RenderTree { /// /// Represents a single edit operation on a component's render tree. /// + [StructLayout(LayoutKind.Explicit)] public readonly struct RenderTreeEdit { /// /// Gets the type of the edit operation. /// - public readonly RenderTreeEditType Type; + [FieldOffset(0)] public readonly RenderTreeEditType Type; /// /// Gets the index of the sibling frame that the edit relates to. /// - public readonly int SiblingIndex; + [FieldOffset(4)] public readonly int SiblingIndex; /// /// Gets the index of related data in an associated render frames array. For example, if the /// value is , gets the /// index of the new frame data in an associated render tree. /// - public readonly int ReferenceFrameIndex; + [FieldOffset(8)] public readonly int ReferenceFrameIndex; + + /// + /// If the value is , + /// gets the sibling index to which the frame should be moved. + /// + // NOTE: Other code relies on the assumption that ReferenceFrameIndex and + // MoveToSiblingIndex share a memory slot. If you change this, be sure to + // update affected usages of ReferenceFrameIndex. + [FieldOffset(8)] public readonly int MoveToSiblingIndex; /// /// If the value is , /// gets the name of the attribute that is being removed. /// - public readonly string RemovedAttributeName; + [FieldOffset(16)] public readonly string RemovedAttributeName; private RenderTreeEdit(RenderTreeEditType type) : this() { @@ -44,11 +54,14 @@ private RenderTreeEdit(RenderTreeEditType type, int siblingIndex) : this() SiblingIndex = siblingIndex; } - private RenderTreeEdit(RenderTreeEditType type, int siblingIndex, int referenceFrameIndex) : this() + private RenderTreeEdit(RenderTreeEditType type, int siblingIndex, int referenceFrameOrMoveToSiblingIndex) : this() { Type = type; SiblingIndex = siblingIndex; - ReferenceFrameIndex = referenceFrameIndex; + + // MoveToSiblingIndex is stored in the same slot as ReferenceFrameIndex, + // so assigning to either one is equivalent + ReferenceFrameIndex = referenceFrameOrMoveToSiblingIndex; } private RenderTreeEdit(RenderTreeEditType type, int siblingIndex, string removedAttributeName) : this() @@ -81,5 +94,11 @@ internal static RenderTreeEdit StepIn(int siblingIndex) internal static RenderTreeEdit StepOut() => new RenderTreeEdit(RenderTreeEditType.StepOut); + + internal static RenderTreeEdit PermutationListEntry(int fromSiblingIndex, int toSiblingIndex) + => new RenderTreeEdit(RenderTreeEditType.PermutationListEntry, fromSiblingIndex, toSiblingIndex); + + internal static RenderTreeEdit PermutationListEnd() + => new RenderTreeEdit(RenderTreeEditType.PermutationListEnd); } } diff --git a/src/Components/Components/src/RenderTree/RenderTreeEditType.cs b/src/Components/Components/src/RenderTree/RenderTreeEditType.cs index aa7ca3a60428..c2f3e4aba692 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeEditType.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeEditType.cs @@ -51,5 +51,18 @@ public enum RenderTreeEditType: int /// should be updated. /// UpdateMarkup = 8, + + /// + /// An entry in a sparse permutation list. That is, a list of old indices with + /// corresponding new indices, which altogether describe a valid permutation of + /// the children at the current edit position. + /// + PermutationListEntry = 9, + + /// + /// Indicates that the preceding series of entries + /// is now complete. + /// + PermutationListEnd = 10, } } diff --git a/src/Components/Components/src/RenderTree/RenderTreeFrame.cs b/src/Components/Components/src/RenderTree/RenderTreeFrame.cs index 920d0752bb5f..7bf18c150dea 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeFrame.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeFrame.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.InteropServices; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; namespace Microsoft.AspNetCore.Components.RenderTree @@ -17,13 +16,22 @@ public readonly struct RenderTreeFrame // Note that the struct layout has to be valid in both 32-bit and 64-bit runtime platforms, // which means that all reference-type fields need to take up 8 bytes (except for the last // one, which will be sized as either 4 or 8 bytes depending on the runtime platform). - // This is not optimal for the Mono-WebAssembly case because that's always 32-bit so the - // reference-type fields could be reduced to 4 bytes each. We could use ifdefs to have - // different fields offsets for the 32 and 64 bit compile targets, but then we'd have the - // complexity of needing different binaries when loaded into Mono-WASM vs desktop. - // Eventually we might stop using this shared memory interop altogether (and would have to - // if running as a web worker) so for now to keep things simple, treat reference types as - // 8 bytes here. + + // Although each frame type uses the slots for different purposes, the runtime does not + // allow reference type slots to overlap with each other or with value-type slots. + // Here's the current layout: + // + // Offset Type + // ------ ---- + // 0-3 Int32 (sequence number) + // 4-7 Int32 (frame type) + // 8-15 Value types (usage varies by frame type) + // 16-23 Reference type (usage varies by frame type) + // 24-31 Reference type (usage varies by frame type) + // 32-39 Reference type (usage varies by frame type) + // + // On Mono WebAssembly, because it's 32-bit, the final slot occupies bytes 32-35, + // so the struct length is only 36. // -------------------------------------------------------------------------------- // Common @@ -58,6 +66,12 @@ public readonly struct RenderTreeFrame /// [FieldOffset(16)] public readonly string ElementName; + /// + /// If the property equals , + /// gets the element's diffing key, or null if none was specified. + /// + [FieldOffset(24)] public readonly object ElementKey; + // -------------------------------------------------------------------------------- // RenderTreeFrameType.Text // -------------------------------------------------------------------------------- @@ -119,6 +133,12 @@ public readonly struct RenderTreeFrame /// [FieldOffset(24)] internal readonly ComponentState ComponentState; + /// + /// If the property equals , + /// gets the component's diffing key, or null if none was specified. + /// + [FieldOffset(32)] public readonly object ComponentKey; + /// /// If the property equals , /// gets the child component instance. Otherwise, the value is undefined. @@ -184,66 +204,72 @@ public readonly struct RenderTreeFrame /// [FieldOffset(16)] public readonly string MarkupContent; - private RenderTreeFrame(int sequence, string elementName, int elementSubtreeLength) + // Element constructor + private RenderTreeFrame(int sequence, int elementSubtreeLength, string elementName, object elementKey) : this() { - FrameType = RenderTreeFrameType.Element; Sequence = sequence; - ElementName = elementName; + FrameType = RenderTreeFrameType.Element; ElementSubtreeLength = elementSubtreeLength; + ElementName = elementName; + ElementKey = elementKey; } - private RenderTreeFrame(int sequence, Type componentType, int componentSubtreeLength) + // Component constructor + private RenderTreeFrame(int sequence, int componentSubtreeLength, Type componentType, ComponentState componentState, object componentKey) : this() { - FrameType = RenderTreeFrameType.Component; Sequence = sequence; - ComponentType = componentType; + FrameType = RenderTreeFrameType.Component; ComponentSubtreeLength = componentSubtreeLength; - } + ComponentType = componentType; + ComponentKey = componentKey; - private RenderTreeFrame(int sequence, Type componentType, int subtreeLength, ComponentState componentState) - : this(sequence, componentType, subtreeLength) - { - ComponentId = componentState.ComponentId; - ComponentState = componentState; + if (componentState != null) + { + ComponentState = componentState; + ComponentId = componentState.ComponentId; + } } - private RenderTreeFrame(int sequence, string textContent) + // Region constructor + private RenderTreeFrame(int sequence, int regionSubtreeLength) : this() { - FrameType = RenderTreeFrameType.Text; Sequence = sequence; - TextContent = textContent; + FrameType = RenderTreeFrameType.Region; + RegionSubtreeLength = regionSubtreeLength; } - private RenderTreeFrame(int sequence, string attributeName, object attributeValue) + // Text/markup constructor + private RenderTreeFrame(int sequence, bool isMarkup, string textOrMarkup) : this() { - FrameType = RenderTreeFrameType.Attribute; Sequence = sequence; - AttributeName = attributeName; - AttributeValue = attributeValue; + if (isMarkup) + { + FrameType = RenderTreeFrameType.Markup; + MarkupContent = textOrMarkup; + } + else + { + FrameType = RenderTreeFrameType.Text; + TextContent = textOrMarkup; + } } - private RenderTreeFrame(int sequence, string attributeName, object attributeValue, int eventHandlerId) + // Attribute constructor + private RenderTreeFrame(int sequence, string attributeName, object attributeValue, int attributeEventHandlerId) : this() { FrameType = RenderTreeFrameType.Attribute; Sequence = sequence; AttributeName = attributeName; AttributeValue = attributeValue; - AttributeEventHandlerId = eventHandlerId; - } - - private RenderTreeFrame(int sequence, int regionSubtreeLength) - : this() - { - FrameType = RenderTreeFrameType.Region; - Sequence = sequence; - RegionSubtreeLength = regionSubtreeLength; + AttributeEventHandlerId = attributeEventHandlerId; } + // Element reference capture constructor private RenderTreeFrame(int sequence, Action elementReferenceCaptureAction, string elementReferenceCaptureId) : this() { @@ -253,6 +279,7 @@ private RenderTreeFrame(int sequence, Action elementReferenceCapture ElementReferenceCaptureId = elementReferenceCaptureId; } + // Component reference capture constructor private RenderTreeFrame(int sequence, Action componentReferenceCaptureAction, int parentFrameIndex) : this() { @@ -262,36 +289,23 @@ private RenderTreeFrame(int sequence, Action componentReferenceCaptureAc ComponentReferenceCaptureParentFrameIndex = parentFrameIndex; } - // If we need further constructors whose signatures clash with the patterns above, - // we can add extra args to this general-purpose one. - private RenderTreeFrame(int sequence, RenderTreeFrameType frameType, string markupContent) - : this() - { - FrameType = frameType; - Sequence = sequence; - MarkupContent = markupContent; - } - internal static RenderTreeFrame Element(int sequence, string elementName) - => new RenderTreeFrame(sequence, elementName: elementName, elementSubtreeLength: 0); + => new RenderTreeFrame(sequence, elementSubtreeLength: 0, elementName, null); internal static RenderTreeFrame Text(int sequence, string textContent) - => new RenderTreeFrame(sequence, textContent: textContent); + => new RenderTreeFrame(sequence, isMarkup: false, textOrMarkup: textContent); internal static RenderTreeFrame Markup(int sequence, string markupContent) - => new RenderTreeFrame(sequence, RenderTreeFrameType.Markup, markupContent); - - internal static RenderTreeFrame Attribute(int sequence, string name, MulticastDelegate value) - => new RenderTreeFrame(sequence, attributeName: name, attributeValue: value); + => new RenderTreeFrame(sequence, isMarkup: true, textOrMarkup: markupContent); internal static RenderTreeFrame Attribute(int sequence, string name, object value) - => new RenderTreeFrame(sequence, attributeName: name, attributeValue: value); + => new RenderTreeFrame(sequence, attributeName: name, attributeValue: value, attributeEventHandlerId: 0); internal static RenderTreeFrame ChildComponent(int sequence, Type componentType) - => new RenderTreeFrame(sequence, componentType, 0); + => new RenderTreeFrame(sequence, componentSubtreeLength: 0, componentType, null, null); internal static RenderTreeFrame PlaceholderChildComponentWithSubtreeLength(int subtreeLength) - => new RenderTreeFrame(0, typeof(IComponent), subtreeLength); + => new RenderTreeFrame(0, componentSubtreeLength: subtreeLength, typeof(IComponent), null, null); internal static RenderTreeFrame Region(int sequence) => new RenderTreeFrame(sequence, regionSubtreeLength: 0); @@ -303,25 +317,31 @@ internal static RenderTreeFrame ComponentReferenceCapture(int sequence, Action new RenderTreeFrame(sequence, componentReferenceCaptureAction: componentReferenceCaptureAction, parentFrameIndex: parentFrameIndex); internal RenderTreeFrame WithElementSubtreeLength(int elementSubtreeLength) - => new RenderTreeFrame(Sequence, elementName: ElementName, elementSubtreeLength: elementSubtreeLength); + => new RenderTreeFrame(Sequence, elementSubtreeLength: elementSubtreeLength, ElementName, ElementKey); internal RenderTreeFrame WithComponentSubtreeLength(int componentSubtreeLength) - => new RenderTreeFrame(Sequence, componentType: ComponentType, componentSubtreeLength: componentSubtreeLength); + => new RenderTreeFrame(Sequence, componentSubtreeLength: componentSubtreeLength, ComponentType, ComponentState, ComponentKey); internal RenderTreeFrame WithAttributeSequence(int sequence) - => new RenderTreeFrame(sequence, attributeName: AttributeName, attributeValue: AttributeValue); + => new RenderTreeFrame(sequence, attributeName: AttributeName, AttributeValue, AttributeEventHandlerId); internal RenderTreeFrame WithComponent(ComponentState componentState) - => new RenderTreeFrame(Sequence, ComponentType, ComponentSubtreeLength, componentState); + => new RenderTreeFrame(Sequence, componentSubtreeLength: ComponentSubtreeLength, ComponentType, componentState, ComponentKey); internal RenderTreeFrame WithAttributeEventHandlerId(int eventHandlerId) - => new RenderTreeFrame(Sequence, AttributeName, AttributeValue, eventHandlerId); + => new RenderTreeFrame(Sequence, attributeName: AttributeName, AttributeValue, eventHandlerId); internal RenderTreeFrame WithRegionSubtreeLength(int regionSubtreeLength) => new RenderTreeFrame(Sequence, regionSubtreeLength: regionSubtreeLength); internal RenderTreeFrame WithElementReferenceCaptureId(string elementReferenceCaptureId) - => new RenderTreeFrame(Sequence, ElementReferenceCaptureAction, elementReferenceCaptureId); + => new RenderTreeFrame(Sequence, elementReferenceCaptureAction: ElementReferenceCaptureAction, elementReferenceCaptureId); + + internal RenderTreeFrame WithElementKey(object elementKey) + => new RenderTreeFrame(Sequence, elementSubtreeLength: ElementSubtreeLength, ElementName, elementKey); + + internal RenderTreeFrame WithComponentKey(object componentKey) + => new RenderTreeFrame(Sequence, componentSubtreeLength: ComponentSubtreeLength, ComponentType, ComponentState, componentKey); /// // Just to be nice for debugging and unit tests. @@ -333,10 +353,10 @@ public override string ToString() return $"Attribute: (seq={Sequence}, id={AttributeEventHandlerId}) '{AttributeName}'='{AttributeValue}'"; case RenderTreeFrameType.Component: - return $"Component: (seq={Sequence}, len={ComponentSubtreeLength}) {ComponentType}"; + return $"Component: (seq={Sequence}, key={ComponentKey ?? "(none)"}, len={ComponentSubtreeLength}) {ComponentType}"; case RenderTreeFrameType.Element: - return $"Element: (seq={Sequence}, len={ElementSubtreeLength}) {ElementName}"; + return $"Element: (seq={Sequence}, key={ElementKey ?? "(none)"}, len={ElementSubtreeLength}) {ElementName}"; case RenderTreeFrameType.Region: return $"Region: (seq={Sequence}, len={RegionSubtreeLength})"; diff --git a/src/Components/Components/src/RenderTree/StackObjectPool.cs b/src/Components/Components/src/RenderTree/StackObjectPool.cs new file mode 100644 index 000000000000..a2c9c1f5241b --- /dev/null +++ b/src/Components/Components/src/RenderTree/StackObjectPool.cs @@ -0,0 +1,75 @@ +// 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; + +namespace Microsoft.AspNetCore.Components.RenderTree +{ + // This is a very simple object pool that requires Get and Return calls to be + // balanced as in a stack. It retains up to 'maxPreservedItems' instances in + // memory, then for any further requests it supplies untracked instances. + + internal class StackObjectPool where T : class + { + private readonly int _maxPreservedItems; + private readonly Func _instanceFactory; + private readonly T[] _contents; + private int _numSuppliedItems; + private int _numTrackedItems; + + public StackObjectPool(int maxPreservedItems, Func instanceFactory) + { + _maxPreservedItems = maxPreservedItems; + _instanceFactory = instanceFactory ?? throw new ArgumentNullException(nameof(instanceFactory)); + _contents = new T[_maxPreservedItems]; + } + + public T Get() + { + _numSuppliedItems++; + + if (_numSuppliedItems <= _maxPreservedItems) + { + if (_numTrackedItems < _numSuppliedItems) + { + // Need to allocate a new one + var newItem = _instanceFactory(); + _contents[_numTrackedItems++] = newItem; + return newItem; + } + else + { + // Can use one that's already in the pool + return _contents[_numSuppliedItems - 1]; + } + } + else + { + // Pool is full; return untracked instance + return _instanceFactory(); + } + } + + public void Return(T instance) + { + if (_numSuppliedItems <= 0) + { + throw new InvalidOperationException("There are no outstanding instances to return."); + } + else if (_numSuppliedItems <= _maxPreservedItems) + { + // We check you're returning the right instance only as a way of + // catching Get/Return mismatch bugs + var expectedInstance = _contents[_numSuppliedItems - 1]; + if (!ReferenceEquals(instance, expectedInstance)) + { + throw new ArgumentException($"Attempting to return wrong pooled instance. {nameof(Get)}/{nameof(Return)} calls must form a stack."); + } + } + + // It's a valid call. Track that we're no longer "supplying" the top item, + // but keep the instance in the _contents array for future reuse. + _numSuppliedItems--; + } + } +} diff --git a/src/Components/Components/src/Rendering/KeyedItemInfo.cs b/src/Components/Components/src/Rendering/KeyedItemInfo.cs new file mode 100644 index 000000000000..f2a56341e2bb --- /dev/null +++ b/src/Components/Components/src/Rendering/KeyedItemInfo.cs @@ -0,0 +1,46 @@ +// 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.AspNetCore.Components.Rendering +{ + // Used internally during diffing to track what we know about keyed items and their positions + internal readonly struct KeyedItemInfo + { + public readonly int OldIndex; + public readonly int NewIndex; + public readonly int OldSiblingIndex; + public readonly int NewSiblingIndex; + public readonly bool IsUnique; + + public KeyedItemInfo(int oldIndex, int newIndex, bool isUnique) + { + OldIndex = oldIndex; + NewIndex = newIndex; + OldSiblingIndex = -1; + NewSiblingIndex = -1; + + // Non-unique keys are problematic, because there's no way to know which instance + // should match with which other, plus they would force us to keep track of which + // usages have been consumed as we proceed through the diff. Since this is such + // an edge case, we "tolerate" it just by tracking which keys have duplicates, and + // for those ones, we never treat them as moved. Instead for those we fall back on + // insert+delete behavior, i.e., not preserving elements/components. + // + // Guidance for developers is therefore to use distinct keys. + IsUnique = isUnique; + } + + private KeyedItemInfo(in KeyedItemInfo copyFrom, int oldSiblingIndex, int newSiblingIndex) + { + this = copyFrom; + OldSiblingIndex = oldSiblingIndex; + NewSiblingIndex = newSiblingIndex; + } + + public KeyedItemInfo WithOldSiblingIndex(int oldSiblingIndex) + => new KeyedItemInfo(this, oldSiblingIndex, NewSiblingIndex); + + public KeyedItemInfo WithNewSiblingIndex(int newSiblingIndex) + => new KeyedItemInfo(this, OldSiblingIndex, newSiblingIndex); + } +} diff --git a/src/Components/Components/src/Rendering/RenderBatchBuilder.cs b/src/Components/Components/src/Rendering/RenderBatchBuilder.cs index 4bcdd82d0aaf..bb5daacec41b 100644 --- a/src/Components/Components/src/Rendering/RenderBatchBuilder.cs +++ b/src/Components/Components/src/Rendering/RenderBatchBuilder.cs @@ -30,6 +30,9 @@ internal class RenderBatchBuilder // Scratch data structure for understanding attribute diffs. public Dictionary AttributeDiffSet { get; } = new Dictionary(); + internal StackObjectPool> KeyedItemInfoDictionaryPool { get; } + = new StackObjectPool>(maxPreservedItems: 10, () => new Dictionary()); + public void ClearStateForCurrentBatch() { // This method is used to reset the builder back to a default state so it can diff --git a/src/Components/Components/test/RenderTreeBuilderTest.cs b/src/Components/Components/test/RenderTreeBuilderTest.cs index 75a7616b1e70..ac05e9b195b0 100644 --- a/src/Components/Components/test/RenderTreeBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeBuilderTest.cs @@ -1047,6 +1047,107 @@ public void AddAttribute_Element_ObjectNull_IgnoresFrame() frame => AssertFrame.Element(frame, "elem", 1, 0)); } + [Fact] + public void CanAddKeyToElement() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + var keyValue = new object(); + + // Act + builder.OpenElement(0, "elem"); + builder.AddAttribute(1, "attribute before", "before value"); + builder.SetKey(keyValue); + builder.AddAttribute(2, "attribute after", "after value"); + builder.CloseElement(); + + // Assert + Assert.Collection( + builder.GetFrames().AsEnumerable(), + frame => + { + AssertFrame.Element(frame, "elem", 3, 0); + Assert.Same(keyValue, frame.ElementKey); + }, + frame => AssertFrame.Attribute(frame, "attribute before", "before value", 1), + frame => AssertFrame.Attribute(frame, "attribute after", "after value", 2)); + } + + [Fact] + public void CanAddKeyToComponent() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + var keyValue = new object(); + + // Act + builder.OpenComponent(0); + builder.AddAttribute(1, "param before", 123); + builder.SetKey(keyValue); + builder.AddAttribute(2, "param after", 456); + builder.CloseComponent(); + + // Assert + Assert.Collection( + builder.GetFrames().AsEnumerable(), + frame => + { + AssertFrame.Component(frame, 3, 0); + Assert.Same(keyValue, frame.ComponentKey); + }, + frame => AssertFrame.Attribute(frame, "param before", 123, 1), + frame => AssertFrame.Attribute(frame, "param after", 456, 2)); + } + + [Fact] + public void CannotAddKeyOutsideComponentOrElement_TreeRoot() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + + // Act/Assert + var ex = Assert.Throws(() => + { + builder.SetKey(new object()); + }); + Assert.Equal("Cannot set a key outside the scope of a component or element.", ex.Message); + } + + [Fact] + public void CannotAddKeyOutsideComponentOrElement_RegionRoot() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + + // Act/Assert + builder.OpenElement(0, "some element"); + builder.OpenRegion(1); + var ex = Assert.Throws(() => + { + builder.SetKey(new object()); + }); + Assert.Equal($"Cannot set a key on a frame of type {RenderTreeFrameType.Region}.", ex.Message); + } + + [Fact] + public void CannotAddNullKey() + { + // Although we could translate 'null' into either some default "null key" + // instance, or just no-op the call, it almost certainly indicates a programming + // error so it's better to fail. + + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + + // Act/Assert + var ex = Assert.Throws(() => + { + builder.OpenElement(0, "elem"); + builder.SetKey(null); + }); + Assert.Equal("value", ex.ParamName); + } + private class TestComponent : IComponent { public void Configure(RenderHandle renderHandle) { } diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index caafa7c7d599..b1dff6447732 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -103,6 +103,417 @@ public void RecognizesOldItemsBeingRemoved() entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); } + [Fact] + public void RecognizesKeyedElementInsertions() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("retained key"); + oldTree.AddContent(1, "Existing"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("new key"); + newTree.AddContent(1, "Inserted"); + newTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("retained key"); + newTree.AddContent(1, "Existing"); + newTree.CloseElement(); + + // Without the key, it would change the text "Existing" to "Inserted", then insert a new "Existing" below it + // With the key, it just inserts a new "Inserted" at the top + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("new key", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }); + } + + [Fact] + public void RecognizesKeyedElementDeletions() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("will delete"); + oldTree.AddContent(1, "First"); + oldTree.CloseElement(); + + oldTree.OpenElement(0, "container"); + oldTree.SetKey("will retain"); + oldTree.AddContent(1, "Second"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("will retain"); + newTree.AddContent(1, "Second"); + newTree.CloseElement(); + + // Without the key, it changes the text content of "First" to "Second", then deletes the other "Second" + // With the key, it just deletes "First" + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 0)); + } + + [Fact] + public void RecognizesSimultaneousKeyedElementInsertionsAndDeletions() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("original key"); + oldTree.AddContent(1, "Original"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("new key"); + newTree.AddContent(1, "Inserted"); + newTree.CloseElement(); + + // Without the key, it would change the text "Original" to "Inserted" + // With the key, it deletes the old element and inserts the new element + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("new key", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + + [Fact] + public void RecognizesKeyedComponentInsertions() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("retained key"); + oldTree.AddAttribute(1, "ParamName", "Param old value"); + oldTree.CloseComponent(); + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); // Assign initial IDs + var oldComponent = GetComponents(oldTree).Single(); + + newTree.OpenComponent(0); + newTree.SetKey("new key"); + newTree.AddAttribute(1, "ParamName", "New component param value"); + newTree.CloseComponent(); + + newTree.OpenComponent(0); + newTree.SetKey("retained key"); + newTree.AddAttribute(1, "ParamName", "Param new value"); + newTree.CloseComponent(); + + // Without the key, it would modify the param on the first component, + // then insert a new second component. + // With the key, it inserts a new first component, then modifies the + // param on the second component. + + // Act + var batch = GetRenderedBatch(initializeFromFrames: false); + var newComponents = GetComponents(newTree); + + // Assert: Inserts new component at position 0 + Assert.Equal(1, batch.UpdatedComponents.Count); + Assert.Collection(batch.UpdatedComponents.Array[0].Edits, + entry => AssertEdit(entry, RenderTreeEditType.PrependFrame, 0)); + + // Assert: Retains old component instance in position 1, and updates its params + Assert.Same(oldComponent, newComponents[1]); + Assert.Equal(2, oldComponent.SetParametersCallCount); + } + + [Fact] + public void RecognizesKeyedComponentDeletions() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("will delete"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Anything"); + oldTree.CloseComponent(); + + oldTree.OpenComponent(0); + oldTree.SetKey("will retain"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Retained param value"); + oldTree.CloseComponent(); + + // Instantiate initial components + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); + var oldComponents = GetComponents(oldTree); + + newTree.OpenComponent(0); + newTree.SetKey("will retain"); + newTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Retained param value"); + newTree.CloseComponent(); + + // Without the key, it updates the param on the first component, then + // deletes the second. + // With the key, it just deletes the first. + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + var newComponent = GetComponents(newTree).Single(); + + // Assert + Assert.Same(oldComponents[1], newComponent); + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 0)); + } + + [Fact] + public void RecognizesSimultaneousKeyedComponentInsertionsAndDeletions() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("original key"); + oldTree.CloseComponent(); + + // Instantiate initial component + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); + var oldComponent = GetComponents(oldTree).Single(); + Assert.NotNull(oldComponent); + + newTree.OpenComponent(0); + newTree.SetKey("new key"); + newTree.CloseComponent(); + + // Without the key, it would retain the component + // With the key, it deletes the old component and inserts the new component + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + var newComponent = GetComponents(newTree).Single(); + + // Assert + Assert.NotNull(newComponent); + Assert.NotSame(oldComponent, newComponent); + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("new key", referenceFrames[entry.ReferenceFrameIndex].ComponentKey); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + + [Fact] + public void HandlesClashingKeys_FirstUsage() + { + // This scenario is problematic for the algorithm if it uses a "first key + // usage wins" policy for duplicate keys. It would not end up with attrib1b + // anywhere in the output, because whenever it sees key1 in oldTree, it tries + // to diff against the first usage of key1 in newTree, which has attrib1a. + + // However, because of the actual "duplicated keys are excluded from the + // dictionary match" policy, we don't preserve any of the key1 items, and + // the diff is valid. + + // Arrange + AddWithKey(oldTree, "key3", "attrib3"); + AddWithKey(oldTree, "key1", "attrib1a"); + AddWithKey(oldTree, "key1", "attrib1a"); + AddWithKey(oldTree, "key2", "attrib2"); + + AddWithKey(newTree, "key1", "attrib1a"); + AddWithKey(newTree, "key2", "attrib2"); + AddWithKey(newTree, "key1", "attrib1b"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Insert key1+attrib1a at the top + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 0); + Assert.Equal("attrib1a", referenceFrames[edit.ReferenceFrameIndex + 1].AttributeValue); + }, + // Delete key3+attrib3 + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1), + // Delete key1+attrib1a + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1), + // Delete the other key1+attrib1a + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1), + // Insert key1+attrib1b at the bottom + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 2); + Assert.Equal("attrib1b", referenceFrames[edit.ReferenceFrameIndex + 1].AttributeValue); + }); + } + + [Fact] + public void HandlesClashingKeys_LastUsage() + { + // This scenario is problematic for the algorithm if it uses a "last key + // usage wins" policy for duplicate keys. It would not end up with attrib1b + // anywhere in the output, because when it sees key1 in oldTree, it tries + // to diff against the last usage of key1 in newTree, which has attrib1a. + + // However, because of the actual "duplicated keys are excluded from the + // dictionary match" policy, we don't preserve any of the key1 items, and + // the diff is valid. + + // Arrange + AddWithKey(oldTree, "key1", "attrib1a"); + AddWithKey(oldTree, "key2", "attrib2"); + AddWithKey(oldTree, "key1", "attrib1b"); + + AddWithKey(newTree, "key2", "attrib2"); + AddWithKey(newTree, "key1", "attrib1b"); + AddWithKey(newTree, "key1", "attrib1a"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Delete key1+attrib1a + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 0), + // Insert a new key1+attrib1a at the bottom + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 2); + Assert.Equal("attrib1a", referenceFrames[edit.ReferenceFrameIndex + 1].AttributeValue); + }); + } + + [Fact] + public void HandlesInsertionOfUnkeyedItemsAroundKey() + { + // The fact that the new sequence numbers are descending makes this + // problematic if it prefers matching by sequence over key. + // However, since the policy is to prefer key over sequence, it works OK. + + // Arrange + oldTree.OpenElement(1, "el"); + oldTree.SetKey("some key"); + oldTree.CloseElement(); + + newTree.OpenElement(2, "other"); + newTree.CloseElement(); + + newTree.OpenElement(1, "el"); + newTree.SetKey("some key"); + newTree.CloseElement(); + + newTree.OpenElement(0, "other 2"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 0), + edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 2)); + } + + [Fact] + public void HandlesDeletionOfUnkeyedItemsAroundKey() + { + // The fact that the old sequence numbers are descending makes this + // problematic if it prefers matching by sequence over key. + // However, since the policy is to prefer key over sequence, it works OK. + + // Arrange + oldTree.OpenElement(2, "other"); + oldTree.CloseElement(); + + oldTree.OpenElement(1, "el"); + oldTree.SetKey("some key"); + oldTree.CloseElement(); + + oldTree.OpenElement(0, "other 2"); + oldTree.CloseElement(); + + newTree.OpenElement(1, "el"); + newTree.SetKey("some key"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 0), + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1)); + } + + [Fact] + public void HandlesKeyBeingAdded() + { + // This is an anomolous situation that can't occur with .razor components. + // It represents the case where, for the same sequence number, we have an + // old frame without a key and a new frame with a key. + + // Arrange + oldTree.OpenElement(0, "el"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "el"); + newTree.SetKey("some key"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Insert new + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 0); + Assert.Equal("some key", referenceFrames[edit.ReferenceFrameIndex].ElementKey); + }, + // Delete old + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1)); + } + + [Fact] + public void HandlesKeyBeingRemoved() + { + // This is an anomolous situation that can't occur with .razor components. + // It represents the case where, for the same sequence number, we have an + // old frame with a key and a new frame without a key. + + // Arrange + oldTree.OpenElement(0, "el"); + oldTree.SetKey("some key"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "el"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Insert new + edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 0), + // Delete old + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1)); + } + [Fact] public void RecognizesTrailingSequenceWithinLoopBlockBeingRemoved() { @@ -1492,6 +1903,254 @@ public void DoesNotInvokeAssignerAgainForRetainedComponents() Assert.Empty(referenceFrames); } + [Fact] + public void RecognizesKeyedElementMoves() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("first key"); + oldTree.AddContent(1, "First"); + oldTree.CloseElement(); + + oldTree.AddContent(2, "Unkeyed item"); + + oldTree.OpenElement(0, "container"); + oldTree.SetKey("second key"); + oldTree.AddContent(1, "Second"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("second key"); + newTree.AddContent(1, "Second"); + newTree.CloseElement(); + + newTree.AddContent(2, "Unkeyed item"); + + newTree.OpenElement(0, "container"); + newTree.SetKey("first key"); + newTree.AddContent(1, "First modified"); + newTree.CloseElement(); + + // Without the key, it changes the text contents of both + // With the key, it reorders them and just updates the text content of one + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // First we update the modified descendants in place + entry => AssertEdit(entry, RenderTreeEditType.StepIn, 0), + entry => + { + AssertEdit(entry, RenderTreeEditType.UpdateText, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("First modified", referenceFrames[entry.ReferenceFrameIndex].TextContent); + }, + entry => AssertEdit(entry, RenderTreeEditType.StepOut, 0), + + // Then we have the permutation list + entry => AssertPermutationListEntry(entry, 0, 2), + entry => AssertPermutationListEntry(entry, 2, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void RecognizesKeyedComponentMoves() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("first key"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "First param"); + oldTree.CloseComponent(); + + oldTree.AddContent(2, "Unkeyed item"); + + oldTree.OpenComponent(0); + oldTree.SetKey("second key"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Second param"); + oldTree.CloseComponent(); + + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); // Assign initial IDs + var oldComponents = GetComponents(oldTree); + + newTree.OpenComponent(0); + newTree.SetKey("second key"); + newTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Second param"); + newTree.CloseComponent(); + + newTree.AddContent(2, "Unkeyed item"); + + newTree.OpenComponent(0); + newTree.SetKey("first key"); + newTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "First param modified"); + newTree.CloseComponent(); + + // Without the key, it changes the parameter on both + // With the key, it reorders them and just updates the parameter of one + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + var newComponents = GetComponents(newTree); + + // Assert: Retains component instances + Assert.Same(oldComponents[0], newComponents[1]); + Assert.Same(oldComponents[1], newComponents[0]); + + // Assert: Supplies updated params only to (originally) first component + Assert.Equal(2, oldComponents[0].SetParametersCallCount); + Assert.Equal(1, oldComponents[1].SetParametersCallCount); + + // Assert: Correct diff + Assert.Collection(result.Edits, + entry => AssertPermutationListEntry(entry, 0, 2), + entry => AssertPermutationListEntry(entry, 2, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveBeforeInsertedItem() + { + // Arrange + AddWithKey(oldTree, "will retain"); + AddWithKey(oldTree, "will move"); + + AddWithKey(newTree, "will move"); + AddWithKey(newTree, "newly inserted"); + AddWithKey(newTree, "will retain"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 1); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("newly inserted", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }, + entry => AssertPermutationListEntry(entry, 0, 2), + entry => AssertPermutationListEntry(entry, 2, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveBeforeDeletedItem() + { + // Arrange + AddWithKey(oldTree, "will retain"); + AddWithKey(oldTree, "will delete"); + AddWithKey(oldTree, "will move"); + + AddWithKey(newTree, "will move"); + AddWithKey(newTree, "will retain"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1), + entry => AssertPermutationListEntry(entry, 0, 1), + entry => AssertPermutationListEntry(entry, 1, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveAfterInsertedItem() + { + // Arrange + AddWithKey(oldTree, "will move"); + AddWithKey(oldTree, "will retain"); + + AddWithKey(newTree, "newly inserted"); + AddWithKey(newTree, "will retain"); + AddWithKey(newTree, "will move"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("newly inserted", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }, + entry => AssertPermutationListEntry(entry, 1, 2), + entry => AssertPermutationListEntry(entry, 2, 1), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveAfterDeletedItem() + { + // Arrange + AddWithKey(oldTree, "will move"); + AddWithKey(oldTree, "will delete"); + AddWithKey(oldTree, "will retain"); + + AddWithKey(newTree, "will retain"); + AddWithKey(newTree, "will move"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1), + entry => AssertPermutationListEntry(entry, 0, 1), + entry => AssertPermutationListEntry(entry, 1, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanChangeFrameTypeWithMatchingSequenceNumber() + { + oldTree.OpenElement(0, "some elem"); + oldTree.AddContent(1, "Hello!"); + oldTree.CloseElement(); + + newTree.AddContent(0, "some text"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("some text", referenceFrames[entry.ReferenceFrameIndex].TextContent); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + + [Fact] + public void CanChangeFrameTypeWithMatchingKey() + { + oldTree.OpenComponent(0); + oldTree.CloseComponent(); + + newTree.OpenElement(0, "some elem"); + newTree.SetKey("my key"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("some elem", referenceFrames[entry.ReferenceFrameIndex].ElementName); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + private (RenderTreeDiff, RenderTreeFrame[]) GetSingleUpdatedComponent(bool initializeFromFrames = false) { var result = GetSingleUpdatedComponentWithBatch(initializeFromFrames); @@ -1524,6 +2183,28 @@ private RenderBatch GetRenderedBatch(RenderTreeBuilder from, RenderTreeBuilder t return batchBuilder.ToBatch(); } + private static IList GetComponents(RenderTreeBuilder builder) + => GetComponents(builder); + + private static IList GetComponents(RenderTreeBuilder builder) where T : IComponent + => builder.GetFrames().AsEnumerable() + .Where(x => x.FrameType == RenderTreeFrameType.Component) + .Select(x => (T)x.Component) + .ToList(); + + private static void AddWithKey(RenderTreeBuilder builder, object key, string attributeValue = null) + { + builder.OpenElement(0, "el"); + builder.SetKey(key); + + if (attributeValue != null) + { + builder.AddAttribute(1, "attrib", attributeValue); + } + + builder.CloseElement(); + } + private class FakeRenderer : Renderer { public FakeRenderer() : base(new TestServiceProvider(), new RendererSynchronizationContext()) @@ -1613,5 +2294,15 @@ private static void AssertEdit( Assert.Equal(type, edit.Type); Assert.Equal(siblingIndex, edit.SiblingIndex); } + + private static void AssertPermutationListEntry( + RenderTreeEdit edit, + int fromSiblingIndex, + int toSiblingIndex) + { + Assert.Equal(RenderTreeEditType.PermutationListEntry, edit.Type); + Assert.Equal(fromSiblingIndex, edit.SiblingIndex); + Assert.Equal(toSiblingIndex, edit.MoveToSiblingIndex); + } } } diff --git a/src/Components/Components/test/StackObjectPoolTest.cs b/src/Components/Components/test/StackObjectPoolTest.cs new file mode 100644 index 000000000000..33b9becc0549 --- /dev/null +++ b/src/Components/Components/test/StackObjectPoolTest.cs @@ -0,0 +1,123 @@ +// 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.Linq; +using Xunit; + +namespace Microsoft.AspNetCore.Components.RenderTree +{ + public class StackObjectPoolTest + { + [Fact] + public void CanGetInstances() + { + // Arrange + var stackObjectPool = new StackObjectPool(10, () => new object()); + + // Act + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + + // Assert + Assert.NotNull(instance1); + Assert.NotNull(instance2); + Assert.NotSame(instance1, instance2); + } + + [Fact] + public void CanReturnInstances() + { + // Arrange + var stackObjectPool = new StackObjectPool(10, () => new object()); + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + + // Act/Assert + // No exception means success + stackObjectPool.Return(instance2); + stackObjectPool.Return(instance1); + } + + [Fact] + public void ReusesInstancesInPoolUpToCapacity() + { + // Arrange + var stackObjectPool = new StackObjectPool(10, () => new object()); + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + stackObjectPool.Return(instance2); + stackObjectPool.Return(instance1); + + // Act + var instance1b = stackObjectPool.Get(); + var instance2b = stackObjectPool.Get(); + var instance3 = stackObjectPool.Get(); + + // Assert + Assert.Same(instance1, instance1b); + Assert.Same(instance2, instance2b); + Assert.NotNull(instance3); + Assert.NotSame(instance1, instance3); + Assert.NotSame(instance2, instance3); + } + + [Fact] + public void SuppliesTransientInstancesWhenExceedingCapacity() + { + // Arrange + var stackObjectPool = new StackObjectPool(1, () => new object()); + + // Act 1: Returns distinct instances beyond capacity + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + var instance3 = stackObjectPool.Get(); + Assert.NotNull(instance1); + Assert.NotNull(instance2); + Assert.NotNull(instance3); + Assert.Equal(3, new[] { instance1, instance2, instance3 }.Distinct().Count()); + + // Act 2: Can return all instances, including transient ones + stackObjectPool.Return(instance3); + stackObjectPool.Return(instance2); + stackObjectPool.Return(instance1); + + // Act 3: Reuses only the non-transient instances + var instance1b = stackObjectPool.Get(); + var instance2b = stackObjectPool.Get(); + Assert.Same(instance1, instance1b); + Assert.NotSame(instance2b, instance2); + Assert.Equal(4, new[] { instance1, instance2, instance3, instance2b }.Distinct().Count()); + } + + [Fact] + public void CannotReturnWhenEmpty() + { + // Arrange + var stackObjectPool = new StackObjectPool(10, () => new object()); + + // Act/Assert + var ex = Assert.Throws(() => + { + stackObjectPool.Return(new object()); + }); + Assert.Equal("There are no outstanding instances to return.", ex.Message); + } + + [Fact] + public void CannotReturnMismatchingTrackedItem() + { + // Arrange + var stackObjectPool = new StackObjectPool(10, () => new object()); + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + + // Act/Assert + var ex = Assert.Throws(() => + { + stackObjectPool.Return(instance1); + }); + Assert.Equal("Attempting to return wrong pooled instance. Get/Return calls must form a stack.", ex.Message); + } + } +} diff --git a/src/Components/Server/src/Circuits/RenderBatchWriter.cs b/src/Components/Server/src/Circuits/RenderBatchWriter.cs index 321bef10845f..d66c5de2a5dc 100644 --- a/src/Components/Server/src/Circuits/RenderBatchWriter.cs +++ b/src/Components/Server/src/Circuits/RenderBatchWriter.cs @@ -105,7 +105,11 @@ void Write(in RenderTreeEdit edit) // for this specific RenderTreeEditType. _binaryWriter.Write((int)edit.Type); _binaryWriter.Write(edit.SiblingIndex); + + // ReferenceFrameIndex and MoveToSiblingIndex share a slot, so this writes + // whichever one applies to the edit type _binaryWriter.Write(edit.ReferenceFrameIndex); + WriteString(edit.RemovedAttributeName, allowDeduplication: true); } diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs new file mode 100644 index 000000000000..32f3ad5e3f69 --- /dev/null +++ b/src/Components/test/E2ETest/Tests/KeyTest.cs @@ -0,0 +1,351 @@ +// 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.Linq; +using System.Threading.Tasks; +using BasicTestApp; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; +using Microsoft.AspNetCore.E2ETesting; +using Microsoft.JSInterop; +using OpenQA.Selenium; +using OpenQA.Selenium.Interactions; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Components.E2ETest.Tests +{ + public class KeyTest : BasicTestAppTestBase + { + public KeyTest( + BrowserFixture browserFixture, + ToggleExecutionModeServerFixture serverFixture, + ITestOutputHelper output) + : base(browserFixture, serverFixture, output) + { + } + + protected override void InitializeAsyncCore() + { + // On WebAssembly, page reloads are expensive so skip if possible + Navigate(ServerPathBase, noReload: !_serverFixture.UsingAspNetHost); + } + + [Fact] + public void CanInsert() + { + PerformTest( + before: new[] + { + new Node("orig1", "A"), + new Node("orig2", "B"), + }, + after: new[] + { + new Node("new1", "Inserted before") { IsNew = true }, + new Node("orig1", "A"), + new Node("new2", "Inserted between") { IsNew = true }, + new Node("orig2", "B edited"), + new Node("new3", "Inserted after") { IsNew = true }, + }); + } + + [Fact] + public void CanDelete() + { + PerformTest( + before: new[] + { + new Node("orig1", "A"), // Will delete first + new Node("orig2", "B"), + new Node("orig3", "C"), // Will delete in middle + new Node("orig4", "D"), + new Node("orig5", "E"), // Will delete at end + }, + after: new[] + { + new Node("orig2", "B"), + new Node("orig4", "D edited"), + }); + } + + [Fact] + public void CanInsertUnkeyed() + { + PerformTest( + before: new[] + { + new Node("orig1", "A"), + new Node("orig2", "B"), + }, + after: new[] + { + new Node(null, "Inserted before") { IsNew = true }, + new Node("orig1", "A edited"), + new Node(null, "Inserted between") { IsNew = true }, + new Node("orig2", "B"), + new Node(null, "Inserted after") { IsNew = true }, + }); + } + + [Fact] + public void CanDeleteUnkeyed() + { + PerformTest( + before: new[] + { + new Node(null, "A"), // Will delete first + new Node("orig2", "B"), + new Node(null, "C"), // Will delete in middle + new Node("orig4", "D"), + new Node(null, "E"), // Will delete at end + }, + after: new[] + { + new Node("orig2", "B edited"), + new Node("orig4", "D"), + }); + } + + [Fact] + public void CanReorder() + { + PerformTest( + before: new[] + { + new Node("keyA", "A", + new Node("keyA1", "A1"), + new Node("keyA2", "A2"), + new Node("keyA3", "A3")), + new Node("keyB", "B", + new Node("keyB1", "B1"), + new Node("keyB2", "B2"), + new Node("keyB3", "B3")), + new Node("keyC", "C", + new Node("keyC1", "C1"), + new Node("keyC2", "C2"), + new Node("keyC3", "C3")), + }, + after: new[] + { + // We're implicitly verifying that all the component instances were preserved, + // because we're not marking any with "IsNew = true" + new Node("keyC", "C", // Rotate all three (ABC->CAB) + // Swap first and last + new Node("keyC3", "C3"), + new Node("keyC2", "C2 edited"), + new Node("keyC1", "C1")), + new Node("keyA", "A", + // Swap first two + new Node("keyA2", "A2 edited"), + new Node("keyA1", "A1"), + new Node("keyA3", "A3")), + new Node("keyB", "B edited", + // Swap last two + new Node("keyB1", "B1"), + new Node("keyB3", "B3"), + new Node("keyB2", "B2 edited")), + }); + } + + [Fact] + public void CanReorderInsertDeleteAndEdit_WithAndWithoutKeys() + { + // This test is a complex bundle of many types of changes happening simultaneously + PerformTest( + before: new[] + { + new Node("keyA", "A", + new Node("keyA1", "A1"), + new Node(null, "A2 unkeyed"), + new Node("keyA3", "A3"), + new Node("keyA4", "A4")), + new Node("keyB", "B", + new Node(null, "B1 unkeyed"), + new Node("keyB2", "B2"), + new Node("keyB3", "B3"), + new Node("keyB4", "B4")), + new Node("keyC", "C", + new Node("keyC1", "C1"), + new Node("keyC2", "C2"), + new Node("keyC3", "C3"), + new Node(null, "C4 unkeyed")), + }, + after: new[] + { + // Swapped A and C + new Node("keyC", "C", + // C1-4 were reordered + // C5 was inserted + new Node("keyC5", "C5 inserted") { IsNew = true }, + new Node("keyC2", "C2"), + // C6 was inserted with no key + new Node(null, "C6 unkeyed inserted") { IsNew = true }, + // C1 was edited + new Node("keyC1", "C1 edited"), + new Node("keyC3", "C3") + // C4 unkeyed was deleted + ), + // B was deleted + // D was inserted + new Node("keyD", "D inserted", + new Node("keyB1", "D1") { IsNew = true }, // Matches an old key, but treated as new because we don't move between parents + new Node("keyD2", "D2") { IsNew = true }, + new Node(null, "D3 unkeyed") { IsNew = true }) + { IsNew = true }, + new Node("keyA", "A", + new Node("keyA1", "A1"), + // A2 (unkeyed) was edited + new Node(null, "A2 unkeyed edited"), + new Node("keyA3", "A3"), + // A4 was deleted + // A5 was inserted + new Node("keyA5", "A5 inserted") { IsNew = true }), + }); + } + + [Fact] + public async Task CanRetainFocusWhileMovingTextBox() + { + var appElem = MountTestComponent(); + Func textboxFinder = () => appElem.FindElement(By.CssSelector(".incomplete-items .item-1 input[type=text]")); + var textToType = "Hello this is a long string that should be typed"; + var expectedTextTyped = ""; + + textboxFinder().Clear(); + + // On each keystroke, the boxes will be shuffled. The text will only + // be inserted correctly if focus is retained. + textboxFinder().Click(); + while (textToType.Length > 0) + { + var nextBlockLength = Math.Min(5, textToType.Length); + var nextBlock = textToType.Substring(0, nextBlockLength); + textToType = textToType.Substring(nextBlockLength); + expectedTextTyped += nextBlock; + + // Send keys to whatever has focus + new Actions(Browser).SendKeys(nextBlock).Perform(); + Browser.Equal(expectedTextTyped, () => textboxFinder().GetAttribute("value")); + + // We delay between typings to ensure the events aren't all collapsed into one. + await Task.Delay(100); + } + + // Verify that after all this, we can still move the edited item + // This was broken originally because of unexpected event-handling behavior + // in Chrome (it raised events recursively) + appElem.FindElement( + By.CssSelector(".incomplete-items .item-1 input[type=checkbox]")).Click(); + Browser.Equal(expectedTextTyped, () => appElem + .FindElement(By.CssSelector(".complete-items .item-1 input[type=text]")) + .GetAttribute("value")); + } + + [Fact] + public void CanUpdateCheckboxStateWhileMovingIt() + { + var appElem = MountTestComponent(); + Func checkboxFinder = () => appElem.FindElement(By.CssSelector(".item-2 input[type=checkbox]")); + Func> incompleteItemStates = () => appElem + .FindElements(By.CssSelector(".incomplete-items input[type=checkbox]")) + .Select(elem => elem.Selected); + Func> completeItemStates = () => appElem + .FindElements(By.CssSelector(".complete-items input[type=checkbox]")) + .Select(elem => elem.Selected); + + // Verify initial state + Browser.Equal(new[] { false, false, false, false, false }, incompleteItemStates); + Browser.Equal(Array.Empty(), completeItemStates); + + // Check a box; see it moves and becomes the sole checked item + checkboxFinder().Click(); + Browser.True(() => checkboxFinder().Selected); + Browser.Equal(new[] { false, false, false, false }, incompleteItemStates); + Browser.Equal(new[] { true }, completeItemStates); + + // Also uncheck it; see it moves and becomes unchecked + checkboxFinder().Click(); + Browser.False(() => checkboxFinder().Selected); + Browser.Equal(new[] { false, false, false, false, false }, incompleteItemStates); + Browser.Equal(Array.Empty(), completeItemStates); + } + + private void PerformTest(Node[] before, Node[] after) + { + var rootBefore = new Node(null, "root", before); + var rootAfter = new Node(null, "root", after); + var jsonBefore = Json.Serialize(rootBefore); + var jsonAfter = Json.Serialize(rootAfter); + + var appElem = MountTestComponent(); + var textbox = appElem.FindElement(By.TagName("textarea")); + var updateButton = appElem.FindElement(By.TagName("button")); + + SetTextAreaValueFast(textbox, jsonBefore); + updateButton.Click(); + ValidateRenderedOutput(appElem, rootBefore, validatePreservation: false); + + SetTextAreaValueFast(textbox, jsonAfter); + updateButton.Click(); + ValidateRenderedOutput(appElem, rootAfter, validatePreservation: true); + } + + private static void ValidateRenderedOutput(IWebElement appElem, Node expectedRootNode, bool validatePreservation) + { + var actualRootElem = appElem.FindElement(By.CssSelector(".render-output > .node")); + var actualRootNode = ReadNodeFromDOM(actualRootElem); + AssertNodesEqual(expectedRootNode, actualRootNode, validatePreservation); + } + + private static void AssertNodesEqual(Node expectedRootNode, Node actualRootNode, bool validatePreservation) + { + Assert.Equal(expectedRootNode.Label, actualRootNode.Label); + + if (validatePreservation) + { + Assert.Equal(expectedRootNode.IsNew, actualRootNode.IsNew); + } + + Assert.Collection( + actualRootNode.Children, + expectedRootNode.Children.Select>(expectedChild => + (actualChild => AssertNodesEqual(expectedChild, actualChild, validatePreservation))).ToArray()); + } + + private static Node ReadNodeFromDOM(IWebElement nodeElem) + { + var label = nodeElem.FindElement(By.ClassName("label")).Text; + var childNodes = nodeElem + .FindElements(By.XPath("*[@class='children']/*[@class='node']")); + return new Node(key: null, label, childNodes.Select(ReadNodeFromDOM).ToArray()) + { + IsNew = nodeElem.FindElement(By.ClassName("is-new")).Text == "true" + }; + } + + private void SetTextAreaValueFast(IWebElement textAreaElementWithId, string value) + { + var javascript = (IJavaScriptExecutor)Browser; + javascript.ExecuteScript($"document.getElementById('{textAreaElementWithId.GetAttribute("id")}').value = {Json.Serialize(value)}"); + textAreaElementWithId.SendKeys(" "); // So it fires the change event + } + + class Node + { + public string Key { get; } + public string Label { get; } + public Node[] Children { get; } + public bool IsNew { get; set; } + + public Node(string key, string label, params Node[] children) + { + Key = key; + Label = label; + Children = children ?? Array.Empty(); + } + } + } +} diff --git a/src/Components/test/testassets/BasicTestApp/Index.razor b/src/Components/test/testassets/BasicTestApp/Index.razor index 76c5881080a4..92f8d65b94d7 100644 --- a/src/Components/test/testassets/BasicTestApp/Index.razor +++ b/src/Components/test/testassets/BasicTestApp/Index.razor @@ -50,6 +50,8 @@ + + @if (SelectedComponentType != null) diff --git a/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor b/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor new file mode 100644 index 000000000000..9ef1a5bffae5 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor @@ -0,0 +1,73 @@ +@using Microsoft.JSInterop +
+
+

Model

+ + +
+
+

Output

+ + + +
+
+ + + +@functions { + string modelJson = @"{ + ""label"": ""root"", + ""children"": [ + { + ""key"": ""a"", + ""label"": ""A"", + ""children"": [ + { ""key"": ""a1"", ""label"": ""A1"" }, + { ""key"": ""a2"", ""label"": ""A2"" }, + { ""key"": ""a3"", ""label"": ""A3"" } + ] + }, + { + ""key"": ""b"", + ""label"": ""B"", + ""children"": [ + { ""key"": ""b1"", ""label"": ""B1"" }, + { ""key"": ""b2"", ""label"": ""B2"" }, + { ""key"": ""b3"", ""label"": ""B3"" } + ] + } + ] +}"; + + KeyCasesTreeNode.Node parsedRootNode; + RenderContext renderContext = new RenderContext(); + + protected override void OnInit() + { + Update(); + } + + void Update() + { + renderContext.UpdateCount++; + parsedRootNode = Json.Deserialize(modelJson); + } + + public class RenderContext + { + // This is so the descendants can detect and display whether they are + // newly-instantiated on any given render + public int UpdateCount { get; set; } + } +} diff --git a/src/Components/test/testassets/BasicTestApp/KeyCasesTreeNode.razor b/src/Components/test/testassets/BasicTestApp/KeyCasesTreeNode.razor new file mode 100644 index 000000000000..16ed8de0eb67 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/KeyCasesTreeNode.razor @@ -0,0 +1,53 @@ +
+ @Data.Label +   [ + Instance: @instanceId; + + Is new: + @if (firstCreatedOnUpdateCount == RenderContext.UpdateCount) + { + true + } + else + { + false + } + ] + + @if (Data.Children?.Any() ?? false) + { +
@{ + foreach (var child in Data.Children) + { + if (child.Key != null) + { + + } + else + { + + } + } + }
+ } +
+ +@functions { + public class Node + { + public object Key { get; set; } + public string Label { get; set; } + public List Children { get; set; } + } + + string instanceId = Guid.NewGuid().ToString("D").Substring(0, 6); + int firstCreatedOnUpdateCount; + + [Parameter] Node Data { get; set; } + [CascadingParameter] KeyCasesComponent.RenderContext RenderContext { get; set; } + + protected override void OnInit() + { + firstCreatedOnUpdateCount = RenderContext.UpdateCount; + } +} diff --git a/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor new file mode 100644 index 000000000000..acede2b46572 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor @@ -0,0 +1,55 @@ +

To do

+ +

+ This component will randomly reorder the todo items on each keystroke. + The point of this is to show that focus is correctly preserved even + when items are moved around. Also, by checking the boxes to move items + between the two lists, we show that use of key causes the + form element state to behave as expected. +

+ +
    + @foreach (var item in todoItems.Where(item => !item.IsDone)) + { +
  • + + +
  • + } +
+ +

Done

+ +
    + @foreach (var item in todoItems.Where(item => item.IsDone)) + { +
  • + + +
  • + } +
+ +@functions { + Random rng = new Random(); + TodoItem[] todoItems = new[] + { + new TodoItem { Id = 1, Text = "First" }, + new TodoItem { Id = 2, Text = "Second" }, + new TodoItem { Id = 3, Text = "Third" }, + new TodoItem { Id = 4, Text = "Fourth" }, + new TodoItem { Id = 5, Text = "Fifth" }, + }; + + void Shuffle() + { + todoItems = todoItems.OrderBy(x => rng.Next()).ToArray(); + } + + class TodoItem + { + public int Id { get; set; } + public string Text { get; set; } + public bool IsDone { get; set; } + } +} diff --git a/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj b/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj index 3e79d4f6a18f..aa193e921049 100644 --- a/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj +++ b/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -11,4 +11,3 @@ -