From 997b233635f5f82c7675d7d800e0ab39e4f9a186 Mon Sep 17 00:00:00 2001 From: Erich Barnstedt Date: Thu, 19 Sep 2024 09:45:11 +0200 Subject: [PATCH] Removed CESMII sources again as the NuGets now have the required fixes in it and updated all NuGets. Also updated all apps to .Net 8.0 except the Cloud Lib itself which still has an imcompatibility with .Net 8.0. --- .../CESMII.OpcUa.NodeSetImporter.csproj | 32 - .../IUANodeSetCache.cs | 172 - .../IUANodeSetResolver.cs | 18 - .../ModelNameAndVersion.cs | 91 - .../UANodeSetCacheManager.cs | 226 - .../UANodeSetFileCache.cs | 207 - .../UANodeSetModelExporter.cs | 341 - .../UANodeSetModelImporter.cs | 148 - .../CESMII.OpcUa.NodeSetModel.EF.csproj | 33 - .../DbOpcUaContext.cs | 178 - .../NodeSetModelContext.cs | 315 - CESMII.OpcUa.NodeSetModel.EF/readme.md | 19 - ...SMII.OpcUa.NodeSetModel.Factory.Opc.csproj | 39 - .../DefaultOpcUaContext.cs | 220 - .../DynamicComplexType.cs | 895 -- .../DynamicEncodeableFactory.cs | 126 - .../ExportContext.cs | 22 - .../IOpcUaContext.cs | 46 - .../NodeModelOpcExtensions.cs | 494 - .../NodeModelUtils.cs | 489 - .../NodeSetResolverException.cs | 25 - .../NodeSets/UNECE_to_OPCUA original.csv | 1828 ---- .../NodeSets/UNECE_to_OPCUA.csv | 1828 ---- .../NodesetModelExportOpc.cs | 1086 -- .../NodesetModelFactoryOpc.cs | 1299 --- .../ReferenceComparer.cs | 27 - .../CESMII.OpcUa.NodeSetModel.csproj | 23 - CESMII.OpcUa.NodeSetModel/NodeSetModel.cs | 735 -- .../NodeSetModelExtensions.cs | 69 - .../NodeSetModelVersioning.cs | 110 - CloudLibSync/CloudLibSync.csproj | 8 +- CloudLibSync/Program.cs | 2 +- .../CloudLibSyncAzureFunction.csproj | 10 +- .../Opc.Ua.Cloud.Library.Client.csproj | 12 +- Opc.Ua.CloudLib.Client/UACloudLibClient.cs | 93 +- .../SampleConsoleClient.csproj | 12 +- .../CloudLibClient.Tests.csproj | 12 +- .../CloudLibIntegrationTest.cs | 8 +- Tests/CloudLibClientTests/Integration.cs | 7 +- .../CloudLibClientTests/QueriesAndDownload.cs | 44 +- Tests/CloudLibClientTests/UploadAndIndex.cs | 14 +- UA-CloudLibrary.sln | 32 - .../Manage/DownloadPersonalData.cshtml.cs | 3 +- UACloudLibraryServer/UA-CloudLibrary.csproj | 68 +- .../clipboard-copy-element/package-lock.json | 9686 +++++++++++++++++ 45 files changed, 9795 insertions(+), 11357 deletions(-) delete mode 100644 CESMII.OpcUa.NodeSetImporter/CESMII.OpcUa.NodeSetImporter.csproj delete mode 100644 CESMII.OpcUa.NodeSetImporter/IUANodeSetCache.cs delete mode 100644 CESMII.OpcUa.NodeSetImporter/IUANodeSetResolver.cs delete mode 100644 CESMII.OpcUa.NodeSetImporter/ModelNameAndVersion.cs delete mode 100644 CESMII.OpcUa.NodeSetImporter/UANodeSetCacheManager.cs delete mode 100644 CESMII.OpcUa.NodeSetImporter/UANodeSetFileCache.cs delete mode 100644 CESMII.OpcUa.NodeSetImporter/UANodeSetModelExporter.cs delete mode 100644 CESMII.OpcUa.NodeSetImporter/UANodeSetModelImporter.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.EF/CESMII.OpcUa.NodeSetModel.EF.csproj delete mode 100644 CESMII.OpcUa.NodeSetModel.EF/DbOpcUaContext.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.EF/NodeSetModelContext.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.EF/readme.md delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/CESMII.OpcUa.NodeSetModel.Factory.Opc.csproj delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/DefaultOpcUaContext.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicComplexType.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicEncodeableFactory.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/ExportContext.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/IOpcUaContext.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelOpcExtensions.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelUtils.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSetResolverException.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA original.csv delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA.csv delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelExportOpc.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelFactoryOpc.cs delete mode 100644 CESMII.OpcUa.NodeSetModel.Factory.Opc/ReferenceComparer.cs delete mode 100644 CESMII.OpcUa.NodeSetModel/CESMII.OpcUa.NodeSetModel.csproj delete mode 100644 CESMII.OpcUa.NodeSetModel/NodeSetModel.cs delete mode 100644 CESMII.OpcUa.NodeSetModel/NodeSetModelExtensions.cs delete mode 100644 CESMII.OpcUa.NodeSetModel/NodeSetModelVersioning.cs create mode 100644 UACloudLibraryServer/wwwroot/lib/clipboard-copy-element/package-lock.json diff --git a/CESMII.OpcUa.NodeSetImporter/CESMII.OpcUa.NodeSetImporter.csproj b/CESMII.OpcUa.NodeSetImporter/CESMII.OpcUa.NodeSetImporter.csproj deleted file mode 100644 index 2fe7f72a..00000000 --- a/CESMII.OpcUa.NodeSetImporter/CESMII.OpcUa.NodeSetImporter.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - netstandard2.0;netstandard2.1 - latest - Debug;Release;Staging - true - cesmii.png - 0.1 - Chris Muench, Markus Horstmann - CESMII - - en - OPC UA Node Set Importer: stores nodeset files and their dependencies. - Copyright © 2022 CESMII - BSD-3-Clause - - - - - - - - - - - - - - - - diff --git a/CESMII.OpcUa.NodeSetImporter/IUANodeSetCache.cs b/CESMII.OpcUa.NodeSetImporter/IUANodeSetCache.cs deleted file mode 100644 index 05b6d75a..00000000 --- a/CESMII.OpcUa.NodeSetImporter/IUANodeSetCache.cs +++ /dev/null @@ -1,172 +0,0 @@ -/* Author: Chris Muench, C-Labs - * Last Update: 4/8/2022 - * License: MIT - * - * Some contributions thanks to CESMII – the Smart Manufacturing Institute, 2021 - */ - -using CESMII.OpcUa.NodeSetModel.Factory.Opc; -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Microsoft.Extensions.Logging; -using Opc.Ua.Export; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace CESMII.OpcUa.NodeSetImporter -{ - public interface IUANodeSetCache - { - public bool GetNodeSet(UANodeSetImportResult results, ModelNameAndVersion nameVersion, object TenantID); - public bool AddNodeSet(UANodeSetImportResult results, string nodeSetXml, object TenantID, bool requested); - public string GetRawModelXML(ModelValue model); - public void DeleteNewlyAddedNodeSetsFromCache(UANodeSetImportResult results); - public UANodeSetImportResult FlushCache(); - public ModelValue GetNodeSetByID(string id); - } - - /// - /// Model Value containing all important fast access datapoints of a model - /// - public class ModelValue - { - /// - /// The imported NodeSet - use this in your subsequent code - /// - public UANodeSet NodeSet { get; set; } - public string HeaderComment { get; set; } - /// - /// File Path to the XML file cache of the NodeSet on the Server - /// - public string FilePath { get; set; } - /// - /// List of all Model URI (Namespace) dependencies of the Model - /// - public List Dependencies { get; set; } = new List(); - /// - /// Name and Version of NodeSet - /// - public ModelNameAndVersion NameVersion { get; set; } - /// - /// a Flag telling the consumer that this model was just found and new to this import - /// - public bool NewInThisImport { get; set; } - - /// - /// A flag telling the consumer that this model is one of the explicitly requested nodemodel, even if it already existed - /// - public bool RequestedForThisImport { get; set; } - - public override string ToString() - { - return $"{NameVersion}"; - } - } - - /// - /// Result-Set of this Importer - /// Check "ErrorMessage" for issues during the import such as missing dependencies - /// Check "MissingModels" as a list of Models that could not be resolved - /// - public class UANodeSetImportResult - { - /// - /// Error Message in case the import was not successful or is missing dependencies - /// - public string ErrorMessage { get; set; } = ""; - /// - /// All Imported Models - sorted from least amount of dependencies to most dependencies - /// - public List Models { get; set; } = new List(); - /// - /// List if missing models listed as ModelUri strings - /// - public List MissingModels { get; set; } = new List(); - /// - /// A NodeSet author might add custom "Extensions" to a NodeSet. - /// - public Dictionary Extensions { get; set; } = new Dictionary(); - - - /// - /// Parses Dependencies and creates the Models- and MissingModels collection - /// - /// - /// - /// - /// - /// - /// The ModelValue created or found in the results - public (ModelValue Model, bool Added) AddModelAndDependencies(UANodeSet nodeSet, string headerComment, ModelTableEntry ns, string filePath, bool wasNewFile, ILogger logger = null) - { - NodeModelUtils.FixupNodesetVersionFromMetadata(nodeSet, logger); - bool bAdded = false; - var tModel = GetMatchingOrHigherModel(ns.ModelUri, ns.GetNormalizedPublicationDate(), ns.Version); - if (tModel == null) - { - // Remove any previous models with this ModelUri, as we have found a newer one - if (this.Models.RemoveAll(m => m.NameVersion.ModelUri == ns.ModelUri) > 0) - { - // superceded - } - - tModel = new ModelValue { NodeSet = nodeSet, HeaderComment = headerComment, NameVersion = new ModelNameAndVersion(ns), FilePath = filePath, NewInThisImport = wasNewFile }; - this.Models.Add(tModel); - bAdded = true; - } - if (ns.RequiredModel?.Any() == true) - { - foreach (var tDep in ns.RequiredModel) - { - tModel.Dependencies.Add(tDep.ModelUri); - if (!this.MissingModels.Any(s => s.HasNameAndVersion(tDep.ModelUri, tDep.GetNormalizedPublicationDate(), tDep.Version))) - { - this.MissingModels.Add(new ModelNameAndVersion(tDep)); - } - } - } - return (tModel, bAdded); - } - - private ModelValue GetMatchingOrHigherModel(string modelUri, DateTime? publicationDate, string version) - { - var matchingNodeSetsForUri = this.Models - .Where(s => s.NameVersion.ModelUri == modelUri) - .Select(m => - new NodeSetModel.NodeSetModel - { - ModelUri = m.NameVersion.ModelUri, - PublicationDate = m.NameVersion.PublicationDate, - Version = m.NameVersion.ModelVersion, - CustomState = m, - }); - var matchingNodeSet = NodeSetModel.NodeSetVersionUtils.GetMatchingOrHigherNodeSet(matchingNodeSetsForUri, publicationDate, version); - var tModel = matchingNodeSet?.CustomState as ModelValue; - if (tModel == null && matchingNodeSet != null) - { - throw new InvalidCastException("Internal error: CustomState not preserved"); - } - return tModel; - } - - /// - /// Updates missing dependencies of NodesSets based on all loaded nodsets - /// - /// - public void ResolveDependencies() - { - if (this?.Models?.Count > 0 && this?.MissingModels?.Count > 0) - { - for (int i = this.MissingModels.Count - 1; i >= 0; i--) - { - if (this.Models.Any(s => s.NameVersion.IsNewerOrSame(this.MissingModels[i]))) - { - this.MissingModels.RemoveAt(i); - } - } - } - } - - } - -} diff --git a/CESMII.OpcUa.NodeSetImporter/IUANodeSetResolver.cs b/CESMII.OpcUa.NodeSetImporter/IUANodeSetResolver.cs deleted file mode 100644 index 731151a6..00000000 --- a/CESMII.OpcUa.NodeSetImporter/IUANodeSetResolver.cs +++ /dev/null @@ -1,18 +0,0 @@ -/* Author: Markus Horstmann, C-Labs - * Last Update: 4/13/2022 - * License: MIT - * - * Some contributions thanks to CESMII – the Smart Manufacturing Institute, 2022 - */ - -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; - -namespace CESMII.OpcUa.NodeSetImporter -{ - public interface IUANodeSetResolver - { - Task> ResolveNodeSetsAsync(List missingModels); - } -} diff --git a/CESMII.OpcUa.NodeSetImporter/ModelNameAndVersion.cs b/CESMII.OpcUa.NodeSetImporter/ModelNameAndVersion.cs deleted file mode 100644 index e72eedb4..00000000 --- a/CESMII.OpcUa.NodeSetImporter/ModelNameAndVersion.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* Author: Chris Muench, C-Labs - * Last Update: 4/8/2022 - * License: MIT - * - * Some contributions thanks to CESMII – the Smart Manufacturing Institute, 2021 - */ - -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Opc.Ua.Export; -using System; - -namespace CESMII.OpcUa.NodeSetImporter -{ - /// - /// Simplified class containing all important information of a NodeSet - /// - public class ModelNameAndVersion - { - /// - /// The main Model URI (Namespace) - /// - public string ModelUri { get; set; } - /// - /// Version of the NodeSet - /// - public string ModelVersion { get; set; } - /// - /// Publication date of the NodeSet - /// - public DateTime? PublicationDate { get; set; } - /// - /// This is not a valid OPC UA Field and might be hidden inside the "Extensions" node - not sure if its the best way to add this here - /// - public string Author { get; set; } - /// - /// Set to !=0 if this Model is an official OPC Foundation Model and points to an index in a lookup table or cloudlib id - /// This requires a call to the CloudLib or another Model validation table listing all officially released UA Models - /// - public int? UAStandardModelID { get; set; } - /// - /// Key into the Cache Table - /// - public object CCacheId { get; set; } - - - public ModelNameAndVersion(ModelTableEntry model) - { - ModelUri = model.ModelUri; - ModelVersion = model.Version; - PublicationDate = model.GetNormalizedPublicationDate(); - } - /// - /// Compares two NodeSetNameAndVersion using ModelUri and Version. - /// - /// Compares this to ThanThis - /// - public bool IsNewerOrSame(ModelNameAndVersion thanThis) - { - if (thanThis == null) - return false; - if (ModelUri != thanThis.ModelUri) - { - return false; - } - return NodeSetModel.NodeSetVersionUtils.IsMatchingOrHigherNodeSet(ModelUri, PublicationDate, ModelVersion, thanThis.PublicationDate, thanThis.ModelVersion) ?? false; - } - - /// - /// Compares this NameAndVersion to incoming Name and Version prarameters - /// - /// ModelUri of version - /// Publish Date of NodeSet - /// - public bool HasNameAndVersion(string ofModelUri, DateTime ofPublicationDate, string ofModelVersion) - { - if (string.IsNullOrEmpty(ofModelUri)) - return false; - if (ModelUri != ofModelUri) - { - return false; - } - return NodeSetModel.NodeSetVersionUtils.IsMatchingOrHigherNodeSet(ModelUri, PublicationDate, ModelVersion, ofPublicationDate, ofModelVersion) ?? false; - } - - public override string ToString() - { - string uaStandardIdLabel = UAStandardModelID.HasValue ? $", UA-ID: {UAStandardModelID.Value}" : ""; - return $"{ModelUri} (Version: {ModelVersion}, PubDate: {PublicationDate?.ToShortDateString()}{uaStandardIdLabel})"; - } - } -} diff --git a/CESMII.OpcUa.NodeSetImporter/UANodeSetCacheManager.cs b/CESMII.OpcUa.NodeSetImporter/UANodeSetCacheManager.cs deleted file mode 100644 index 30e3c988..00000000 --- a/CESMII.OpcUa.NodeSetImporter/UANodeSetCacheManager.cs +++ /dev/null @@ -1,226 +0,0 @@ -/* Author: Chris Muench, C-Labs - * Last Update: 4/8/2022 - * License: MIT - * - * Some contributions thanks to CESMII – the Smart Manufacturing Institute, 2021 - */ - -using Opc.Ua.Export; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; - -namespace CESMII.OpcUa.NodeSetImporter -{ - //Glossary of Terms: - //----------------------------------- - //NodeSet - Container File of one or more Models - //Model - a unique OPC UA Model identified with a unique NamespaceUri/ModelUri. A model can be spanned across multiple NodeSet (files) - //Namespace - the unique identifier of a Model (also called ModelUri) - //UAStandardModel - A Model that has been standardized by the OPC UA Foundation and can be found in the official schema store: https://files.opcfoundation.org/schemas/ - //UANodeSetImporter - Imports one or more OPC UA NodeSets resulting in a "NodeSetImportResult" containing all found Models and a list of missing dependencies - - /// - /// Main Importer class importing NodeSets - /// - public class UANodeSetCacheManager - { - - UANodeSetImportResult _results = new(); - private readonly IUANodeSetCache _nodeSetCacheSystem; - private readonly IUANodeSetResolver _nodeSetResolver; - - public UANodeSetCacheManager() - { - _nodeSetCacheSystem = new UANodeSetFileCache(); - _nodeSetResolver = null; - } - public UANodeSetCacheManager(IUANodeSetCache nodeSetCacheSystem) - { - _nodeSetCacheSystem = nodeSetCacheSystem; - _nodeSetResolver = null; - } - public UANodeSetCacheManager(IUANodeSetCache nodeSetCacheSystem, IUANodeSetResolver nodeSetResolver) - { - _nodeSetCacheSystem = nodeSetCacheSystem; - _nodeSetResolver = nodeSetResolver; - } - - /// - /// Imports NodeSets from Files resolving dependencies using already uploaded NodeSets - /// - /// This interface can be used to override the default file cache of the Importer, i.e with a Database cache - /// If null, a new resultset will be created. If not null already uploaded NodeSets can be augmented with New NodeSets referred in the FileNames - /// List of full paths to uploaded NodeSets - /// List of streams containing NodeSets - /// Default behavior is that all Models in NodeSets are returned even if they have been imported before. If set to true, the importer will fail if it has imported a nodeset before and does not cache nodeset if they have missing dependencies - /// If the import has Multi-Tenant Cache, the tenant ID has to be set here - /// - public UANodeSetImportResult ImportNodeSetFiles(List nodeSetFilenames, bool FailOnExisting = false, object TenantID = null) - { - return ImportNodeSets(nodeSetFilenames.Select(f => File.ReadAllText(f)), FailOnExisting, TenantID); - } - /// - /// Imports NodeSets from Files resolving dependencies using already uploaded NodeSets - /// - /// This interface can be used to override the default file cache of the Importer, i.e with a Database cache - /// If null, a new resultset will be created. If not null already uploaded NodeSets can be augmented with New NodeSets referred in the FileNames - /// List of full paths to uploaded NodeSets - /// List of streams containing NodeSets - /// Default behavior is that all Models in NodeSets are returned even if they have been imported before. If set to true, the importer will fail if it has imported a nodeset before and does not cache nodeset if they have missing dependencies - /// If the import has Multi-Tenant Cache, the tenant ID has to be set here - /// - public UANodeSetImportResult ImportNodeSets(IEnumerable nodeSetStreams, bool FailOnExisting = false, object TenantID = null) - { - return ImportNodeSets(nodeSetStreams.Select(s => - { - using (var sr = new StreamReader(s, Encoding.UTF8)) - { - return sr.ReadToEnd(); - } - }), FailOnExisting, TenantID); - } - /// - /// Imports NodeSets from Files resolving dependencies using already uploaded NodeSets - /// - /// This interface can be used to override the default file cache of the Importer, i.e with a Database cache - /// If null, a new resultset will be created. If not null already uploaded NodeSets can be augmented with New NodeSets referred in the FileNames - /// List of full paths to uploaded NodeSets - /// List of streams containing NodeSets - /// Default behavior is that all Models in NodeSets are returned even if they have been imported before. If set to true, the importer will fail if it has imported a nodeset before and does not cache nodeset if they have missing dependencies - /// If the import has Multi-Tenant Cache, the tenant ID has to be set here - /// - public UANodeSetImportResult ImportNodeSets(IEnumerable nodeSetsXml, bool FailOnExisting = false, object TenantID = null) - { - _results.ErrorMessage = ""; - List previousMissingModels = new List(); - try - { - bool rerun; - do - { - rerun = false; - bool NewNodeSetFound = false; - if (nodeSetsXml != null) - { - // Must enumerate the nodeSetsXml only once in case the caller creates/loads strings as needed (streams of files) - foreach (var nodeSetXml in nodeSetsXml) - { - var JustFoundNewNodeSet = _nodeSetCacheSystem.AddNodeSet(_results, nodeSetXml, TenantID, true); - NewNodeSetFound |= JustFoundNewNodeSet; - } - nodeSetsXml = null; - } - - if (!NewNodeSetFound && FailOnExisting) - { - string names = string.Join(", ", _results.Models.Select(m => m.NameVersion)); - _results.ErrorMessage = $"All selected NodeSets or newer versions of them ({names}) have already been imported"; - return _results; - } - if (_results.Models.Count == 0) - { - _results.ErrorMessage = "No Nodesets specified in either nodeSetFilenames or nodeSetStreams"; - return _results; - } - _results.ResolveDependencies(); - - if (_results?.MissingModels?.Any() == true) - { - foreach (var t in _results.MissingModels.ToList()) - { - rerun |= _nodeSetCacheSystem.GetNodeSet(_results, t, TenantID); - } - _results.ResolveDependencies(); - - if (_results.MissingModels.Any()) - { - if (_results.MissingModels.SequenceEqual(previousMissingModels)) - { - rerun = false; - continue; - } - previousMissingModels = _results.MissingModels.ToList(); - // No more cached models were added, but we are still missing models: invoke the resolver if provided - if (_nodeSetResolver != null) - { - try - { - var newNodeSetsXml = _nodeSetResolver.ResolveNodeSetsAsync(_results.MissingModels.ToList()).Result; - if (newNodeSetsXml?.Any() == true) - { - nodeSetsXml = newNodeSetsXml; - rerun = true; - continue; - } - } - catch (Exception ex) - { - if (_results.ErrorMessage.Length > 0) _results.ErrorMessage += ", "; - _results.ErrorMessage += $"Error resolving missing nodesets: {ex.Message}"; - } - } - if (_results.ErrorMessage.Length > 0) _results.ErrorMessage += ", "; - _results.ErrorMessage += string.Join(",", _results.MissingModels); - } - if (!string.IsNullOrEmpty(_results.ErrorMessage)) - { - _results.ErrorMessage = $"The following NodeSets are required: " + _results.ErrorMessage; - //We must delete newly cached models as they need to be imported again into the backend - if (FailOnExisting) - _nodeSetCacheSystem.DeleteNewlyAddedNodeSetsFromCache(_results); - } - } - - _results.Models = OrderByDependencies(_results.Models); // _results.Models.OrderBy(s => s.Dependencies.Count).ToList(); - } while (rerun && _results.MissingModels.Any()); - } - catch (Exception ex) - { - _results.ErrorMessage = ex.Message; - } - - return _results; - } - - static List OrderByDependencies(List models) - { - var remainingModels = new List(models); - var orderedModels = new List(); - - bool modelAdded; - do - { - modelAdded = false; - for (int i = 0; i < remainingModels.Count;) - { - var remainingModel = remainingModels[i]; - bool bDependenciesSatisfied = true; - foreach (var dependency in remainingModel.Dependencies) - { - if (!orderedModels.Any(m => m.NameVersion.ModelUri == dependency)) - { - bDependenciesSatisfied = false; - break; - } - } - if (bDependenciesSatisfied) - { - orderedModels.Add(remainingModel); - remainingModels.RemoveAt(i); - modelAdded = true; - } - else - { - i++; - } - } - } while (remainingModels.Count > 0 && modelAdded); - - orderedModels.AddRange(remainingModels); // Add any remaining models (dependencies not satisfied, not ordered) - return orderedModels; - } - } -} diff --git a/CESMII.OpcUa.NodeSetImporter/UANodeSetFileCache.cs b/CESMII.OpcUa.NodeSetImporter/UANodeSetFileCache.cs deleted file mode 100644 index ccd6ec41..00000000 --- a/CESMII.OpcUa.NodeSetImporter/UANodeSetFileCache.cs +++ /dev/null @@ -1,207 +0,0 @@ -/* Author: Chris Muench, C-Labs - * Last Update: 4/8/2022 - * License: MIT - * - * Some contributions thanks to CESMII – the Smart Manufacturing Institute, 2021 - */ -using CESMII.OpcUa.NodeSetModel; -using CESMII.OpcUa.NodeSetModel.Factory.Opc; -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Opc.Ua.Export; -using System; -using System.IO; -using System.Linq; -using System.Text; - -namespace CESMII.OpcUa.NodeSetImporter -{ - - /// - /// Implementation of File Cache - can be replaced with Database cache if necessary - /// - public class UANodeSetFileCache : IUANodeSetCache - { - public UANodeSetFileCache() - { - RootFolder = Path.Combine(Directory.GetCurrentDirectory(), "NodeSetCache"); - } - - public UANodeSetFileCache(string pRootFolder) - { - RootFolder = pRootFolder; - } - static string RootFolder = null; - /// - /// Not Supported on File Cache - /// - /// - /// - public ModelValue GetNodeSetByID(string id) - { - return null; - } - - /// - /// By default the Imporater caches all imported NodeSets in a directory called "/NodeSets" under the correct bin directory - /// This function can be called to flush this cache (for debugging and development purpose only!) - /// - /// - public UANodeSetImportResult FlushCache() - { - UANodeSetImportResult ret = new UANodeSetImportResult(); - string tPath = Path.Combine(RootFolder, "NodeSets"); - try - { - var tFiles = Directory.GetFiles(tPath); - foreach (var tfile in tFiles) - { - File.Delete(tfile); - } - } - catch (Exception e) - { - ret.ErrorMessage = $"Flushing Cache failed: {e}"; - } - return ret; - } - - /// - /// After the NodeSets were returned by the Importer the succeeding code might fail during processing. - /// This function allows to remove NodeSets from the cache if the succeeding call failed - /// - /// Set to the result-set coming from the ImportNodeSets message to remove newly added NodeSets from the cache - public void DeleteNewlyAddedNodeSetsFromCache(UANodeSetImportResult results) - { - if (results?.Models?.Count > 0) - { - foreach (var tMod in results.Models) - { - if (tMod.NewInThisImport) - File.Delete(tMod.FilePath); - } - } - } - - /// - /// Returns the content of a cached NodeSet - /// - /// - /// - public string GetRawModelXML(ModelValue model) - { - if (!File.Exists(model?.FilePath)) - return null; - return File.ReadAllText(model.FilePath); - } - - /// - /// Loads a NodeSet From File. - /// - /// - /// - public void AddNodeSetFile(UANodeSetImportResult results, string nodesetFileName, object tenantId) - { - if (!File.Exists(nodesetFileName)) - return; - var nodeSetXml = File.ReadAllText(nodesetFileName); - AddNodeSet(results, nodeSetXml, tenantId, false); - } - - public bool GetNodeSet(UANodeSetImportResult results, ModelNameAndVersion nameVersion, object TenantID) - { - //Try to find already uploaded NodeSets using cached NodeSets in the "NodeSets" Folder. - string tFileName = GetCacheFileName(nameVersion, TenantID); - if (File.Exists(tFileName)) - { - AddNodeSetFile(results, tFileName, TenantID); - return true; - } - return false; - } - - private static string GetCacheFileName(ModelNameAndVersion nameVersion, object TenantID) - { - string tPath = Path.Combine(RootFolder, "NodeSets"); - if (!Directory.Exists(tPath)) - Directory.CreateDirectory(tPath); - if (TenantID != null && (int)TenantID > 0) - { - tPath = Path.Combine(tPath, $"{(int)TenantID}"); - if (!Directory.Exists(tPath)) - Directory.CreateDirectory(tPath); - } - string tFile = nameVersion.ModelUri.Replace("http://", ""); - tFile = tFile.Replace('/', '.'); - if (!tFile.EndsWith(".")) tFile += "."; - string filePath = Path.Combine(tPath, $"{tFile}NodeSet2.xml"); - return filePath; - } - - /// - /// Loads NodeSets from a given byte array and saves new NodeSets to the cache - /// - /// - /// - - /// - public bool AddNodeSet(UANodeSetImportResult results, string nodeSetXml, object TenantID, bool requested) - { - bool WasNewSet = false; - // UANodeSet.Read disposes the stream. We need it later on so create a copy - UANodeSet nodeSet; - - // workaround for bug https://github.com/dotnet/runtime/issues/67622 - var patchedXML = nodeSetXml.Replace("", ""); - using (var nodesetBytes = new MemoryStream(Encoding.UTF8.GetBytes(patchedXML))) - { - nodeSet = UANodeSet.Read(nodesetBytes); - } - - #region Comment processing - var headerComment = NodeModelUtils.ReadHeaderComment(patchedXML); - #endregion - - UANodeSet tOldNodeSet = null; - if (nodeSet?.Models == null) - { - results.ErrorMessage = $"No Nodeset found in bytes"; - return false; - } - foreach (var importedModel in nodeSet.Models) - { - //Caching the streams to a "NodeSets" subfolder using the Model Name - //Even though "Models" is an array, most NodeSet files only contain one model. - //In case a NodeSet stream does contain multiple models, the same file will be cached with each Model Name - string filePath = GetCacheFileName(new ModelNameAndVersion(importedModel), TenantID); - - bool CacheNewerVersion = true; - if (File.Exists(filePath)) - { - CacheNewerVersion = false; - using (Stream nodeSetStream = new FileStream(filePath, FileMode.Open)) - { - if (tOldNodeSet == null) - tOldNodeSet = UANodeSet.Read(nodeSetStream); - } - var tOldModel = tOldNodeSet.Models.Where(s => s.ModelUri == importedModel.ModelUri).OrderByDescending(s => s.GetNormalizedPublicationDate()).FirstOrDefault(); - if (tOldModel == null - || NodeSetVersionUtils.CompareNodeSetVersion( - importedModel.ModelUri, - importedModel.GetNormalizedPublicationDate(), importedModel.Version, - tOldModel.GetNormalizedPublicationDate(), tOldModel.Version) > 0) - { - CacheNewerVersion = true; //Cache the new NodeSet if the old (file) did not contain the model or if the version of the new model is greater - } - } - if (CacheNewerVersion) //Cache only newer version - { - File.WriteAllText(filePath, nodeSetXml); - WasNewSet = true; - } - var modelInfo = results.AddModelAndDependencies(nodeSet, headerComment, importedModel, filePath, WasNewSet); - modelInfo.Model.RequestedForThisImport = requested; - } - return WasNewSet; - } - } -} diff --git a/CESMII.OpcUa.NodeSetImporter/UANodeSetModelExporter.cs b/CESMII.OpcUa.NodeSetImporter/UANodeSetModelExporter.cs deleted file mode 100644 index 84e21173..00000000 --- a/CESMII.OpcUa.NodeSetImporter/UANodeSetModelExporter.cs +++ /dev/null @@ -1,341 +0,0 @@ -/* Author: Chris Muench, C-Labs - * Last Update: 4/8/2022 - * License: MIT - * - * Some contributions thanks to CESMII – the Smart Manufacturing Institute, 2021 - */ - -using Opc.Ua.Export; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using CESMII.OpcUa.NodeSetModel.Export.Opc; -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Opc.Ua; -using System.Xml.Serialization; -using System.Xml; -using Microsoft.Extensions.Logging; - -namespace CESMII.OpcUa.NodeSetModel -{ - /// - /// Exporter helper class - /// - public class UANodeSetModelExporter - { - public static string ExportNodeSetAsXml(NodeSetModel nodesetModel, Dictionary nodesetModels, ILogger logger = null, Dictionary aliases = null, bool encodeJsonScalarsAsValue = false) - { - return ExportNodeSetAsXmlAndNodeSet(nodesetModel, nodesetModels, logger, aliases, encodeJsonScalarsAsValue).NodeSetXml; - } - public static (string NodeSetXml, UANodeSet NodeSet) ExportNodeSetAsXmlAndNodeSet(NodeSetModel nodesetModel, Dictionary nodesetModels, ILogger logger = null, Dictionary aliases = null, bool encodeJsonScalarsAsValue = false) - { - var exportedNodeSet = ExportNodeSet(nodesetModel, nodesetModels, logger, aliases, encodeJsonScalarsAsValue: encodeJsonScalarsAsValue); - - string exportedNodeSetXml; - // .Net6 changed the default to no-identation: https://github.com/dotnet/runtime/issues/64885 - using (var ms = new MemoryStream()) - { - using (var writer = new StreamWriter(ms, Encoding.UTF8)) - { - try - { - using (var xmlWriter = XmlWriter.Create(writer, new XmlWriterSettings { Indent = true, })) - { - XmlSerializer serializer = new XmlSerializer(typeof(UANodeSet)); - serializer.Serialize(xmlWriter, exportedNodeSet); - } - } - finally - { - writer.Flush(); - } - } - var xmlBytes = ms.ToArray(); - if (string.IsNullOrEmpty(nodesetModel.HeaderComments)) - { - exportedNodeSetXml = Encoding.UTF8.GetString(xmlBytes); - } - else - { - int secondLineIndex; - for (secondLineIndex = 0; secondLineIndex < xmlBytes.Length; secondLineIndex++) - { - if (xmlBytes[secondLineIndex] == '\r' || xmlBytes[secondLineIndex] == '\n') - { - secondLineIndex++; - if (xmlBytes[secondLineIndex + 1] == '\n') - { - secondLineIndex++; - } - break; - } - } - if (secondLineIndex < xmlBytes.Length - 1) - { - var sb = new StringBuilder(); - sb.Append(Encoding.UTF8.GetString(xmlBytes, 0, secondLineIndex)); - if (nodesetModel.HeaderComments.EndsWith("\r\n")) - { - sb.Append(nodesetModel.HeaderComments); - } - else - { - sb.AppendLine(nodesetModel.HeaderComments); - } - sb.Append(Encoding.UTF8.GetString(xmlBytes, secondLineIndex, xmlBytes.Length - secondLineIndex)); - exportedNodeSetXml = sb.ToString(); - } - else - { - exportedNodeSetXml = Encoding.UTF8.GetString(ms.ToArray()); - } - } - } - return (exportedNodeSetXml, exportedNodeSet); - } - public static UANodeSet ExportNodeSet(NodeSetModel nodeSetModel, Dictionary nodeSetModels, ILogger logger, Dictionary aliases = null, bool encodeJsonScalarsAsValue = false) - { - if (aliases == null) - { - aliases = new(); - } - - var exportedNodeSet = new UANodeSet(); - exportedNodeSet.LastModified = DateTime.UtcNow; - exportedNodeSet.LastModifiedSpecified = true; - - var namespaceUris = nodeSetModel.AllNodesByNodeId.Values.Select(v => v.Namespace).Distinct().ToList(); - - var requiredModels = new List(); - - var context = new ExportContext(logger, nodeSetModels) - { - Aliases = aliases, - ReencodeExtensionsAsJson = true, - EncodeJsonScalarsAsValue = encodeJsonScalarsAsValue, - _nodeIdsUsed = new HashSet(), - _exportedSoFar = new Dictionary(), - }; - - foreach (var nsUri in namespaceUris) - { - context.NamespaceUris.GetIndexOrAppend(nsUri); - } - var items = ExportAllNodes(nodeSetModel, context); - - // remove unused aliases - var usedAliases = aliases.Where(pk => context._nodeIdsUsed.Contains(pk.Key)).ToDictionary(kv => kv.Key, kv => kv.Value); - - // Add aliases for all nodeids from other namespaces: aliases can only be used on references, not on the definitions - var currentNodeSetNamespaceIndex = context.NamespaceUris.GetIndex(nodeSetModel.ModelUri); - bool bAliasesAdded = false; - foreach (var nodeId in context._nodeIdsUsed) - { - var parsedNodeId = NodeId.Parse(nodeId); - if (parsedNodeId.NamespaceIndex != currentNodeSetNamespaceIndex - && !usedAliases.ContainsKey(nodeId)) - { - var namespaceUri = context.NamespaceUris.GetString(parsedNodeId.NamespaceIndex); - var nodeIdWithUri = new ExpandedNodeId(parsedNodeId, namespaceUri).ToString(); - var nodeModel = nodeSetModels.Select(nm => nm.Value.AllNodesByNodeId.TryGetValue(nodeIdWithUri, out var model) ? model : null).FirstOrDefault(n => n != null); - var displayName = nodeModel?.DisplayName?.FirstOrDefault()?.Text; - if (displayName != null && !(nodeModel is InstanceModelBase)) - { - if (!usedAliases.ContainsValue(displayName)) - { - usedAliases.Add(nodeId, displayName); - aliases.Add(nodeId, displayName); - bAliasesAdded = true; - } - else - { - // name collision: number them - int i; - for (i = 1; i < 10000; i++) - { - var numberedDisplayName = $"{displayName}_{i}"; - if (!usedAliases.ContainsValue(numberedDisplayName)) - { - usedAliases.Add(nodeId, numberedDisplayName); - aliases.Add(nodeId, numberedDisplayName); - bAliasesAdded = true; - break; - } - } - if (i >= 10000) - { - - } - } - } - } - } - - var aliasList = usedAliases - .Select(alias => new NodeIdAlias { Alias = alias.Value, Value = alias.Key }) - .OrderBy(kv => GetNodeIdForSorting(kv.Value)) - .ToList(); - exportedNodeSet.Aliases = aliasList.ToArray(); - - if (bAliasesAdded) - { - context._nodeIdsUsed = null; // No need to track anymore - // Re-export with new aliases - items = ExportAllNodes(nodeSetModel, context); - } - - var allNamespaces = context.NamespaceUris.ToArray(); - if (allNamespaces.Length > 1) - { - exportedNodeSet.NamespaceUris = allNamespaces.Where(ns => ns != Namespaces.OpcUa).ToArray(); - } - else - { - exportedNodeSet.NamespaceUris = allNamespaces; - } - - // Export all referenced nodesets to capture any of their dependencies that may not be used in the model being exported - foreach (var otherModel in nodeSetModels.Values.Where(m => m.ModelUri != Namespaces.OpcUa && !namespaceUris.Contains(m.ModelUri))) - { - // Only need to update the namespaces table - context.Aliases = null; - context._nodeIdsUsed = null; - _ = ExportAllNodes(otherModel, context); - } - var allNamespacesIncludingDependencies = context.NamespaceUris.ToArray(); - - foreach (var uaNamespace in allNamespacesIncludingDependencies.Except(namespaceUris)) - { - if (!requiredModels.Any(m => m.ModelUri == uaNamespace)) - { - if (nodeSetModels.TryGetValue(uaNamespace, out var requiredNodeSetModel)) - { - var requiredModel = new ModelTableEntry - { - ModelUri = uaNamespace, - Version = requiredNodeSetModel.Version, - PublicationDate = requiredNodeSetModel.PublicationDate.GetNormalizedPublicationDate(), - PublicationDateSpecified = requiredNodeSetModel.PublicationDate != null, - RolePermissions = null, - AccessRestrictions = 0, - }; - requiredModels.Add(requiredModel); - } - else - { - // The model was not loaded. This can happen if the only reference to the model is in an extension object that only gets parsed but not turned into a node model (Example: onboarding nodeset refernces GDS ns=2;i=1) - var requiredModel = new ModelTableEntry - { - ModelUri = uaNamespace, - }; - requiredModels.Add(requiredModel); - } - } - } - - var model = new ModelTableEntry - { - ModelUri = nodeSetModel.ModelUri, - RequiredModel = requiredModels.ToArray(), - AccessRestrictions = 0, - PublicationDate = nodeSetModel.PublicationDate.GetNormalizedPublicationDate(), - PublicationDateSpecified = nodeSetModel.PublicationDate != null, - RolePermissions = null, - Version = nodeSetModel.Version, - XmlSchemaUri = nodeSetModel.XmlSchemaUri != nodeSetModel.ModelUri ? nodeSetModel.XmlSchemaUri : null - }; - if (exportedNodeSet.Models != null) - { - var models = exportedNodeSet.Models.ToList(); - models.Add(model); - exportedNodeSet.Models = models.ToArray(); - } - else - { - exportedNodeSet.Models = new ModelTableEntry[] { model }; - } - if (exportedNodeSet.Items != null) - { - var newItems = exportedNodeSet.Items.ToList(); - newItems.AddRange(items); - exportedNodeSet.Items = newItems.ToArray(); - } - else - { - exportedNodeSet.Items = items.ToArray(); - } - return exportedNodeSet; - } - - private static string GetNodeIdForSorting(string nodeId) - { - var intIdIndex = nodeId?.IndexOf("i="); - if (intIdIndex >= 0 && int.TryParse(nodeId.Substring(intIdIndex.Value + "i=".Length), out var intIdValue)) - { - return $"{nodeId.Substring(0, intIdIndex.Value)}i={intIdValue:D10}"; - } - return nodeId; - } - - private static List ExportAllNodes(NodeSetModel nodesetModel, ExportContext context) - { - context._exportedSoFar = new Dictionary(); - var itemsOrdered = new List(); - var itemsOrderedSet = new HashSet(); - foreach (var nodeModel in nodesetModel.AllNodesByNodeId.Values - .OrderBy(GetNodeModelSortOrder) - .ThenBy(n => GetNodeIdForSorting(n.NodeId))) - { - var result = NodeModelExportOpc.GetUANode(nodeModel, context); - if (result.ExportedNode != null) - { - if (context._exportedSoFar.TryAdd(result.ExportedNode.NodeId, result.ExportedNode) || !itemsOrderedSet.Contains(result.ExportedNode)) - { - itemsOrdered.Add(result.ExportedNode); - itemsOrderedSet.Add(result.ExportedNode); - } - else - { - if (context._exportedSoFar[result.ExportedNode.NodeId] != result.ExportedNode) - { - - } - } - } - if (result.AdditionalNodes != null) - { - result.AdditionalNodes.ForEach(n => - { - if (context._exportedSoFar.TryAdd(n.NodeId, n) || !itemsOrderedSet.Contains(n)) - { - itemsOrdered.Add(n); - itemsOrderedSet.Add(n); - } - else - { - if (context._exportedSoFar[n.NodeId] != n) - { - - } - - } - }); - } - } - return itemsOrdered; - } - - static int GetNodeModelSortOrder(NodeModel nodeModel) - { - if (nodeModel is ReferenceTypeModel) return 1; - if (nodeModel is DataTypeModel) return 2; - if (nodeModel is ObjectTypeModel) return 3; - if (nodeModel is VariableTypeModel) return 4; - return 5; - } - - - } -} diff --git a/CESMII.OpcUa.NodeSetImporter/UANodeSetModelImporter.cs b/CESMII.OpcUa.NodeSetImporter/UANodeSetModelImporter.cs deleted file mode 100644 index 3aa2a92d..00000000 --- a/CESMII.OpcUa.NodeSetImporter/UANodeSetModelImporter.cs +++ /dev/null @@ -1,148 +0,0 @@ -/* Author: Chris Muench, C-Labs - * Last Update: 4/8/2022 - * License: MIT - * - * Some contributions thanks to CESMII – the Smart Manufacturing Institute, 2021 - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -using CESMII.OpcUa.NodeSetModel.Factory.Opc; -using CESMII.OpcUa.NodeSetImporter; -using Opc.Ua.Export; -using Microsoft.Extensions.Logging; -using Opc.Ua; - -namespace CESMII.OpcUa.NodeSetModel -{ - /// - /// Main Importer class importing NodeSets - /// - public class UANodeSetModelImporter - { - private readonly IUANodeSetCache _nodeSetCache; - private readonly UANodeSetCacheManager _nodeSetCacheManager; - private readonly IOpcUaContext _opcContext; - - public UANodeSetModelImporter(ILogger logger) - { - _opcContext = new DefaultOpcUaContext(logger); - _nodeSetCache = new UANodeSetFileCache(); - _nodeSetCacheManager = new UANodeSetCacheManager(_nodeSetCache); - } - public UANodeSetModelImporter(ILogger logger, IUANodeSetResolver resolver) - { - _opcContext = new DefaultOpcUaContext(logger); - _nodeSetCache = new UANodeSetFileCache(); - _nodeSetCacheManager = new UANodeSetCacheManager(_nodeSetCache, resolver); - } - public UANodeSetModelImporter(IOpcUaContext opcContext) - { - _opcContext = opcContext; - _nodeSetCache = new UANodeSetFileCache(); - _nodeSetCacheManager = new UANodeSetCacheManager(_nodeSetCache); - } - public UANodeSetModelImporter(IOpcUaContext opcContext, IUANodeSetCache nodeSetCache) - { - _opcContext = opcContext; - _nodeSetCache = nodeSetCache; - _nodeSetCacheManager = new UANodeSetCacheManager(_nodeSetCache); - } - public UANodeSetModelImporter(IOpcUaContext opcContext, IUANodeSetCache nodeSetCache, UANodeSetCacheManager nodeSetCacheManager) - { - _opcContext = opcContext; - _nodeSetCache = nodeSetCache; - _nodeSetCacheManager = nodeSetCacheManager; - } - - /// - /// - /// - /// nodeset to be imported. - /// optional identifier to be attached to the nodeset. For use by the application. - /// optional identifier to be used by the nodeSetCache to distinguish between tenants in a multi-tenant system - /// Fail if the nodeset already exists in the nodeSetCache. - /// Fully load all dependent models. Otherwise, dependent types will only be resolved when referenced by a subsequently imported nodeset. - /// - /// - public async Task> ImportNodeSetModelAsync(string nodeSetXML, string identifier = null, object tenantId = null, bool failOnExistingNodeSet = false, bool loadAllDependentModels = false) - { - _opcContext.NamespaceUris.GetIndexOrAppend(Namespaces.OpcUa); - var resolvedNodeSets = _nodeSetCacheManager.ImportNodeSets(new List { nodeSetXML }, failOnExistingNodeSet, tenantId); - if (!string.IsNullOrEmpty(resolvedNodeSets.ErrorMessage)) - { - throw new NodeSetResolverException($"{resolvedNodeSets.ErrorMessage}"); - } - - var firstNewNodeset = resolvedNodeSets.Models.FirstOrDefault(m => m.NewInThisImport || m.RequestedForThisImport); - if (firstNewNodeset?.NodeSet?.NamespaceUris?.Any() == true) - { - // Ensure namespaces are in the context and in proper order - var namespaces = firstNewNodeset.NodeSet.NamespaceUris.ToList(); - if (namespaces[0] != Namespaces.OpcUa) - { - namespaces.Insert(0, Namespaces.OpcUa); - } - namespaces.ForEach(n => _opcContext.NamespaceUris.GetIndexOrAppend(n)); - if (!namespaces.Take(_opcContext.NamespaceUris.Count).SequenceEqual(_opcContext.NamespaceUris.ToArray().Take(namespaces.Count))) - { - throw new Exception($"Namespace table for {firstNewNodeset} is not in the order required by the nodeset."); - } - } - - List allLoadedNodesetModels = new(); - - try - { - foreach (var resolvedModel in resolvedNodeSets.Models) - { - if (loadAllDependentModels || resolvedModel.RequestedForThisImport || resolvedModel.NewInThisImport) - { - List loadedNodesetModels = await LoadNodeSetModelAsync(_opcContext, resolvedModel.NodeSet); - foreach (var nodeSetModel in loadedNodesetModels) - { - nodeSetModel.Identifier = identifier; - nodeSetModel.HeaderComments = resolvedModel.HeaderComment; - if (_opcContext.UseLocalNodeIds) - { - nodeSetModel.NamespaceIndex = _opcContext.NamespaceUris.GetIndex(nodeSetModel.ModelUri); - } - } - allLoadedNodesetModels.AddRange(loadedNodesetModels); - } - else - { - var existingNodeSetModel = _opcContext.GetOrAddNodesetModel(resolvedModel.NodeSet.Models.FirstOrDefault(), false); - - if (existingNodeSetModel == null) - { - throw new ArgumentException($"Required NodeSet {existingNodeSetModel} not in database: Inconsistency between file store and db?"); - } - // Get the node state for required models so that UANodeSet.Import works - _opcContext.ImportUANodeSet(resolvedModel.NodeSet); - } - } - } - catch - { - _nodeSetCache.DeleteNewlyAddedNodeSetsFromCache(resolvedNodeSets); - throw; - } - return allLoadedNodesetModels; - } - - /// - /// Loads a nodeset into the opcContext, without requiring cache. All dependent nodesets must be loaded previously (or their nodestates must be populated using _opcContext.ImportUANodeSet if only actually referenced types from those nodesets are required) - /// - /// - /// - /// - public async Task> LoadNodeSetModelAsync(IOpcUaContext opcContext, UANodeSet nodeSet) - { - return await NodeModelFactoryOpc.LoadNodeSetAsync(opcContext, nodeSet, null, new Dictionary(), true); - } - } -} diff --git a/CESMII.OpcUa.NodeSetModel.EF/CESMII.OpcUa.NodeSetModel.EF.csproj b/CESMII.OpcUa.NodeSetModel.EF/CESMII.OpcUa.NodeSetModel.EF.csproj deleted file mode 100644 index ddcfbc65..00000000 --- a/CESMII.OpcUa.NodeSetModel.EF/CESMII.OpcUa.NodeSetModel.EF.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - net6.0 - Debug;Release;Staging - true - cesmii.png - 0.1 - Markus Horstmann - CESMII - - en - OPC UA Node Set Model mapping for Entity Framework - Copyright © 2022 CESMII - BSD-3-Clause - - - - - - - - - - - - - - - - - - diff --git a/CESMII.OpcUa.NodeSetModel.EF/DbOpcUaContext.cs b/CESMII.OpcUa.NodeSetModel.EF/DbOpcUaContext.cs deleted file mode 100644 index 4a1418cc..00000000 --- a/CESMII.OpcUa.NodeSetModel.EF/DbOpcUaContext.cs +++ /dev/null @@ -1,178 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2022 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using CESMII.OpcUa.NodeSetModel; -using CESMII.OpcUa.NodeSetModel.Factory.Opc; -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using Opc.Ua; -using Opc.Ua.Export; - -namespace CESMII.OpcUa.NodeSetModel.EF -{ - public class DbOpcUaContext : DefaultOpcUaContext - { - protected DbContext _dbContext; - protected Func _nodeSetFactory; - protected List<(string ModelUri, DateTime? PublicationDate)> _namespacesInDb; - - public DbOpcUaContext(DbContext appDbContext, ILogger logger, Func nodeSetFactory = null) - : base(logger) - { - this._dbContext = appDbContext; - this._nodeSetFactory = nodeSetFactory; - // Get all namespaces with at least one node: used for avoiding DB lookups - this._namespacesInDb = _dbContext.Set().Select(nm => new { nm.NodeSet.ModelUri, nm.NodeSet.PublicationDate }).Distinct().AsEnumerable().Select(n => (n.ModelUri, n.PublicationDate)).ToList(); - } - public DbOpcUaContext(DbContext appDbContext, SystemContext systemContext, NodeStateCollection importedNodes, Dictionary nodesetModels, ILogger logger, Func nodeSetFactory = null) - : base(systemContext, importedNodes, nodesetModels, logger) - { - this._dbContext = appDbContext; - this._nodeSetFactory = nodeSetFactory; - } - - public override TNodeModel GetModelForNode(string nodeId) - { - var model = base.GetModelForNode(nodeId); - if (model != null) return model; - - var uaNamespace = NodeModelUtils.GetNamespaceFromNodeId(nodeId); - NodeModel nodeModelDb; - if (_nodesetModels.TryGetValue(uaNamespace, out var nodeSet)) - { - if (!_namespacesInDb.Contains((nodeSet.ModelUri, nodeSet.PublicationDate))) - { - // namespace was not in DB when the context was created: assume it's being imported - return null; - } - else - { - // Preexisting namespace: find an entity if already in EF cache - int retryCount = 0; - bool lookedUp = false; - do - { - try - { - nodeModelDb = _dbContext.Set().Local.FirstOrDefault(nm => nm.NodeId == nodeId && nm.NodeSet.ModelUri == nodeSet.ModelUri && nm.NodeSet.PublicationDate == nodeSet.PublicationDate); - lookedUp = true; - } - catch (InvalidOperationException) - { - // re-try in case the NodeSet access caused a database query that modified the local cache - nodeModelDb = null; - } - retryCount++; - } while (!lookedUp && retryCount < 100); - if (nodeModelDb == null) - { - // Not in EF cache: assume it's in the database and attach a proxy with just primary key values - // This avoids a database lookup for each referenced node (or the need to pre-fetch all nodes in the EF cache) - nodeModelDb = _dbContext.CreateProxy(nm => - { - nm.NodeSet = nodeSet; - nm.NodeId = nodeId; - } - ); - _dbContext.Attach(nodeModelDb); - } - } - nodeModelDb?.NodeSet.AllNodesByNodeId.Add(nodeModelDb.NodeId, nodeModelDb); - } - else - { - nodeModelDb = _dbContext.Set().FirstOrDefault(nm => nm.NodeId == nodeId && nm.NodeSet.ModelUri == uaNamespace); - if (nodeModelDb != null) - { - nodeSet = GetOrAddNodesetModel(new ModelTableEntry { ModelUri = nodeModelDb.NodeSet.ModelUri, PublicationDate = nodeModelDb.NodeSet.PublicationDate ?? DateTime.MinValue, PublicationDateSpecified = nodeModelDb.NodeSet.PublicationDate != null }); - nodeModelDb?.NodeSet.AllNodesByNodeId.Add(nodeModelDb.NodeId, nodeModelDb); - } - } - if (!(nodeModelDb is TNodeModel)) - { - _logger.LogWarning($"Nodemodel {nodeModelDb} is of type {nodeModelDb.GetType()} when type {typeof(TNodeModel)} was requested. Returning null."); - } - return nodeModelDb as TNodeModel; - } - - public override NodeSetModel GetOrAddNodesetModel(ModelTableEntry model, bool createNew = true) - { - if (!_nodesetModels.TryGetValue(model.ModelUri, out var nodesetModel)) - { - var existingNodeSet = GetMatchingOrHigherNodeSetAsync(model.ModelUri, model.GetNormalizedPublicationDate(), model.Version).Result; - if (existingNodeSet != null) - { - _nodesetModels.Add(existingNodeSet.ModelUri, existingNodeSet); - nodesetModel = existingNodeSet; - } - } - if (nodesetModel == null && createNew) - { - if (_nodeSetFactory == null) - { - nodesetModel = base.GetOrAddNodesetModel(model, createNew); - if (nodesetModel.PublicationDate == null) - { - // Primary Key value can not be null - nodesetModel.PublicationDate = DateTime.MinValue; - } - } - else - { - nodesetModel = _nodeSetFactory.Invoke(model); - if (nodesetModel != null) - { - if (nodesetModel.ModelUri != model.ModelUri) - { - throw new ArgumentException($"Created mismatching nodeset: expected {model.ModelUri} created {nodesetModel.ModelUri}"); - } - _nodesetModels.Add(nodesetModel.ModelUri, nodesetModel); - } - } - } - return nodesetModel; - } - - public Task GetMatchingOrHigherNodeSetAsync(string modelUri, DateTime? publicationDate, string version) - { - return GetMatchingOrHigherNodeSetAsync(_dbContext, modelUri, publicationDate, version); - } - public static async Task GetMatchingOrHigherNodeSetAsync(DbContext dbContext, string modelUri, DateTime? publicationDate, string version) - { - var matchingNodeSets = await dbContext.Set() - .Where(nsm => nsm.ModelUri == modelUri).ToListAsync(); - return NodeSetVersionUtils.GetMatchingOrHigherNodeSet(matchingNodeSets, publicationDate, version); - } - } -} diff --git a/CESMII.OpcUa.NodeSetModel.EF/NodeSetModelContext.cs b/CESMII.OpcUa.NodeSetModel.EF/NodeSetModelContext.cs deleted file mode 100644 index bb7c0f63..00000000 --- a/CESMII.OpcUa.NodeSetModel.EF/NodeSetModelContext.cs +++ /dev/null @@ -1,315 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq.Expressions; - -namespace CESMII.OpcUa.NodeSetModel.EF -{ - public class NodeSetModelContext : DbContext - { - protected bool CascadeDelete { get; set; } - public NodeSetModelContext(DbContextOptions options) : base(options) - { - // Blank - } - - protected NodeSetModelContext(DbContextOptions options) - { - // Blank - } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder - .UseLazyLoadingProxies() - ; - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - CreateModel(modelBuilder, CascadeDelete); - - } - public static void CreateModel(ModelBuilder modelBuilder, bool cascadeDelete = false, bool methodArgs = false) - { - modelBuilder.Owned(); - modelBuilder.Owned(); - modelBuilder.Owned(); - modelBuilder.Owned(); - modelBuilder.Owned(); - modelBuilder.Owned(); - - modelBuilder.Entity() - .ToTable("NodeSets") - .Ignore(nsm => nsm.AllNodesByNodeId) - .Ignore(nsm => nsm.CustomState) - .Ignore(nm => nm.NamespaceIndex) - .HasKey(nsm => new { nsm.ModelUri, nsm.PublicationDate }) - ; - var rmb = modelBuilder.Entity() - .OwnsMany(nsm => nsm.RequiredModels) - ; - rmb.WithOwner() - .HasForeignKey("DependentModelUri", "DependentPublicationDate"); - if (cascadeDelete) - { - rmb.HasOne(rm => rm.AvailableModel).WithMany() - .OnDelete(DeleteBehavior.SetNull); - } - modelBuilder.Entity() - .Ignore(nm => nm.CustomState) - .Ignore(nm => nm.ReferencesNotResolved) - .Property("NodeSetPublicationDate") // EF tooling does not properly infer the type of this auto-generated property when using it in a foreign key: workaround declare explcitly - ; - modelBuilder.Entity() - .ToTable("Nodes") - // This syntax is not supported by EF: use without typing - //.HasKey(nm => new { nm.NodeId, nm.NodeSet.ModelUri, nm.NodeSet.PublicationDate }) - .HasKey( - nameof(NodeModel.NodeId), - $"{nameof(NodeModel.NodeSet)}{nameof(NodeSetModel.ModelUri)}",// Foreign key with auto-generated PK of the NodeModel.NodeSet property - $"{nameof(NodeModel.NodeSet)}{nameof(NodeSetModel.PublicationDate)}") - ; - modelBuilder.Entity() - .ToTable("ObjectTypes") - ; - var dtm = modelBuilder.Entity() - .ToTable("DataTypes"); - if (cascadeDelete) - { - dtm.OwnsMany(dt => dt.StructureFields) - .HasOne(sf => sf.DataType).WithMany().OnDelete(DeleteBehavior.Cascade) - ; - } - var vtm = modelBuilder.Entity() - .ToTable("VariableTypes") - ; - if (cascadeDelete) - { - vtm.HasOne(vt => vt.DataType).WithMany().OnDelete(DeleteBehavior.Cascade); - } - var dvmParentFk = modelBuilder.Entity() - .ToTable("DataVariables") - .HasOne(dv => dv.Parent).WithMany() - .HasForeignKey("ParentNodeId", "ParentModelUri", "ParentPublicationDate") - ; - if (cascadeDelete) - { - dvmParentFk.OnDelete(DeleteBehavior.Cascade); - } - - var pmParentFk = modelBuilder.Entity() - .ToTable("Properties") - .HasOne(dv => dv.Parent).WithMany() - .HasForeignKey("ParentNodeId", "ParentModelUri", "ParentPublicationDate") - ; - if (cascadeDelete) - { - pmParentFk.OnDelete(DeleteBehavior.Cascade); - } - var omTd = modelBuilder.Entity() - .ToTable("Objects") - .HasOne(o => o.TypeDefinition).WithMany() - ; - if (cascadeDelete) - { - omTd.OnDelete(DeleteBehavior.Cascade); - } - var omParentFk = modelBuilder.Entity() - .HasOne(dv => dv.Parent).WithMany() - .HasForeignKey("ParentNodeId", "ParentModelUri", "ParentPublicationDate") - ; - if (cascadeDelete) - { - omParentFk.OnDelete(DeleteBehavior.Cascade); - } - modelBuilder.Entity() - .ToTable("Interfaces") - ; - modelBuilder.Entity() - .ToTable("Variables") - .OwnsOne(v => v.EngineeringUnit).Property(v => v.NamespaceUri).IsRequired() - ; - if (cascadeDelete) - { - modelBuilder.Entity() - .HasOne(vm => vm.DataType).WithMany().OnDelete(DeleteBehavior.Cascade); - modelBuilder.Entity() - .HasOne(vm => vm.TypeDefinition).WithMany().OnDelete(DeleteBehavior.Cascade); - } - var btmSt = modelBuilder.Entity() - .ToTable("BaseTypes") - .HasOne(bt => bt.SuperType).WithMany(bt => bt.SubTypes) - ; - if (cascadeDelete) - { - btmSt.OnDelete(DeleteBehavior.Cascade); - } - modelBuilder.Entity() - .ToTable("DataTypes"); - modelBuilder.Entity() - .ToTable("ObjectTypes"); - modelBuilder.Entity() - .ToTable("Interfaces"); - modelBuilder.Entity() - .ToTable("VariableTypes"); - modelBuilder.Entity() - .ToTable("ReferenceTypes"); - - if (!methodArgs) - { - modelBuilder.Entity() - .Ignore(m => m.InputArguments) - .Ignore(m => m.OutputArguments); - } - var mmParentFk = modelBuilder.Entity() - .ToTable("Methods") - .HasOne(dv => dv.Parent).WithMany() - .HasForeignKey("ParentNodeId", "ParentModelUri", "ParentPublicationDate") - ; - if (cascadeDelete) - { - mmParentFk.OnDelete(DeleteBehavior.Cascade); - } - if (cascadeDelete) - { - modelBuilder.Entity() - .HasOne(mm => mm.TypeDefinition).WithMany().OnDelete(DeleteBehavior.Cascade); - } - modelBuilder.Entity() - .ToTable("ReferenceTypes") - ; - - #region NodeSetModel collections - DeclareNodeSetCollection(modelBuilder, nsm => nsm.ObjectTypes, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.VariableTypes, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.DataTypes, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.ReferenceTypes, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.Objects, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.Methods, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.Interfaces, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.Properties, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.DataVariables, cascadeDelete); - DeclareNodeSetCollection(modelBuilder, nsm => nsm.UnknownNodes, cascadeDelete); - #endregion - - #region NodeModel collections - // Unclear why these collection require declarations while the others just work - modelBuilder.Entity() - .HasMany(dv => dv.NodesWithDataVariables).WithMany(nm => nm.DataVariables); - modelBuilder.Entity() - .HasMany(nm => nm.Properties).WithMany(v => v.NodesWithProperties); - modelBuilder.Entity() - .HasMany(nm => nm.Interfaces).WithMany(v => v.NodesWithInterface); - - #endregion - - { - var orn = modelBuilder.Entity() - .OwnsMany(nm => nm.OtherReferencedNodes) - ; - orn.WithOwner() - .HasForeignKey("OwnerNodeId", "OwnerModelUri", "OwnerPublicationDate") - ; - orn.Property("ReferencedNodeId"); - orn.Property("ReferencedModelUri"); - orn.Property("ReferencedPublicationDate"); - var ornFK = orn.HasOne(nr => nr.Node).WithMany() - .HasForeignKey("ReferencedNodeId", "ReferencedModelUri", "ReferencedPublicationDate") - ; - if (cascadeDelete) - { - ornFK.OnDelete(DeleteBehavior.Cascade); - } - orn.Property("OwnerNodeId"); - orn.Property("OwnerModelUri"); - orn.Property("OwnerPublicationDate"); - - //orn.Ignore(nr => nr.ReferenceType); - orn.Property("ReferenceTypeNodeId"); - orn.Property("ReferenceTypeModelUri"); - orn.Property("ReferenceTypePublicationDate"); - //orn.Property(nr => nr.ReferenceType) - // .HasConversion() - // //.HasColumnType(typeof(NodeModel).FullName) - // //.HasColumnType(typeof(NodeModel).FullName) - // ; - var ornRTFK = orn.HasOne(nr => nr.ReferenceType).WithMany() - .HasForeignKey("ReferenceTypeNodeId", "ReferenceTypeModelUri", "ReferenceTypePublicationDate") - //.HasPrincipalKey("NodeId", "ModelUri", "PublicationDate") - ; - if (cascadeDelete) - { - ornRTFK.OnDelete(DeleteBehavior.Cascade); - } - } - { - var orn = modelBuilder.Entity() - .OwnsMany(nm => nm.OtherReferencingNodes) - ; - orn.WithOwner() - .HasForeignKey("OwnerNodeId", "OwnerModelUri", "OwnerPublicationDate") - ; - orn.Property("ReferencingNodeId"); - orn.Property("ReferencingModelUri"); - orn.Property("ReferencingPublicationDate"); - var ornFK = orn.HasOne(nr => nr.Node).WithMany() - .HasForeignKey("ReferencingNodeId", "ReferencingModelUri", "ReferencingPublicationDate") - ; - if (cascadeDelete) - { - ornFK.OnDelete(DeleteBehavior.Cascade); - } - orn.Property("OwnerNodeId"); - orn.Property("OwnerModelUri"); - orn.Property("OwnerPublicationDate"); - - orn.Property("ReferenceTypeNodeId"); - orn.Property("ReferenceTypeModelUri"); - orn.Property("ReferenceTypePublicationDate"); - // TODO figure out why this does not work if ReferenceType is declared as ReferenceTypeModel instead of NodeModel - //orn.Property(nr => nr.ReferenceType) - // .HasConversion() - // //.HasColumnType(typeof(NodeModel).FullName) - // //.HasColumnType(typeof(NodeModel).FullName) - // ; - var ornRTFK = orn.HasOne(nr => nr.ReferenceType).WithMany() - .HasForeignKey("ReferenceTypeNodeId", "ReferenceTypeModelUri", "ReferenceTypePublicationDate") - ; - if (cascadeDelete) - { - ornRTFK.OnDelete(DeleteBehavior.Cascade); - } - - } - } - - private static void DeclareNodeSetCollection(ModelBuilder modelBuilder, Expression>> collection, bool cascadeDelete) where TEntity : NodeModel - { - var collectionName = (collection.Body as MemberExpression).Member.Name; - var modelProp = $"NodeSet{collectionName}ModelUri"; - var pubDateProp = $"NodeSet{collectionName}PublicationDate"; - modelBuilder.Entity().Property(modelProp); - modelBuilder.Entity().Property(pubDateProp); - var propFK = modelBuilder.Entity().HasOne("CESMII.OpcUa.NodeSetModel.NodeSetModel", null) - .WithMany(collectionName) - .HasForeignKey(modelProp, pubDateProp); - if (cascadeDelete) - { - propFK.OnDelete(DeleteBehavior.Cascade); - } - // With this typed declaration the custom property names are not picked up for some reason - //modelBuilder.Entity() - // .HasOne(nm => nm.NodeSet).WithMany(collection) - // .HasForeignKey(modelProp, pubDateProp) - // ; - //modelBuilder.Entity() - // .HasMany(collection).WithOne(nm => nm.NodeSet) - // .HasForeignKey(modelProp, pubDateProp) - // ; - } - - public DbSet NodeSets { get; set; } - public DbSet NodeModels { get; set; } - } - -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel.EF/readme.md b/CESMII.OpcUa.NodeSetModel.EF/readme.md deleted file mode 100644 index d8de03e3..00000000 --- a/CESMII.OpcUa.NodeSetModel.EF/readme.md +++ /dev/null @@ -1,19 +0,0 @@ -Install tools into project: -``` -cd ProfileDesigner\api\CESMIINodeSetUtilities -dotnet tool install --global dotnet-ef -dotnet tool update --global dotnet-ef -``` -Create migration/database schema -``` -dotnet ef migrations add InitialCreate --context NodeSetModelContext -dotnet ef database update --context NodeSetModelContext -``` - -Recreate database: -``` -del .\Migrations\* -dotnet ef migrations add InitialCreate --context NodeSetModelContext -dotnet ef database drop --context NodeSetModelContext -dotnet ef database update --context NodeSetModelContext -``` diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/CESMII.OpcUa.NodeSetModel.Factory.Opc.csproj b/CESMII.OpcUa.NodeSetModel.Factory.Opc/CESMII.OpcUa.NodeSetModel.Factory.Opc.csproj deleted file mode 100644 index 9b39eea9..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/CESMII.OpcUa.NodeSetModel.Factory.Opc.csproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - netstandard2.0;netstandard2.1 - Debug;Release;Staging - latest - true - cesmii.png - 0.1 - Markus Horstmann - CESMII - - en - OPC UA Node Set Model factory: creates a Node Set Model from an OPC UA node set file. - Copyright © 2022 CESMII - BSD-3-Clause - - - - - - - - - - - - - - - - - - - Never - - - - diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/DefaultOpcUaContext.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/DefaultOpcUaContext.cs deleted file mode 100644 index 15fbd370..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/DefaultOpcUaContext.cs +++ /dev/null @@ -1,220 +0,0 @@ -using Opc.Ua; - -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Logging; -using Opc.Ua.Export; -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using CESMII.OpcUa.NodeSetModel.Export.Opc; -using Microsoft.Extensions.Logging.Abstractions; - -namespace CESMII.OpcUa.NodeSetModel.Factory.Opc -{ - public class DefaultOpcUaContext : IOpcUaContext - { - private readonly ISystemContext _systemContext; - private readonly NodeStateCollection _importedNodes; - protected readonly Dictionary _nodesetModels; - protected readonly ILogger _logger; - - public DefaultOpcUaContext(ILogger logger) - { - _importedNodes = new NodeStateCollection(); - _nodesetModels = new Dictionary(); - _logger = logger ?? NullLogger.Instance; - - var namespaceTable = new NamespaceTable(); - namespaceTable.GetIndexOrAppend(Namespaces.OpcUa); - var typeTable = new TypeTable(namespaceTable); - _systemContext = new SystemContext() - { - NamespaceUris = namespaceTable, - TypeTable = typeTable, - EncodeableFactory = new DynamicEncodeableFactory(EncodeableFactory.GlobalFactory), - }; - } - - public DefaultOpcUaContext(Dictionary nodesetModels, ILogger logger) : this(logger) - { - _nodesetModels = nodesetModels; - _logger = logger ?? NullLogger.Instance; - } - public DefaultOpcUaContext(ISystemContext systemContext, NodeStateCollection importedNodes, Dictionary nodesetModels, ILogger logger) - : this(nodesetModels, logger) - { - _systemContext = systemContext; - _importedNodes = importedNodes; - } - - public bool ReencodeExtensionsAsJson { get; set; } - public bool EncodeJsonScalarsAsValue { get; set; } - - private Dictionary _importedNodesByNodeId; - private Dictionary _importedUANodeSetsByUri = new(); - - public NamespaceTable NamespaceUris { get => _systemContext.NamespaceUris; } - - public ILogger Logger => _logger; - - public bool UseLocalNodeIds { get; set; } - public Dictionary NodeSetModels => _nodesetModels; - - public virtual string GetModelNodeId(NodeId nodeId) - { - string namespaceUri; - namespaceUri = GetNamespaceUri(nodeId.NamespaceIndex); - if (string.IsNullOrEmpty(namespaceUri)) - { - throw ServiceResultException.Create(StatusCodes.BadNodeIdInvalid, "Namespace Index ({0}) for node id {1} is not in the namespace table.", nodeId.NamespaceIndex, nodeId); - } - if (UseLocalNodeIds) - { - return nodeId.ToString(); - } - var nodeIdWithUri = new ExpandedNodeId(nodeId, namespaceUri).ToString(); - return nodeIdWithUri; - } - - public virtual NodeState GetNode(ExpandedNodeId expandedNodeId) - { - var nodeId = ExpandedNodeId.ToNodeId(expandedNodeId, _systemContext.NamespaceUris); - return GetNode(nodeId); - } - - public virtual NodeState GetNode(NodeId nodeId) - { - _importedNodesByNodeId ??= _importedNodes.ToDictionary(n => n.NodeId); - NodeState nodeStateDict = null; - if (nodeId != null) - { - _importedNodesByNodeId.TryGetValue(nodeId, out nodeStateDict); - } - return nodeStateDict; - } - - public virtual string GetNamespaceUri(ushort namespaceIndex) - { - return _systemContext.NamespaceUris.GetString(namespaceIndex); - } - - public virtual TNodeModel GetModelForNode(string nodeId) where TNodeModel : NodeModel - { - foreach (var nodeSetModel in _nodesetModels.Values) - { - if (nodeSetModel.AllNodesByNodeId.TryGetValue(nodeId, out var nodeModel)) - { - var result = nodeModel as TNodeModel; - return result; - } - } - return null; - } - - public virtual NodeSetModel GetOrAddNodesetModel(ModelTableEntry model, bool createNew = true) - { - if (!_nodesetModels.TryGetValue(model.ModelUri, out var nodesetModel)) - { - nodesetModel = new NodeSetModel(); - nodesetModel.ModelUri = model.ModelUri; - nodesetModel.PublicationDate = model.GetNormalizedPublicationDate(); - nodesetModel.Version = model.Version; - if (!string.IsNullOrEmpty(model.XmlSchemaUri)) - { - nodesetModel.XmlSchemaUri = model.XmlSchemaUri; - } - if (UseLocalNodeIds) - { - nodesetModel.NamespaceIndex = NamespaceUris.GetIndexOrAppend(nodesetModel.ModelUri); - } - if (model.RequiredModel != null) - { - foreach (var requiredModel in model.RequiredModel) - { - var existingNodeSet = GetOrAddNodesetModel(requiredModel); - var requiredModelInfo = new RequiredModelInfo - { - ModelUri = requiredModel.ModelUri, - PublicationDate = requiredModel.GetNormalizedPublicationDate(), - Version = requiredModel.Version, - AvailableModel = existingNodeSet, - }; - nodesetModel.RequiredModels.Add(requiredModelInfo); - } - } - _nodesetModels.Add(nodesetModel.ModelUri, nodesetModel); - } - return nodesetModel; - } - - public virtual List ImportUANodeSet(UANodeSet nodeSet) - { - var previousNodes = _importedNodes.ToList(); - if (nodeSet.Items?.Any() == true) - { - nodeSet.Import(_systemContext, _importedNodes); - } - var newlyImportedNodes = _importedNodes.Except(previousNodes).ToList(); - if (newlyImportedNodes.Any()) - { - _importedNodesByNodeId = null; - } - var modelUri = nodeSet.Models?.FirstOrDefault()?.ModelUri; - if (modelUri != null) - { - _importedUANodeSetsByUri.Add(modelUri, nodeSet); - } - return newlyImportedNodes; - } - public virtual UANodeSet GetUANodeSet(string modeluri) - { - if (_importedUANodeSetsByUri.TryGetValue(modeluri, out var nodeSet)) - { - return nodeSet; - } - return null; - } - - public virtual List GetHierarchyReferences(NodeState nodeState) - { - var hierarchy = new Dictionary(); - var references = new List(); - nodeState.GetHierarchyReferences(_systemContext, null, hierarchy, references); - return references; - } - - public virtual (string Json, bool IsScalar) JsonEncodeVariant(Variant wrappedValue, DataTypeModel dataType = null) - { - return NodeModelUtils.JsonEncodeVariant(_systemContext, wrappedValue, dataType, ReencodeExtensionsAsJson, EncodeJsonScalarsAsValue); - } - - public virtual Variant JsonDecodeVariant(string jsonVariant, DataTypeModel dataType = null) - { - dataType ??= this.GetModelForNode(this.GetModelNodeId(DataTypeIds.String)); - var variant = NodeModelUtils.JsonDecodeVariant(jsonVariant, new ServiceMessageContext { NamespaceUris = _systemContext.NamespaceUris }, dataType, EncodeJsonScalarsAsValue); - return variant; - } - - public string GetModelBrowseName(QualifiedName browseName) - { - if (UseLocalNodeIds) - { - return browseName.ToString(); - } - return $"{NamespaceUris.GetString(browseName.NamespaceIndex)};{browseName.Name}"; - } - - public QualifiedName GetBrowseNameFromModel(string modelBrowseName) - { - if (UseLocalNodeIds) - { - return QualifiedName.Parse(modelBrowseName); - } - var parts = modelBrowseName.Split(new[] { ';' }, 2); - if (parts.Length == 1) - { - return new QualifiedName(parts[0]); - } - return new QualifiedName(parts[1], (ushort)NamespaceUris.GetIndex(parts[0])); - } - } -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicComplexType.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicComplexType.cs deleted file mode 100644 index 0090611a..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicComplexType.cs +++ /dev/null @@ -1,895 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2022 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using System.Xml; -using CESMII.OpcUa.NodeSetModel; -using CESMII.OpcUa.NodeSetModel.Export.Opc; - -namespace Opc.Ua.Client.ComplexTypes -{ - /// - /// A complex type that performs encoding and decoding based on NodeSetModel type information, without requiring a concrete CLR type - /// - public class DynamicComplexType : - IEncodeable, IJsonEncodeable, IFormattable, IComplexTypeInstance, IDynamicComplexTypeInstance - { - #region Constructors - /// - /// - /// - public DynamicComplexType() - { - - } - - #endregion Constructors - - #region Public Properties - /// - public ExpandedNodeId TypeId { get; set; } - /// - public ExpandedNodeId BinaryEncodingId { get; set; } - /// - public ExpandedNodeId XmlEncodingId { get; set; } - /// - public ExpandedNodeId JsonEncodingId { get; set; } - - /// - /// Makes a deep copy of the object. - /// - /// - /// A new object that is a copy of this instance. - /// - public new virtual object MemberwiseClone() - { - throw new NotImplementedException(); - //Type thisType = this.GetType(); - //BaseComplexType clone = Activator.CreateInstance(thisType) as BaseComplexType; - - //clone.TypeId = TypeId; - //clone.BinaryEncodingId = BinaryEncodingId; - //clone.XmlEncodingId = XmlEncodingId; - - //// clone all properties of derived class - //foreach (var property in GetPropertyEnumerator()) - //{ - // property.SetValue(clone, Utils.Clone(property.GetValue(this))); - //} - - //return clone; - } - - /// - public virtual void Encode(IEncoder encoder) - { - InitializeDynamicEncodeable(encoder.Context); - - encoder.PushNamespace(XmlNamespace); - foreach (DynamicTypePropertyInfo property in m_propertyList) - { - EncodeProperty(encoder, property); - if (m_IsUnion && m_propertyDict.TryGetValue("SwitchField", out var sfObject) && sfObject is UInt32 sf && sf == 0) - { - // No fields - break; - } - } - encoder.PopNamespace(); - } - - /// - public virtual void Decode(IDecoder decoder) - { - InitializeDynamicEncodeable(decoder.Context); - decoder.PushNamespace(XmlNamespace); - UInt32? encodingMask = null; - UInt32 currentBit = 0; - - foreach (DynamicTypePropertyInfo property in m_propertyList) - { - if (encodingMask == null) - { - DecodeProperty(decoder, property); - if (currentBit == 0 && property.Name == "EncodingMask") - { - // read encoding mask, but only if it's the first property (currentBit != 0 on subsequent iterations) - encodingMask = (UInt32)m_propertyDict["EncodingMask"]; - } - currentBit = 0x01; - } - else - { - if (!property.IsOptional || (currentBit & encodingMask ?? UInt32.MaxValue) != 0) - { - // Only decode non-optional properties or optional properties that are in encoding mask - DecodeProperty(decoder, property); - } - if (property.IsOptional) - { - currentBit <<= 1; - } - } - if (m_IsUnion && m_propertyDict.TryGetValue("SwitchField", out var sfObject) && sfObject is UInt32 sf && sf == 0) - { - // No fields - break; - } - } - - decoder.PopNamespace(); - } - - private void InitializeDynamicEncodeable(IServiceMessageContext context) - { - if (m_propertyDict == null && this.TypeId != null && context.Factory is IDynamicEncodeableFactory dynamicFactory) - { - var dataType = dynamicFactory.GetDataTypeForEncoding(this.TypeId); - if (dataType == null) - { - dataType = dynamicFactory.GetDataTypeForEncoding(this.XmlEncodingId); - } - if (dataType == null) - { - dataType = dynamicFactory.GetDataTypeForEncoding(this.BinaryEncodingId); - } - if (dataType == null) - { - dataType = dynamicFactory.GetDataTypeForEncoding(this.JsonEncodingId); - } - if (dataType != null) - { - var dtExpandedNodeId = ExpandedNodeId.Parse(dataType.NodeId); - var dtNodeId = ExpandedNodeId.ToNodeId(dtExpandedNodeId, context.NamespaceUris); - var builtInType = TypeInfo.GetBuiltInType(dtNodeId); - if (builtInType != BuiltInType.Null && builtInType != BuiltInType.ExtensionObject) - { - return; - } - - if (XmlNamespace == null) - { - XmlNamespace = GetXmlNamespace(dataType.NodeSet); - } - if (_xmlName == null) - { - var typeName = dataType.SymbolicName ?? dataType.DisplayName?.FirstOrDefault()?.Text; - _xmlName = new XmlQualifiedName(typeName, XmlNamespace); - } - - if (BinaryEncodingId == null) - { - var binaryEncodingId = dataType.OtherReferencedNodes.FirstOrDefault(rn => - rn.ReferenceType?.NodeId == new ExpandedNodeId(ReferenceTypeIds.HasEncoding, Namespaces.OpcUa).ToString() - && rn.Node.BrowseName == $"{Namespaces.OpcUa};{BrowseNames.DefaultBinary}" - )?.Node.NodeId; - if (binaryEncodingId != null) - { - BinaryEncodingId = ExpandedNodeId.Parse(binaryEncodingId, context.NamespaceUris); - } - else - { - BinaryEncodingId = this.TypeId; - } - } - if (XmlEncodingId == null) - { - var xmlEncodingId = dataType.OtherReferencedNodes.FirstOrDefault(rn => - rn.ReferenceType?.NodeId == new ExpandedNodeId(ReferenceTypeIds.HasEncoding, Namespaces.OpcUa).ToString() - && rn.Node.BrowseName == $"{Namespaces.OpcUa};{BrowseNames.DefaultXml}" - )?.Node.NodeId; - if (xmlEncodingId != null) - { - XmlEncodingId = ExpandedNodeId.Parse(xmlEncodingId, context.NamespaceUris); - } - else - { - XmlEncodingId = this.TypeId; - } - } - if (JsonEncodingId == null) - { - var jsonEncodingId = dataType.OtherReferencedNodes.FirstOrDefault(rn => - rn.ReferenceType?.NodeId == new ExpandedNodeId(ReferenceTypeIds.HasEncoding, Namespaces.OpcUa).ToString() - && rn.Node.BrowseName == $"{Namespaces.OpcUa};{BrowseNames.DefaultJson}" - )?.Node.NodeId; - if (jsonEncodingId != null) - { - JsonEncodingId = ExpandedNodeId.Parse(jsonEncodingId, context.NamespaceUris); - } - else - { - JsonEncodingId = this.TypeId; - } - } - - var propertyTypeInfo = GetEncodeableTypeInfo(dataType, dynamicFactory, context.NamespaceUris); - - m_propertyList = propertyTypeInfo.ToList(); - m_propertyDict = m_propertyList.ToDictionary(p => p.Name, p => (object)null); - } - } - } - - private static string GetXmlNamespace(NodeSetModel nodeSet) - { - return nodeSet.XmlSchemaUri ?? $"{nodeSet.ModelUri.TrimEnd('/')}/Types.xsd"; - } - - public List GetEncodeableTypeInfo(DataTypeModel dataType, IDynamicEncodeableFactory dynamicFactory, NamespaceTable namespaceUris) - { - List properties = new(); - var fields = dataType.GetStructureFieldsInherited(); - if (dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Union}")) - { - m_IsUnion = true; - if (!fields.Any(f => f.Name == "StructureField")) - { - // Union: add switchfield - var property = new DynamicTypePropertyInfo - { - Name = "SwitchField", - TypeId = DataTypeIds.UInt32, - ValueRank = -1, - BuiltInType = BuiltInType.UInt32, - IsOptional = false, - }; - properties.Add(property); - } - } - if (fields.Any() /* || dataType.HasBaseType(new ExpandedNodeId(DataTypeIds.Structure, Namespaces.OpcUa).ToString())*/) - { - bool hasOptionalFields = false; - foreach (var field in fields) - { - var fieldDt = field.DataType as DataTypeModel; - if (field.IsOptional) - { - hasOptionalFields = true; - } - DynamicTypePropertyInfo property = GetPropertyTypeInfo(field.SymbolicName ?? field.Name, fieldDt, field.IsOptional, field.AllowSubTypes, field.ValueRank, dynamicFactory, namespaceUris); - property.XmlSchemaUri = field.Owner.NodeSet.XmlSchemaUri; - properties.Add(property); - } - if (hasOptionalFields) - { - properties.Insert(0, new DynamicTypePropertyInfo { BuiltInType = BuiltInType.UInt32, IsOptional = true, Name = "EncodingMask", ValueRank = -1 }); - } - } - else if (dataType.EnumFields?.Any() == true || dataType.HasBaseType(new ExpandedNodeId(DataTypeIds.Enumeration, Namespaces.OpcUa).ToString())) - { - DynamicTypePropertyInfo property = GetPropertyTypeInfo(dataType.BrowseName, dataType, false, false, null, dynamicFactory, namespaceUris); - property.IsEnum = true; - properties.Add(property); - } - return properties; - } - - private static DynamicTypePropertyInfo GetPropertyTypeInfo(string propertyName, DataTypeModel dataType, bool isOptional, bool allowSubTypes, int? valueRank, IDynamicEncodeableFactory dynamicFactory, NamespaceTable namespaceUris) - { - var builtInType = DynamicEncodeableFactory.GetBuiltInType(dataType as DataTypeModel, namespaceUris); - Type systemType = builtInType != BuiltInType.Null ? null : typeof(DynamicComplexType); - bool isEnum = false; - if (builtInType == BuiltInType.Null && dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Enumeration}")) - { - isEnum = true; - // Get the current application domain for the current thread. - AppDomain currentDomain = AppDomain.CurrentDomain; - - // Create a dynamic assembly in the current application domain, - // and allow it to be executed and saved to disk. - var aName = new AssemblyName("TempAssembly"); - var ab = AssemblyBuilder.DefineDynamicAssembly( - aName, AssemblyBuilderAccess.Run); - - // Define a dynamic module in "TempAssembly" assembly. For a single- - // module assembly, the module has the same name as the assembly. - ModuleBuilder mb = ab.DefineDynamicModule(aName.Name); - - // Define a public enumeration with the name "Elevation" and an - // underlying type of Integer. - EnumBuilder eb = mb.DefineEnum(dataType.SymbolicName ?? dataType.DisplayName.FirstOrDefault().Text, TypeAttributes.Public, typeof(int)); - foreach (var enumField in dataType.EnumFields) - { - eb.DefineLiteral(enumField.Name, (int)enumField.Value); - } - // Create the type and save the assembly. - systemType = eb.CreateTypeInfo().AsType(); - } - var encodings = dynamicFactory.AddEncodingsForDataType(dataType, namespaceUris); - ExpandedNodeId binaryEncodingId = null, xmlEncodingId = null, jsonEncodingId = null; - if (encodings != null) - { - encodings.TryGetValue(BrowseNames.DefaultBinary, out binaryEncodingId); - encodings.TryGetValue(BrowseNames.DefaultXml, out xmlEncodingId); - encodings.TryGetValue(BrowseNames.DefaultJson, out jsonEncodingId); - } - var property = new DynamicTypePropertyInfo - { - Name = propertyName, - TypeId = DynamicEncodeableFactory.NormalizeNodeIdForEncodableFactory(ExpandedNodeId.Parse(dataType.NodeId), namespaceUris), - BinaryEncodingId = binaryEncodingId, - XmlEncodingId = xmlEncodingId, - JsonEncodingId = jsonEncodingId, - ValueRank = valueRank ?? -1, - BuiltInType = builtInType, - SystemType = systemType, - IsOptional = isOptional, - AllowSubTypes = allowSubTypes, - IsEnum = isEnum, - }; - return property; - } - - /// - public virtual bool IsEqual(IEncodeable encodeable) - { - if (Object.ReferenceEquals(this, encodeable)) - { - return true; - } - - if (!(encodeable is DynamicComplexType valueBaseType)) - { - return false; - } - - var valueType = valueBaseType.GetType(); - if (this.GetType() != valueType) - { - return false; - } - throw new NotImplementedException(); - //foreach (var property in GetPropertyEnumerator()) - //{ - // if (!Utils.IsEqual(property.GetValue(this), property.GetValue(valueBaseType))) - // { - // return false; - // } - //} - - //return true; - } - - /// - public override string ToString() - { - return ToString(null, null); - } - #endregion Public Properties - - #region IFormattable Members - /// - /// Returns the string representation of the complex type. - /// - /// (Unused). Leave this as null - /// The provider of a mechanism for retrieving an object to control formatting. - /// - /// A containing the value of the current embeded instance in the specified format. - /// - /// Thrown if the format parameter is not null - public virtual string ToString(string format, IFormatProvider formatProvider) - { - if (format == null) - { - StringBuilder body = new StringBuilder(); - - foreach (var property in m_propertyList) - { - AppendPropertyValue(formatProvider, body, m_propertyDict[property.Name], property.ValueRank); - } - - if (body.Length > 0) - { - return body.Append('}').ToString(); - } - - if (!NodeId.IsNull(this.TypeId)) - { - return String.Format(formatProvider, "{{{0}}}", this.TypeId); - } - - return "(null)"; - } - - throw new FormatException(Utils.Format("Invalid format string: '{0}'.", format)); - } - #endregion IFormattable Members - - #region IComplexTypeProperties - /// - public virtual int GetPropertyCount() - { - return m_propertyList?.Count ?? 0; - } - - /// - /// - public virtual object this[int index] - { - get => m_propertyDict[m_propertyList.ElementAt(index).Name]; - set => m_propertyDict[m_propertyList.ElementAt(index).Name] = value; - } - - /// - public virtual object this[string name] - { - get => m_propertyDict[name]; - set => m_propertyDict[name] = value; - } - - #endregion IComplexTypeProperties - - #region Private Members - /// - /// Formatting helper. - /// - private void AddSeparator(StringBuilder body) - { - if (body.Length == 0) - { - body.Append('{'); - } - else - { - body.Append('|'); - } - } - - /// - /// Append a property to the value string. - /// Handle arrays and enumerations. - /// - protected void AppendPropertyValue( - IFormatProvider formatProvider, - StringBuilder body, - object value, - int valueRank) - { - AddSeparator(body); - if (valueRank >= 0 && value is Array array) - { - var rank = array.Rank; - var dimensions = new int[rank]; - var mods = new int[rank]; - for (int ii = 0; ii < rank; ii++) - { - dimensions[ii] = array.GetLength(ii); - } - - for (int ii = rank - 1; ii >= 0; ii--) - { - mods[ii] = dimensions[ii]; - if (ii < rank - 1) - { - mods[ii] *= mods[ii + 1]; - } - } - - int count = 0; - foreach (var item in array) - { - bool needSeparator = true; - for (int dc = 0; dc < rank; dc++) - { - if ((count % mods[dc]) == 0) - { - body.Append('['); - needSeparator = false; - } - } - if (needSeparator) - { - body.Append(','); - } - AppendPropertyValue(formatProvider, body, item); - count++; - needSeparator = false; - for (int dc = 0; dc < rank; dc++) - { - if ((count % mods[dc]) == 0) - { - body.Append(']'); - needSeparator = true; - } - } - if (needSeparator && count < array.Length) - { - body.Append(','); - } - } - } - else if (valueRank >= 0 && value is IEnumerable enumerable) - { - bool first = true; - body.Append('['); - foreach (var item in enumerable) - { - if (!first) - { - body.Append(','); - } - AppendPropertyValue(formatProvider, body, item); - first = false; - } - body.Append(']'); - } - else - { - AppendPropertyValue(formatProvider, body, value); - } - } - - /// - /// Append a property to the value string. - /// - private void AppendPropertyValue( - IFormatProvider formatProvider, - StringBuilder body, - object value) - { - if (value is byte[] x) - { - body.AppendFormat(formatProvider, "Byte[{0}]", x.Length); - return; - } - - if (value is XmlElement xmlElements) - { - body.AppendFormat(formatProvider, "<{0}>", xmlElements.Name); - return; - } - - body.AppendFormat(formatProvider, "{0}", value); - } - - /// - /// Encode a property based on the property type and value rank. - /// - protected void EncodeProperty( - IEncoder encoder, - DynamicTypePropertyInfo property - ) - { - int valueRank = property.ValueRank; - BuiltInType builtInType = property.BuiltInType; - var propertyValue = m_propertyDict[property.Name]; - if (propertyValue == null) - { - return; - } - if (property.XmlSchemaUri != null && property.XmlSchemaUri != XmlNamespace) - { - encoder.PushNamespace(property.XmlSchemaUri); - } - if (valueRank == ValueRanks.Scalar) - { - EncodeProperty(encoder, property.Name, propertyValue, builtInType, property.SystemType, false, property.AllowSubTypes); - } - else if (valueRank >= ValueRanks.OneDimension) - { - EncodePropertyArray(encoder, property.Name, propertyValue, builtInType, valueRank, false); - } - else - { - throw ServiceResultException.Create(StatusCodes.BadEncodingError, - "Cannot encode a property with unsupported ValueRank {0}.", valueRank); - } - if (property.XmlSchemaUri != null && property.XmlSchemaUri != XmlNamespace) - { - encoder.PopNamespace(); - } - } - - /// - /// Encode a scalar property based on the property type. - /// - private void EncodeProperty(IEncoder encoder, string name, object propertyValue, BuiltInType builtInType, Type systemType, bool isEnum, bool allowSubTypes) - { - if (systemType?.IsEnum == true) - { - isEnum = true; - builtInType = BuiltInType.Enumeration; - } - switch (builtInType) - { - case BuiltInType.Boolean: encoder.WriteBoolean(name, (Boolean)propertyValue); break; - case BuiltInType.SByte: encoder.WriteSByte(name, (SByte)propertyValue); break; - case BuiltInType.Byte: encoder.WriteByte(name, (Byte)propertyValue); break; - case BuiltInType.Int16: encoder.WriteInt16(name, (Int16)propertyValue); break; - case BuiltInType.UInt16: encoder.WriteUInt16(name, (UInt16)propertyValue); break; - case BuiltInType.Int32: encoder.WriteInt32(name, (Int32)propertyValue); break; - case BuiltInType.UInt32: encoder.WriteUInt32(name, (UInt32)propertyValue); break; - case BuiltInType.Int64: encoder.WriteInt64(name, (Int64)propertyValue); break; - case BuiltInType.UInt64: encoder.WriteUInt64(name, (UInt64)propertyValue); break; - case BuiltInType.Float: encoder.WriteFloat(name, (Single)propertyValue); break; - case BuiltInType.Double: encoder.WriteDouble(name, (Double)propertyValue); break; - case BuiltInType.String: encoder.WriteString(name, (String)propertyValue); break; - case BuiltInType.DateTime: encoder.WriteDateTime(name, (DateTime)propertyValue); break; - case BuiltInType.Guid: encoder.WriteGuid(name, (Uuid)propertyValue); break; - case BuiltInType.ByteString: encoder.WriteByteString(name, (Byte[])propertyValue); break; - case BuiltInType.XmlElement: encoder.WriteXmlElement(name, (XmlElement)propertyValue); break; - case BuiltInType.NodeId: encoder.WriteNodeId(name, (NodeId)propertyValue); break; - case BuiltInType.ExpandedNodeId: encoder.WriteExpandedNodeId(name, (ExpandedNodeId)propertyValue); break; - case BuiltInType.StatusCode: encoder.WriteStatusCode(name, (StatusCode)propertyValue); break; - case BuiltInType.DiagnosticInfo: encoder.WriteDiagnosticInfo(name, (DiagnosticInfo)propertyValue); break; - case BuiltInType.QualifiedName: encoder.WriteQualifiedName(name, (QualifiedName)propertyValue); break; - case BuiltInType.LocalizedText: encoder.WriteLocalizedText(name, (LocalizedText)propertyValue); break; - case BuiltInType.DataValue: encoder.WriteDataValue(name, (DataValue)propertyValue); break; - case BuiltInType.Variant: encoder.WriteVariant(name, (Variant)propertyValue); break; - case BuiltInType.ExtensionObject: encoder.WriteExtensionObject(name, (ExtensionObject)propertyValue); break; - case BuiltInType.Enumeration: - if (isEnum) - { - encoder.WriteEnumerated(name, propertyValue as Enum); - break; - } - goto case BuiltInType.Int32; - default: - if (propertyValue is IEncodeable encodableValue) - { - if (allowSubTypes) - { - encoder.WriteExtensionObject(name, new ExtensionObject(encodableValue)); - } - else - { - encoder.WriteEncodeable(name, encodableValue, systemType); - } - break; - } - throw ServiceResultException.Create(StatusCodes.BadEncodingError, - "Cannot encode unknown type {0}.", propertyValue?.GetType()); - } - } - - /// - /// Encode an array property based on the base property type. - /// - private void EncodePropertyArray(IEncoder encoder, string name, object propertyValue, BuiltInType builtInType, int valueRank, bool isEnum) - { - if (isEnum) - { - builtInType = BuiltInType.Enumeration; - } - if (propertyValue != null) - { - encoder.WriteArray(name, propertyValue, valueRank, builtInType); - } - } - - /// - /// Decode a property based on the property type and value rank. - /// - protected void DecodeProperty( - IDecoder decoder, - DynamicTypePropertyInfo property) - { - - if (property.XmlSchemaUri != null && property.XmlSchemaUri != XmlNamespace) - { - decoder.PushNamespace(property.XmlSchemaUri); - } - - int valueRank = property.ValueRank; - if (valueRank == ValueRanks.Scalar) - { - DecodeProperty(decoder, property.Name, property.BuiltInType, property.SystemType, property.IsEnum, property.AllowSubTypes, property.TypeId); - } - else if (valueRank >= ValueRanks.OneDimension) - { - DecodePropertyArray(decoder, property.Name, property.BuiltInType, property.SystemType, valueRank, property.IsEnum, property.TypeId); - } - else - { - throw ServiceResultException.Create(StatusCodes.BadDecodingError, - "Cannot decode a property with unsupported ValueRank {0}.", valueRank); - } - if (property.XmlSchemaUri != null && property.XmlSchemaUri != XmlNamespace) - { - decoder.PopNamespace(); - } - } - - /// - /// Decode a scalar property based on the property type. - /// - private void DecodeProperty(IDecoder decoder, string name, BuiltInType builtInType, Type systemType, bool isEnum, bool allowSubTypes, ExpandedNodeId typeId) - { - //var propertyType = property.PropertyType; - if (systemType?.IsEnum == true) - { - isEnum = true; - builtInType = BuiltInType.Enumeration; - } - switch (builtInType) - { - case BuiltInType.Boolean: m_propertyDict[name] = decoder.ReadBoolean(name); break; - case BuiltInType.SByte: m_propertyDict[name] = decoder.ReadSByte(name); break; - case BuiltInType.Byte: m_propertyDict[name] = decoder.ReadByte(name); break; - case BuiltInType.Int16: m_propertyDict[name] = decoder.ReadInt16(name); break; - case BuiltInType.UInt16: m_propertyDict[name] = decoder.ReadUInt16(name); break; - case BuiltInType.Int32: m_propertyDict[name] = decoder.ReadInt32(name); break; - case BuiltInType.UInt32: m_propertyDict[name] = decoder.ReadUInt32(name); break; - case BuiltInType.Int64: m_propertyDict[name] = decoder.ReadInt64(name); break; - case BuiltInType.UInt64: m_propertyDict[name] = decoder.ReadUInt64(name); break; - case BuiltInType.Float: m_propertyDict[name] = decoder.ReadFloat(name); break; - case BuiltInType.Double: m_propertyDict[name] = decoder.ReadDouble(name); break; - case BuiltInType.String: m_propertyDict[name] = decoder.ReadString(name); break; - case BuiltInType.DateTime: m_propertyDict[name] = decoder.ReadDateTime(name); break; - case BuiltInType.Guid: m_propertyDict[name] = decoder.ReadGuid(name); break; - case BuiltInType.ByteString: m_propertyDict[name] = decoder.ReadByteString(name); break; - case BuiltInType.XmlElement: m_propertyDict[name] = decoder.ReadXmlElement(name); break; - case BuiltInType.NodeId: m_propertyDict[name] = decoder.ReadNodeId(name); break; - case BuiltInType.ExpandedNodeId: m_propertyDict[name] = decoder.ReadExpandedNodeId(name); break; - case BuiltInType.StatusCode: m_propertyDict[name] = decoder.ReadStatusCode(name); break; - case BuiltInType.QualifiedName: m_propertyDict[name] = decoder.ReadQualifiedName(name); break; - case BuiltInType.LocalizedText: m_propertyDict[name] = decoder.ReadLocalizedText(name); break; - case BuiltInType.DataValue: m_propertyDict[name] = decoder.ReadDataValue(name); break; - case BuiltInType.Variant: m_propertyDict[name] = decoder.ReadVariant(name); break; - case BuiltInType.DiagnosticInfo: m_propertyDict[name] = decoder.ReadDiagnosticInfo(name); break; - case BuiltInType.ExtensionObject: - m_propertyDict[name] = decoder.ReadExtensionObject(name); - break; - case BuiltInType.Enumeration: - if (isEnum) - { - m_propertyDict[name] = decoder.ReadEnumerated(name, systemType); break; - } - goto case BuiltInType.Int32; - default: - Type encodeableType = null; - if (!decoder.Context.Factory.EncodeableTypes.TryGetValue(typeId, out encodeableType)) - { - if (typeof(IEncodeable).IsAssignableFrom(systemType)) - { - encodeableType = systemType; - } - } - if (encodeableType != null) - { - if (allowSubTypes) - { - m_propertyDict[name] = decoder.ReadExtensionObject(name)?.Body; - } - else - { - m_propertyDict[name] = decoder.ReadEncodeable(name, encodeableType, typeId); - } - } - else - { - throw ServiceResultException.Create(StatusCodes.BadDecodingError, - "Cannot decode unknown type {0} with encoding {1}.", systemType, typeId); - //m_propertyDict[name] = decoder.ReadEncodeable(name, typeof(DynamicComplexType), typeId); - } - break; - } - } - - /// - /// Decode an array property based on the base property type. - /// - private void DecodePropertyArray(IDecoder decoder, string name, BuiltInType builtInType, Type systemType, int valueRank, bool isEnum, ExpandedNodeId typeId) - { - if (isEnum) - { - builtInType = BuiltInType.Enumeration; - } - Array decodedArray = decoder.ReadArray(name, valueRank, builtInType/*, elementType*/, systemType, typeId); - m_propertyDict[name] = decodedArray; - } - - /// - /// - /// - /// - public XmlQualifiedName GetXmlName(IServiceMessageContext context) - { - InitializeDynamicEncodeable(context); - return _xmlName; - } - - public object Clone() - { - throw new NotImplementedException(); - } - - private XmlQualifiedName _xmlName; - - #endregion Private Members - - #region Protected Properties - /// - /// Provide XmlNamespace - /// - public string XmlNamespace { get; set; } - - #endregion - - #region Protected Fields - /// - /// The list of properties of this complex type. - /// - protected IList m_propertyList; - - /// - /// The list of properties as dictionary. - /// - protected Dictionary m_propertyDict; - private bool m_IsUnion; - #endregion Protected Fields - - #region Private Fields - //private XmlQualifiedName m_xmlName; - #endregion Private Fields - } - - /// - /// - /// - public class DynamicTypePropertyInfo - { - /// - public int ValueRank { get; set; } - /// - public BuiltInType BuiltInType { get; set; } - public Type SystemType { get; set; } - /// - public string Name { get; set; } - /// - /// Indicates optional structure field: important for JSON and XML encodingmask - /// - public bool IsOptional { get; set; } - /// - /// Indicates if subtypes are allowed: uses ExtensionObject encoding to capture the type/encoding id - /// - public bool AllowSubTypes { get; set; } - /// - public ExpandedNodeId TypeId { get; set; } - /// - public ExpandedNodeId BinaryEncodingId { get; set; } - /// - public ExpandedNodeId XmlEncodingId { get; set; } - /// - public ExpandedNodeId JsonEncodingId { get; set; } - public bool IsEnum { get; set; } - public string XmlSchemaUri { get; set; } - - public override string ToString() => $"{Name} {TypeId} {XmlEncodingId} {XmlSchemaUri}"; - } - - -}//namespace diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicEncodeableFactory.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicEncodeableFactory.cs deleted file mode 100644 index 8b48bb80..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/DynamicEncodeableFactory.cs +++ /dev/null @@ -1,126 +0,0 @@ -using Opc.Ua; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; - -using Opc.Ua.Client.ComplexTypes; -using System.Runtime.Serialization; -using R = System.Reflection; -using System.Reflection.Emit; -//using Opc.Ua.Gds; - -namespace CESMII.OpcUa.NodeSetModel.Export.Opc -{ - - /// - /// - /// - public interface IDynamicEncodeableFactory - { - public DataTypeModel GetDataTypeForEncoding(ExpandedNodeId typeId); - Dictionary AddEncodingsForDataType(DataTypeModel dataType, NamespaceTable namespaceUris); - } - - public class DynamicEncodeableFactory : EncodeableFactory, IDynamicEncodeableFactory - { - Dictionary _dynamicDataTypes = new(); - - public DynamicEncodeableFactory(IEncodeableFactory factory) : base(factory) - { - } - - public DataTypeModel GetDataTypeForEncoding(ExpandedNodeId typeId) - { - if (typeId != null) - { - if (_dynamicDataTypes.TryGetValue(typeId, out var dataType)) - { - return dataType; - } - } - return null; - } - - public Dictionary AddEncodingsForDataType(DataTypeModel dataType, NamespaceTable namespaceUris) - { - bool bTypeAlreadyProcessed = false; - var dataTypeExpandedNodeId = ExpandedNodeId.Parse(dataType.NodeId); - dataTypeExpandedNodeId = NormalizeNodeIdForEncodableFactory(dataTypeExpandedNodeId, namespaceUris); - - if (_dynamicDataTypes.ContainsKey(dataTypeExpandedNodeId)) - { - // Used later to break recursion for recursive data structures - bTypeAlreadyProcessed = true; - } - BuiltInType builtInType = GetBuiltInType(dataType, namespaceUris); - if (builtInType != BuiltInType.Null && builtInType != BuiltInType.ExtensionObject) - { - return null; - } - - _dynamicDataTypes[dataTypeExpandedNodeId] = dataType; - - var encodingsDict = new Dictionary(); - var encodings = dataType.OtherReferencedNodes.Where(rn => rn.ReferenceType?.NodeId == new ExpandedNodeId(ReferenceTypeIds.HasEncoding, Namespaces.OpcUa).ToString()); - foreach(var encoding in encodings) - { - var encodingExpandedNodeId = ExpandedNodeId.Parse(encoding.Node.NodeId); - encodingExpandedNodeId = NormalizeNodeIdForEncodableFactory(encodingExpandedNodeId, namespaceUris); - - var encodingName = encoding.Node.BrowseName.Replace($"{Namespaces.OpcUa};", ""); - if (!encodingsDict.ContainsKey(encodingName)) - { - encodingsDict.Add(encodingName, encodingExpandedNodeId); - } - if (!EncodeableTypes.ContainsKey(encodingExpandedNodeId)) - { - this.AddEncodeableType(encodingExpandedNodeId, typeof(DynamicComplexType)); - _dynamicDataTypes[encodingExpandedNodeId] = dataType; - } - } - if (!this.EncodeableTypes.ContainsKey(dataTypeExpandedNodeId)) - { - this.AddEncodeableType(dataTypeExpandedNodeId, typeof(DynamicComplexType)); - } - - if (!bTypeAlreadyProcessed && dataType.StructureFields?.Any() == true) - { - foreach (var field in dataType.StructureFields) - { - AddEncodingsForDataType(field.DataType as DataTypeModel, namespaceUris); - } - } - return encodingsDict; - } - - public static ExpandedNodeId NormalizeNodeIdForEncodableFactory(ExpandedNodeId expandedNodeId, NamespaceTable namespaceUris) - { - // check for default namespace. - if (expandedNodeId.NamespaceUri == Namespaces.OpcUa) - { - // EncodableFactory expects namespace 0 nodeids to have no URI, and all others to provide the URI - expandedNodeId = NodeId.ToExpandedNodeId(ExpandedNodeId.ToNodeId(expandedNodeId, namespaceUris), namespaceUris); - } - return expandedNodeId; - } - - public static BuiltInType GetBuiltInType(DataTypeModel dataType, NamespaceTable namespaceUris) - { - var dtNodeId = ExpandedNodeId.Parse(dataType.NodeId, namespaceUris); - var builtInType = TypeInfo.GetBuiltInType(dtNodeId); - if (builtInType == BuiltInType.Null && dataType.SuperType != null) - { - var superTypeBuiltInType = GetBuiltInType(dataType.SuperType as DataTypeModel, namespaceUris); - if (superTypeBuiltInType == BuiltInType.ExtensionObject || superTypeBuiltInType == BuiltInType.Enumeration) - { - return BuiltInType.Null; - } - return superTypeBuiltInType; - } - return builtInType; - } - - } - -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/ExportContext.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/ExportContext.cs deleted file mode 100644 index bc3686bd..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/ExportContext.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using Opc.Ua.Export; -using CESMII.OpcUa.NodeSetModel.Factory.Opc; -using Microsoft.Extensions.Logging; - -namespace CESMII.OpcUa.NodeSetModel.Export.Opc -{ - public class ExportContext : DefaultOpcUaContext - { - public ExportContext(ILogger logger, Dictionary nodeSetModels) : base(nodeSetModels, logger) - { - } - public Dictionary Aliases; - /// - /// Assumes that any VariableModel.Value or VariableTypeModel.Value that contain scalars just contain the scalar value, rather than the OPC JSON encoding - /// - - public HashSet _nodeIdsUsed; - public Dictionary _exportedSoFar; - } - -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/IOpcUaContext.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/IOpcUaContext.cs deleted file mode 100644 index 333a4bd1..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/IOpcUaContext.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Opc.Ua; - -using System; -using System.Collections.Generic; -using Microsoft.Extensions.Logging; -using Opc.Ua.Export; - -namespace CESMII.OpcUa.NodeSetModel.Factory.Opc -{ - public interface IOpcUaContext - { - // OPC utilities - NamespaceTable NamespaceUris { get; } - /// - /// NodeIds in the NodeModel will not use namespace URIs ("nsu=", absolute NodeIds) but namespace indices ("ns=", local NodeIds). - /// Use only if the NodeModel is generated in the context of a specific OPC server, or in a specific set of nodesets that are loaded in a specific order. - /// - bool UseLocalNodeIds { get; } - /// - /// / - /// - /// - /// - /// - string GetModelNodeId(NodeId nodeId); - - // OPC NodeState cache - NodeState GetNode(NodeId nodeId); - NodeState GetNode(ExpandedNodeId expandedNodeId); - List GetHierarchyReferences(NodeState nodeState); - - // NodesetModel cache - NodeSetModel GetOrAddNodesetModel(ModelTableEntry model, bool createNew = true); - TNodeModel GetModelForNode(string nodeId) where TNodeModel : NodeModel; - ILogger Logger { get; } - (string Json, bool IsScalar) JsonEncodeVariant(Variant wrappedValue, DataTypeModel dataType = null); - Variant JsonDecodeVariant(string jsonVariant, DataTypeModel dataType = null); - List ImportUANodeSet(UANodeSet nodeSet); - UANodeSet GetUANodeSet(string modeluri); - - string GetModelBrowseName(QualifiedName browseName); - QualifiedName GetBrowseNameFromModel(string modelBrowseName); - - Dictionary NodeSetModels { get; } - } -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelOpcExtensions.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelOpcExtensions.cs deleted file mode 100644 index 6aa2bddc..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelOpcExtensions.cs +++ /dev/null @@ -1,494 +0,0 @@ -using Opc.Ua; -using ua = Opc.Ua; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -using NotVisualBasic.FileIO; -using System.Reflection; -using Opc.Ua.Export; -using System; - -using CESMII.OpcUa.NodeSetModel.Factory.Opc; -using Newtonsoft.Json; -using Microsoft.Extensions.Logging; - -namespace CESMII.OpcUa.NodeSetModel.Opc.Extensions -{ - public static class NodeModelOpcExtensions - { - public static string GetDisplayNamePath(this InstanceModelBase model) - { - return model.GetDisplayNamePath(new List()); - } - public static DateTime GetNormalizedPublicationDate(this ModelTableEntry model) - { - return model.PublicationDateSpecified ? DateTime.SpecifyKind(model.PublicationDate, DateTimeKind.Utc) : default; - } - public static DateTime GetNormalizedPublicationDate(this DateTime? publicationDate) - { - return publicationDate != null ? DateTime.SpecifyKind(publicationDate.Value, DateTimeKind.Utc) : default; - } - public static string GetDisplayNamePath(this InstanceModelBase model, List nodesVisited) - { - if (nodesVisited.Contains(model)) - { - return "(cycle)"; - } - nodesVisited.Add(model); - if (model.Parent is InstanceModelBase parent) - { - return $"{parent.GetDisplayNamePath(nodesVisited)}.{model.DisplayName.FirstOrDefault()?.Text}"; - } - return model.DisplayName.FirstOrDefault()?.Text; - } - public static string GetUnqualifiedBrowseName(this NodeModel _this) - { - var browseName = _this.GetBrowseName(); - var parts = browseName.Split(new[] { ';' }, 2); - if (parts.Length > 1) - { - return parts[1]; - } - return browseName; - } - - public enum JsonValueType - { - /// - /// JSON object - /// - Object, - /// - /// Scalar, to be quoted - /// - String, - /// - /// Scalar, not to be quoted - /// - Value - } - - public static bool IsJsonScalar(this DataTypeModel dataType) - { - return GetJsonValueType(dataType) != JsonValueType.Object; - } - public static JsonValueType GetJsonValueType(this DataTypeModel dataType) - { - if (dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.String}") - || dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Int64}") // numeric, but encoded as string - || dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.UInt64}") // numeric, but encoded as string - || dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.DateTime}") - || dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.ByteString}") - || dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.String}") - ) - { - return JsonValueType.String; - } - if (dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Boolean}") - || (dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Number}") - && !dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Decimal}") // numeric, but encoded as Scale/Value object - ) - || dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.StatusCode}") - || dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Enumeration}") - ) - { - return JsonValueType.Value; - } - return JsonValueType.Object; - } - - internal static void SetEngineeringUnits(this VariableModel model, EUInformation euInfo) - { - model.EngineeringUnit = new VariableModel.EngineeringUnitInfo - { - DisplayName = euInfo.DisplayName?.ToModelSingle(), - Description = euInfo.Description?.ToModelSingle(), - NamespaceUri = euInfo.NamespaceUri, - UnitId = euInfo.UnitId, - }; - } - - internal static void SetRange(this VariableModel model, ua.Range euRange) - { - model.MinValue = euRange.Low; - model.MaxValue = euRange.High; - } - internal static void SetInstrumentRange(this VariableModel model, ua.Range range) - { - model.InstrumentMinValue = range.Low; - model.InstrumentMaxValue = range.High; - } - - private const string strUNECEUri = "http://www.opcfoundation.org/UA/units/un/cefact"; - - static List _UNECEEngineeringUnits; - public static List UNECEEngineeringUnits - { - get - { - if (_UNECEEngineeringUnits == null) - { - // Load UNECE units if not already loaded - _UNECEEngineeringUnits = new List(); - var fileName = Path.Combine(Path.GetDirectoryName(typeof(VariableModel).Assembly.Location), "NodeSets", "UNECE_to_OPCUA.csv"); - Stream fileStream; - if (File.Exists(fileName)) - { - fileStream = File.OpenRead(fileName); - } - else - { - fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CESMII.OpcUa.NodeSetModel.Factory.Opc.NodeSets.UNECE_to_OPCUA.csv"); - } - var parser = new CsvTextFieldParser(fileStream); - if (!parser.EndOfData) - { - var headerFields = parser.ReadFields(); - } - while (!parser.EndOfData) - { - var parts = parser.ReadFields(); - if (parts.Length != 4) - { - // error - } - var UNECECode = parts[0]; - var UnitId = parts[1]; - var DisplayName = parts[2]; - var Description = parts[3]; - var newEuInfo = new EUInformation(DisplayName, Description, strUNECEUri) - { - UnitId = int.Parse(UnitId), - }; - _UNECEEngineeringUnits.Add(newEuInfo); - } - } - - return _UNECEEngineeringUnits; - } - } - - static Dictionary> _euInformationByDescription; - static Dictionary> EUInformationByDescription - { - get - { - if (_euInformationByDescription == null) - { - _euInformationByDescription = new Dictionary>(); - foreach (var aEuInformation in UNECEEngineeringUnits) - { - if (!_euInformationByDescription.ContainsKey(aEuInformation.Description.Text)) - { - _euInformationByDescription.Add(aEuInformation.Description.Text, new List { aEuInformation }); - } - else - { - _euInformationByDescription[aEuInformation.DisplayName.Text].Add(aEuInformation); - } - } - } - return _euInformationByDescription; - } - } - - static Dictionary> _euInformationByDisplayName; - static Dictionary> EUInformationByDisplayName - { - get - { - if (_euInformationByDisplayName == null) - { - _euInformationByDisplayName = new Dictionary>(); - foreach (var aEuInformation in UNECEEngineeringUnits) - { - if (!_euInformationByDisplayName.ContainsKey(aEuInformation.DisplayName.Text)) - { - _euInformationByDisplayName.Add(aEuInformation.DisplayName.Text, new List { aEuInformation }); - } - else - { - _euInformationByDisplayName[aEuInformation.DisplayName.Text].Add(aEuInformation); - } - } - } - return _euInformationByDisplayName; - } - } - - public static EUInformation GetEUInformation(VariableModel.EngineeringUnitInfo engineeringUnitDescription) - { - if (engineeringUnitDescription == null) return null; - - List euInfoList; - if (!string.IsNullOrEmpty(engineeringUnitDescription.DisplayName?.Text) - && engineeringUnitDescription.UnitId == null - && engineeringUnitDescription.Description == null - && (string.IsNullOrEmpty(engineeringUnitDescription.NamespaceUri) || engineeringUnitDescription.NamespaceUri == strUNECEUri)) - { - // If we only have a displayname, assume it's a UNECE unit - // Try to lookup engineering unit by description - if (EUInformationByDescription.TryGetValue(engineeringUnitDescription.DisplayName.Text, out euInfoList)) - { - return euInfoList.FirstOrDefault(); - } - // Try to lookup engineering unit by display name - else if (EUInformationByDisplayName.TryGetValue(engineeringUnitDescription.DisplayName.Text, out euInfoList)) - { - return euInfoList.FirstOrDefault(); - } - else - { - // No unit found: just use the displayname - return new EUInformation(engineeringUnitDescription.DisplayName.Text, engineeringUnitDescription.DisplayName.Text, null); - } - } - else - { - // Custom EUInfo: use what was specified without further validation - EUInformation euInfo = new EUInformation(engineeringUnitDescription.DisplayName?.Text, engineeringUnitDescription.Description?.Text, engineeringUnitDescription.NamespaceUri); - if (engineeringUnitDescription.UnitId != null) - { - euInfo.UnitId = engineeringUnitDescription.UnitId.Value; - } - return euInfo; - } - } - - public static void UpdateAllMethodArgumentVariables(this NodeSetModel nodeSetModel, IOpcUaContext opcContext) - { - foreach(var nodeModel in nodeSetModel.AllNodesByNodeId.SelectMany(kv => kv.Value.Methods)) - { - UpdateMethodArgumentVariables(nodeModel as MethodModel, opcContext); - } - } - - public static void UpdateMethodArgumentVariables(MethodModel methodModel, IOpcUaContext opcContext) - { - UpdateMethodArgumentVariable(methodModel, BrowseNames.InputArguments, methodModel.InputArguments, opcContext); - UpdateMethodArgumentVariable(methodModel, BrowseNames.OutputArguments, methodModel.OutputArguments, opcContext); - } - private static void UpdateMethodArgumentVariable(MethodModel methodModel, string browseName, List modelArguments, IOpcUaContext opcContext) - { - var argumentProperty = GetArgumentProperty(methodModel, browseName, modelArguments, opcContext); - if (argumentProperty != null) - { - var existingArgumentProperty = methodModel.Properties.FirstOrDefault(p => p.BrowseName == browseName); - if (existingArgumentProperty == null) - { - methodModel.Properties.Add(argumentProperty); - } - else - { - // Update arguments in existing property - if (existingArgumentProperty.Value != argumentProperty.Value) - { - opcContext.Logger.LogInformation($"Updated {browseName} for method {methodModel}"); - opcContext.Logger.LogTrace($"Updated {browseName} for method {methodModel}. Previous arguments: {existingArgumentProperty.Value}. New arguments: {argumentProperty.Value}"); - existingArgumentProperty.Value = argumentProperty.Value; - } - } - } - - } - internal static PropertyModel GetArgumentProperty(MethodModel methodModel, string browseName, List modelArguments, IOpcUaContext opcContext) - { - List arguments = new List(); - if (modelArguments?.Any() == true) - { - foreach (var modelArgument in modelArguments) - { - UInt32Collection arrayDimensions = null; - if (modelArgument.ArrayDimensions != null) - { - arrayDimensions = JsonConvert.DeserializeObject($"[{modelArgument.ArrayDimensions}]"); - } - - var argument = new Argument - { - Name = modelArgument.BrowseName, - ArrayDimensions = arrayDimensions, - // TODO parse into array ArrayDimensions = inputArg.ArrayDimensions, - ValueRank = modelArgument.ValueRank ?? -1, - DataType = ExpandedNodeId.Parse(modelArgument.DataType.NodeId, opcContext.NamespaceUris), - Description = new ua.LocalizedText(modelArgument.Description?.FirstOrDefault()?.Text), - }; - if (modelArgument.Value != null || modelArgument.Description.Count > 1 || modelArgument.ModellingRule == "Optional") - { - // TODO Create or update argumentDescription - } - arguments.Add(argument); - } - } - if (arguments.Any()) - { - var argumentDataType = opcContext.GetModelForNode($"nsu={Namespaces.OpcUa};{DataTypeIds.Argument}"); - var argumentPropertyJson = opcContext.JsonEncodeVariant( - new Variant(arguments.Select(a => new ExtensionObject(a)).ToArray()), - argumentDataType); - var argumentProperty = new PropertyModel - { - NodeSet = modelArguments[0].NodeSet, - NodeId = modelArguments[0].NodeId, - CustomState = modelArguments[0].CustomState, - BrowseName = opcContext.GetModelBrowseName(browseName), - DisplayName = NodeModel.LocalizedText.ListFromText(browseName), - Description = new(), - Parent = methodModel, - DataType = argumentDataType, - TypeDefinition = opcContext.GetModelForNode($"nsu={Namespaces.OpcUa};{VariableTypeIds.PropertyType}"), - ValueRank = 1, - ArrayDimensions = $"{arguments.Count}", - Value = argumentPropertyJson.Json, - ModellingRule = "Mandatory", - }; - return argumentProperty; - } - return null; - } - - /// - /// Updates or creates the object of type NamespaceMetaDataType as described in https://reference.opcfoundation.org/Core/Part5/v105/docs/6.3.13 - /// - /// - public static bool UpdateNamespaceMetaData(this NodeSetModel _this, IOpcUaContext opcContext, bool createIfNotExist = true) - { - bool addedMetadata = false; - var metaDataTypeNodeId = opcContext.GetModelNodeId(ObjectTypeIds.NamespaceMetadataType); - var serverNamespacesNodeId = opcContext.GetModelNodeId(ObjectIds.Server_Namespaces); - var metadataObjects = _this.Objects.Where(o => o.TypeDefinition.HasBaseType(metaDataTypeNodeId) && o.Parent.NodeId == serverNamespacesNodeId).ToList(); - var metadataObject = metadataObjects.FirstOrDefault(); - if (metadataObject == null) - { - if (!createIfNotExist) - { - return false; - } - var parent = opcContext.GetModelForNode($"nsu={Namespaces.OpcUa};{ObjectIds.Server}"); - metadataObject = new ObjectModel - { - NodeSet = _this, - NodeId = GetNewNodeId(_this.ModelUri), - DisplayName = new ua.LocalizedText(_this.ModelUri).ToModel(), - BrowseName = opcContext.GetModelBrowseName(BrowseNames.NamespaceMetadataType), // $"{Namespaces.OpcUa};{nameof(ObjectTypeIds.NamespaceMetadataType)}", - Parent = parent, - OtherReferencingNodes = new List - { - new NodeModel.NodeAndReference - { - ReferenceType = opcContext.GetModelForNode($"nsu={Namespaces.OpcUa};{ReferenceTypeIds.HasComponent}"), - Node = parent, - } - } - }; - _this.Objects.Add(metadataObject); - addedMetadata = true; - } - addedMetadata |= CreateOrReplaceMetaDataProperty(_this, opcContext, metadataObject, BrowseNames.NamespaceUri, _this.ModelUri, true); - addedMetadata |= CreateOrReplaceMetaDataProperty(_this, opcContext, metadataObject, BrowseNames.NamespacePublicationDate, _this.PublicationDate, true); - addedMetadata |= CreateOrReplaceMetaDataProperty(_this, opcContext, metadataObject, BrowseNames.NamespaceVersion, _this.Version, true); - - // Only create if not already authored - addedMetadata |= CreateOrReplaceMetaDataProperty(_this, opcContext, metadataObject, BrowseNames.IsNamespaceSubset, "false", false); - addedMetadata |= CreateOrReplaceMetaDataProperty(_this, opcContext, metadataObject, BrowseNames.StaticNodeIdTypes, null, false); - addedMetadata |= CreateOrReplaceMetaDataProperty(_this, opcContext, metadataObject, BrowseNames.StaticNumericNodeIdRange, null, false); - addedMetadata |= CreateOrReplaceMetaDataProperty(_this, opcContext, metadataObject, BrowseNames.StaticStringNodeIdPattern, null, false); - return addedMetadata; - } - - private static bool CreateOrReplaceMetaDataProperty(NodeSetModel _this, IOpcUaContext context, ObjectModel metadataObject, QualifiedName browseName, object value, bool replaceIfExists) - { - string modelBrowseName = context.GetModelBrowseName(browseName); - var previousProp = metadataObject.Properties.FirstOrDefault(p => p.BrowseName == modelBrowseName); - if (replaceIfExists || previousProp == null) - { - string encodedValue; - if (value is DateTime) - { - encodedValue = $"{{\"Value\":{{\"Type\":13,\"Body\":\"{value:O}\"}}}}"; - } - else - { - encodedValue = $"{{\"Value\":{{\"Type\":12,\"Body\":\"{value}\"}}}}"; - } - if (previousProp != null) - { - previousProp.Value = encodedValue; - } - else - { - metadataObject.Properties.Add(new PropertyModel - { - NodeSet = _this, - NodeId = GetNewNodeId(_this.ModelUri), - BrowseName = modelBrowseName, - DisplayName = new ua.LocalizedText(browseName.Name).ToModel(), - Value = encodedValue, - }); - } - return true; - } - return false; - } - - public static List UpdateEncodings(this NodeSetModel _this, IOpcUaContext context) - { - var missingEncodings = new List(); - foreach (var dataType in _this.DataTypes) - { - if (dataType.StructureFields?.Any() == true) - { - // Ensure there's an encoding for the data type - var hasEncodingNodeId = context.GetModelNodeId(ReferenceTypeIds.HasEncoding); - var encodingReferences = dataType.OtherReferencedNodes.Where(nr => (nr.ReferenceType as ReferenceTypeModel).HasBaseType(hasEncodingNodeId)).ToList(); - - foreach (var encodingBrowseName in new[] { BrowseNames.DefaultXml, BrowseNames.DefaultJson, BrowseNames.DefaultBinary }) - { - var encodingModelBrowseName = context.GetModelBrowseName(encodingBrowseName); - if (!encodingReferences.Any(nr => nr.Node.BrowseName == encodingModelBrowseName)) - { - var encodingId = NodeModelOpcExtensions.GetNewNodeId(dataType.Namespace); - var encoding = new ObjectModel - { - NodeSet = dataType.NodeSet, - NodeId = encodingId, - BrowseName = encodingModelBrowseName, - DisplayName = new ua.LocalizedText(encodingBrowseName).ToModel(), - TypeDefinition = context.GetModelForNode($"nsu={Namespaces.OpcUa};{ObjectTypeIds.DataTypeEncodingType}"), - Parent = dataType, - }; - // According to https://reference.opcfoundation.org/Core/Part6/v105/docs/F.4 only one direction of the reference is required: using inverse reference on the encoding only to keep the data type XML cleaner - encoding.OtherReferencingNodes.Add(new NodeModel.NodeAndReference - { - ReferenceType = context.GetModelForNode($"nsu={Namespaces.OpcUa};{ReferenceTypeIds.HasEncoding}"), - Node = dataType, - }); - _this.Objects.Add(encoding); - missingEncodings.Add($"{dataType}: {encoding}"); - } - } - } - } - return missingEncodings; - } - - public static string GetNewNodeId(string nameSpace) - { - return new ExpandedNodeId(Guid.NewGuid(), nameSpace).ToString(); - } - public static string ToModel(this QualifiedName qName, NamespaceTable namespaceUris) - { - return $"{namespaceUris.GetString(qName.NamespaceIndex)};{qName.Name}"; - } - - public static string GetNodeClass(this NodeModel nodeModel) - { - var type = nodeModel.GetType().Name; - var nodeClass = type.Substring(0, type.Length - "Model".Length); - return nodeClass; - } - - } - -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelUtils.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelUtils.cs deleted file mode 100644 index f2a2e8bd..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeModelUtils.cs +++ /dev/null @@ -1,489 +0,0 @@ -using Opc.Ua; -using export = Opc.Ua.Export; -using System.Collections.Generic; -using System.Xml; -using System.Linq; -using CESMII.OpcUa.NodeSetModel.Export.Opc; -using System; -using Microsoft.Extensions.Logging; -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.IO; -using System.Text; -using System.Threading.Tasks; -using System.Threading; - -namespace CESMII.OpcUa.NodeSetModel.Factory.Opc -{ - public static class NodeModelUtils - { - public static string GetNodeIdIdentifier(string nodeId) - { - return nodeId.Substring(nodeId.LastIndexOf(';') + 1); - } - - public static string GetNamespaceFromNodeId(string nodeId) - { - var parsedNodeId = ExpandedNodeId.Parse(nodeId); - var namespaceUri = parsedNodeId.NamespaceUri; - return namespaceUri; - } - - public static string JsonEncodeVariant(Variant value, bool reencodeExtensionsAsJson = false) - { - return JsonEncodeVariant(null, value, null, reencodeExtensionsAsJson = false).Json; - } - public static string JsonEncodeVariant(ISystemContext systemContext, Variant value, bool reencodeExtensionsAsJson = false) - { - return JsonEncodeVariant(systemContext, value, null, reencodeExtensionsAsJson).Json; - } - public static (string Json, bool IsScalar) JsonEncodeVariant(ISystemContext systemContext, Variant value, DataTypeModel dataType, bool reencodeExtensionsAsJson = false, bool encodeJsonScalarsAsValues = false) - { - bool isScalar = false; - - ServiceMessageContext context; - if (systemContext != null) - { - context = new ServiceMessageContext { NamespaceUris = systemContext.NamespaceUris, Factory = systemContext.EncodeableFactory }; - } - else - { - context = ServiceMessageContext.GlobalContext; - } - if (reencodeExtensionsAsJson) - { - if (dataType != null && systemContext.EncodeableFactory is DynamicEncodeableFactory lookupContext) - { - lookupContext.AddEncodingsForDataType(dataType, systemContext.NamespaceUris); - } - - // Reencode extension objects as JSON - if (value.Value is ExtensionObject extObj && extObj.Encoding == ExtensionObjectEncoding.Xml && extObj.Body is XmlElement extXmlBody) - { - var xmlDecoder = new XmlDecoder(extXmlBody, context); - var parsedBody = xmlDecoder.ReadExtensionObjectBody(extObj.TypeId); - value.Value = new ExtensionObject(extObj.TypeId, parsedBody); - } - else if (value.Value is ExtensionObject[] extObjList && extObjList.Any(e => e.Encoding == ExtensionObjectEncoding.Xml && e.Body is XmlElement)) - { - var newExtObjList = new ExtensionObject[extObjList.Length]; - int i = 0; - bool bReencoded = false; - foreach (var extObj2 in extObjList) - { - if (extObj2.Encoding == ExtensionObjectEncoding.Xml && extObj2.Body is XmlElement extObj2XmlBody) - { - var xmlDecoder = new XmlDecoder(extObj2XmlBody, context); - var parsedBody = xmlDecoder.ReadExtensionObjectBody(extObj2.TypeId); - newExtObjList[i] = new ExtensionObject(extObj2.TypeId, parsedBody); - bReencoded = true; - } - else - { - newExtObjList[i] = extObj2; - } - i++; - } - if (bReencoded) - { - value.Value = newExtObjList; - } - } - else if (value.Value is byte[] byteArray && value.TypeInfo.BuiltInType == BuiltInType.ByteString && dataType?.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Byte}")== true) - { - // The XML decoder returns byte arrays as a bytestring variant: fix it up so we don't get a base64 encoded JSON value - value = new Variant(byteArray, new TypeInfo(BuiltInType.Byte, ValueRanks.OneDimension)); - } - } - using (var encoder = new JsonEncoder(context, true)) - { - encoder.ForceNamespaceUri = true; - encoder.ForceNamespaceUriForIndex1 = true; - encoder.WriteVariant("Value", value); - - var encodedVariant = encoder.CloseAndReturnText(); - var parsedValue = JsonConvert.DeserializeObject(encodedVariant, new JsonSerializerSettings { Formatting = Newtonsoft.Json.Formatting.None }); - - string encodedValue; - NodeModelOpcExtensions.JsonValueType jsonValueType; - if (encodeJsonScalarsAsValues && dataType != null && - ((jsonValueType = dataType.GetJsonValueType()) == NodeModelOpcExtensions.JsonValueType.Value || jsonValueType == NodeModelOpcExtensions.JsonValueType.String)) - { - isScalar = true; - if (parsedValue["Value"]["Body"] is JValue jValue) - { - if (jValue.Value is string stringValue) - { - encodedValue = stringValue; - } - else if (jValue.Value is bool boolValue) - { - // Ensure proper casing, ToString() return True/False vs. json's true/false - encodedValue = JsonConvert.SerializeObject(jValue, Newtonsoft.Json.Formatting.None); - } - else - { - encodedValue = JsonConvert.SerializeObject(jValue, Newtonsoft.Json.Formatting.None); - encodedValue = encodedValue.Trim('"'); - var encodedValue2 = jValue.Value?.ToString(); - if (encodedValue != encodedValue2 && !(jValue.Value is DateTime)) - { - - } - } - } - else if (parsedValue["Value"]["Body"] is JArray jArray) - { - encodedValue = JsonConvert.SerializeObject(jArray, Newtonsoft.Json.Formatting.None); - } - else - { - encodedValue = null; - } - if (encodedValue.Length >= 2 && encodedValue.StartsWith("\"") && encodedValue.EndsWith("'\"")) - { - encodedValue = encodedValue.Substring(1, encodedValue.Length - 2); - } - } - else - { - encodedValue = parsedValue["Value"]?.ToString(Newtonsoft.Json.Formatting.None); - } - - return (encodedValue, isScalar); - } - } - - //private static Dictionary ParseStructureValues(XmlElement extXmlBody, int nestingLevel) - //{ - // if (nestingLevel > 100) - // { - // throw new System.Exception("Nested structure of more than 100 levels not supported."); - // } - // Dictionary defaultValues = new Dictionary(); - // foreach (var child in extXmlBody.ChildNodes) - // { - // if (child is XmlElement elementChild) - // { - // if (elementChild.ChildNodes.OfType().Any()) - // { - // defaultValues.Add(elementChild.Name, ParseStructureValues(elementChild, nestingLevel + 1)); - // } - // else - // { - // defaultValues.Add(elementChild.Name, elementChild.InnerText); - // } - // } - // } - // return defaultValues; - //} - - public static Variant JsonDecodeVariant(string jsonVariant, IServiceMessageContext context, DataTypeModel dataType = null, bool EncodeJsonScalarsAsString = false) - { - if (jsonVariant == null) - { - return Variant.Null; - } - if ((jsonVariant?.TrimStart()?.StartsWith("{\"Value\"") == false)) - { - NodeModelOpcExtensions.JsonValueType? jsonValueType; - if (EncodeJsonScalarsAsString && ((jsonValueType = dataType?.GetJsonValueType()) == NodeModelOpcExtensions.JsonValueType.Value || jsonValueType == NodeModelOpcExtensions.JsonValueType.String)) - { - uint? dataTypeId = null; - if (dataType.HasBaseType($"nsu={Namespaces.OpcUa};{DataTypeIds.Enumeration}")) - { - dataTypeId = DataTypes.Int32; - } - else - { - var dtNodeId = ExpandedNodeId.Parse(dataType.NodeId, context.NamespaceUris); - var builtInType = TypeInfo.GetBuiltInType(dtNodeId, new PartialTypeTree(dataType, context.NamespaceUris)); - if (builtInType != BuiltInType.Null) - { - dataTypeId = (uint)builtInType; - } - - else - { - if (dtNodeId.IdType == IdType.Numeric && dtNodeId.NamespaceIndex == 0) - { - dataTypeId = (uint)dtNodeId.Identifier; - } - } - } - if (dataTypeId != null) - { - // TODO more reliable check for array (handle a scalar string that starts with [ ). - if (jsonValueType == NodeModelOpcExtensions.JsonValueType.String && !jsonVariant.StartsWith("[")) - { - // encode and quote it - jsonVariant = JsonConvert.ToString(jsonVariant); - } - jsonVariant = $"{{\"Value\":{{\"Type\":{dataTypeId},\"Body\":{jsonVariant}}}}}"; - } - } - else - { - jsonVariant = $"{{\"Value\":{jsonVariant}"; - } - } - using (var decoder = new JsonDecoder(jsonVariant, context)) - { - var variant = decoder.ReadVariant("Value"); - return variant; - } - } - public static XmlElement JsonDecodeVariantToXml(string jsonVariant, IServiceMessageContext context, DataTypeModel dataType = null, bool EncodeJsonScalarsAsString = false) - { - var variant = JsonDecodeVariant(jsonVariant, context, dataType, EncodeJsonScalarsAsString); - var xml = GetVariantAsXML(variant, context); - return xml; - } - - public static System.Xml.XmlElement GetExtensionObjectAsXML(object extensionBody) - { - var extension = new ExtensionObject(extensionBody); - var context = new ServiceMessageContext(); - var ms = new System.IO.MemoryStream(); - using (var xmlWriter = new System.Xml.XmlTextWriter(ms, System.Text.Encoding.UTF8)) - { - xmlWriter.WriteStartDocument(); - - using (var encoder = new XmlEncoder(new System.Xml.XmlQualifiedName("uax:ExtensionObject", null), xmlWriter, context)) - { - encoder.WriteExtensionObject(null, extension); - xmlWriter.WriteEndDocument(); - xmlWriter.Flush(); - } - } - var xml = System.Text.Encoding.UTF8.GetString(ms.ToArray()); - var doc = new System.Xml.XmlDocument(); - doc.LoadXml(xml.Substring(1)); - var xmlElem = doc.DocumentElement; - return xmlElem; - } - public static System.Xml.XmlElement EncodeAsXML(Action encode) - { - var context = new ServiceMessageContext(); - var ms = new System.IO.MemoryStream(); - using (var xmlWriter = new System.Xml.XmlTextWriter(ms, System.Text.Encoding.UTF8)) - { - xmlWriter.WriteStartDocument(); - - using (var encoder = new XmlEncoder(new System.Xml.XmlQualifiedName("uax:ExtensionObject", null), xmlWriter, context)) - { - encode(encoder); - xmlWriter.WriteEndDocument(); - xmlWriter.Flush(); - } - } - var xml = System.Text.Encoding.UTF8.GetString(ms.ToArray()); - var doc = new System.Xml.XmlDocument(); - // Skip any BOM markers or the XML loader fails - doc.LoadXml(xml[0] > 255 ? xml.Substring(1) : xml); - var xmlElem = doc.DocumentElement; - return xmlElem; - } - - public static System.Xml.XmlElement GetVariantAsXML(Variant value, IServiceMessageContext context) - { - var ms = new System.IO.MemoryStream(); - using (var xmlWriter = new System.Xml.XmlTextWriter(ms, System.Text.Encoding.UTF8)) - { - xmlWriter.WriteStartDocument(); - using (var encoder = new XmlEncoder(new System.Xml.XmlQualifiedName("myRoot"/*, "http://opcfoundation.org/UA/2008/02/Types.xsd"*/), xmlWriter, context)) - { - encoder.WriteVariant("value", value); - xmlWriter.WriteEndDocument(); - xmlWriter.Flush(); - } - } - var xml = System.Text.Encoding.UTF8.GetString(ms.ToArray()); - var doc = new System.Xml.XmlDocument(); - - doc.LoadXml(xml.Substring(1)); - var xmlElem = doc.DocumentElement; - var xmlValue = xmlElem.FirstChild?.FirstChild?.FirstChild as System.Xml.XmlElement; - return xmlValue; - } - - public static ServiceMessageContext GetContextWithDynamicEncodeableFactory(DataTypeModel dataType, NamespaceTable namespaces) - { - DynamicEncodeableFactory dynamicFactory = new(EncodeableFactory.GlobalFactory); - dynamicFactory.AddEncodingsForDataType(dataType, namespaces); - var messageContext = new ServiceMessageContext { Factory = dynamicFactory, NamespaceUris = namespaces }; - return messageContext; - } - - /// - /// Reads a missing nodeset version from a NamespaceVersion object - /// - /// - public static void FixupNodesetVersionFromMetadata(export.UANodeSet nodeSet, ILogger logger) - { - if (nodeSet?.Models == null) - { - return; - } - foreach (var model in nodeSet.Models) - { - if (string.IsNullOrEmpty(model.Version)) - { - var namespaceVersionObject = nodeSet.Items?.FirstOrDefault(n => n is export.UAVariable && n.BrowseName == BrowseNames.NamespaceVersion) as export.UAVariable; - var version = namespaceVersionObject?.Value?.InnerText; - if (!string.IsNullOrEmpty(version)) - { - model.Version = version; - if (logger != null) - { - logger.LogWarning($"Nodeset {model.ModelUri} did not specify a version, but contained a NamespaceVersion property with value {version}."); - } - } - } - } - } - - public static DataTypeModel GetDataTypeModel(IOpcUaContext opcContext, Variant field) - { - var builtinType = field.TypeInfo.BuiltInType; - var dataTypeNodeId = opcContext.GetModelNodeId(new NodeId((uint)builtinType)); - var dataTypeModel = opcContext.GetModelForNode(dataTypeNodeId); - return dataTypeModel; - } - - public static string ReadHeaderComment(string nodeSetXml) - { - string headerComments = ""; - using (var nodesetXmlReader = new StringReader(nodeSetXml)) - { - var firstLine = nodesetXmlReader.ReadLine(); - if (!firstLine.StartsWith("")); - sbHeaderComment.AppendLine(firstLine); - headerComments = sbHeaderComment.ToString(); - } - //var doc = XElement.Load(nodesetXmlReader); - //var comments = doc.DescendantNodes().OfType(); - //foreach (XComment comment in comments) - //{ - // //inline XML Commments are not showing here...only real XML comments (not file comments with /**/) - // //Unfortunately all OPC UA License Comments are not using XML Comments but file-comments and therefore cannot be "preserved" - //} - } - return headerComments; - } - - private class PartialTypeTree : ITypeTable - { - private DataTypeModel _dataType; - private NamespaceTable _namespaceUris; - - public PartialTypeTree(DataTypeModel dataType, NamespaceTable namespaceUris) - { - this._dataType = dataType; - this._namespaceUris = namespaceUris; - } - - public NodeId FindSuperType(NodeId typeId) - { - var type = this._dataType; - do - { - if (ExpandedNodeId.Parse(type.NodeId, _namespaceUris) == typeId) - { - return ExpandedNodeId.Parse(type.SuperType.NodeId, _namespaceUris); - } - type = type.SuperType as DataTypeModel; - } while (type != null); - return null; - } - public Task FindSuperTypeAsync(NodeId typeId, CancellationToken ct = default) - { - return Task.FromResult(FindSuperType(typeId)); - } - - - public NodeId FindDataTypeId(ExpandedNodeId encodingId) - { - throw new NotImplementedException(); - } - - public NodeId FindDataTypeId(NodeId encodingId) - { - throw new NotImplementedException(); - } - - public NodeId FindReferenceType(QualifiedName browseName) - { - throw new NotImplementedException(); - } - - public QualifiedName FindReferenceTypeName(NodeId referenceTypeId) - { - throw new NotImplementedException(); - } - - public IList FindSubTypes(ExpandedNodeId typeId) - { - throw new NotImplementedException(); - } - - public NodeId FindSuperType(ExpandedNodeId typeId) - { - throw new NotImplementedException(); - } - public Task FindSuperTypeAsync(ExpandedNodeId typeId, CancellationToken ct = default) - { - throw new NotImplementedException(); - } - - - public bool IsEncodingFor(NodeId expectedTypeId, ExtensionObject value) - { - throw new NotImplementedException(); - } - - public bool IsEncodingFor(NodeId expectedTypeId, object value) - { - throw new NotImplementedException(); - } - - public bool IsEncodingOf(ExpandedNodeId encodingId, ExpandedNodeId datatypeId) - { - throw new NotImplementedException(); - } - - public bool IsKnown(ExpandedNodeId typeId) - { - throw new NotImplementedException(); - } - - public bool IsKnown(NodeId typeId) - { - throw new NotImplementedException(); - } - - public bool IsTypeOf(ExpandedNodeId subTypeId, ExpandedNodeId superTypeId) - { - throw new NotImplementedException(); - } - - public bool IsTypeOf(NodeId subTypeId, NodeId superTypeId) - { - throw new NotImplementedException(); - } - } - } - -} diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSetResolverException.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSetResolverException.cs deleted file mode 100644 index 5c12bd9b..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSetResolverException.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace CESMII.OpcUa.NodeSetModel.Factory.Opc -{ - [Serializable] - public class NodeSetResolverException : Exception - { - public NodeSetResolverException() - { - } - - public NodeSetResolverException(string message) : base(message) - { - } - - public NodeSetResolverException(string message, Exception innerException) : base(message, innerException) - { - } - - protected NodeSetResolverException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - } -} diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA original.csv b/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA original.csv deleted file mode 100644 index 253b0511..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA original.csv +++ /dev/null @@ -1,1828 +0,0 @@ -UNECECode,UnitId,DisplayName,Description -C81,4405297,"rad","radian" -C25,4403765,"mrad","milliradian" -B97,4340023,"µrad","microradian" -DD,17476,"°","degree [unit of angle]" -D61,4470321,"'","minute [unit of angle]" -D62,4470322,"""","second [unit of angle]" -A91,4274481,"gon","gon" -M43,5059635,"mil","mil" -M44,5059636,"rev","revolution" -D27,4469303,"sr","steradian" -H57,4732215,"in/revolution","inch per two pi radiant" -MTR,5067858,"m","metre" -E96,4536630,"°/s","degree per second" -H27,4731447,"°/m","degree per metre" -M55,5059893,"m/rad","metre per radiant" -DMT,4476244,"dm","decimetre" -CMT,4410708,"cm","centimetre" -4H,13384,"µm","micrometre (micron)" -MMT,5066068,"mm","millimetre" -HMT,4738388,"hm","hectometre" -KMT,4934996,"km","kilometre" -C45,4404277,"nm","nanometre" -C52,4404530,"pm","picometre" -A71,4273969,"fm","femtometre" -A45,4273205,"dam","decametre" -NMI,5131593,"n mile","nautical mile" -A11,4272433,"Å","angstrom" -A12,4272434,"ua","astronomical unit" -C63,4404787,"pc","parsec" -F52,4601138,"m/K","metre per kelvin" -F50,4601136,"µm/K","micrometre per kelvin" -F51,4601137,"cm/K","centimetre per kelvin" -G06,4665398,"mm/bar","millimetre per bar" -H84,4732980,"g·mm","gram millimetre" -G04,4665396,"cm/bar","centimetre per bar" -G05,4665397,"m/bar","metre per bar" -H79,4732729,"Fg","French gauge" -AK,16715,"fth","fathom" -X1,22577,"ch (UK)","Gunter's chain" -INH,4804168,"in","inch" -M7,19767,"µin","micro-inch" -FOT,4607828,"ft","foot" -YRD,5853764,"yd","yard" -SMI,5459273,"mile","mile (statute mile)" -77,14135,"mil","milli-inch" -B57,4338999,"ly","light year" -F49,4600889,"rd (US)","rod [unit of distance]" -MAM,5062989,"Mm","megametre" -K13,4927795,"ft/°F","foot per degree Fahrenheit" -K17,4927799,"ft/psi","foot per psi" -K45,4928565,"in/°F","inch per degree Fahrenheit" -K46,4928566,"in/psi","inch per psi" -L98,4995384,"yd/°F","yard per degree Fahrenheit" -L99,4995385,"yd/psi","yard per psi" -M49,5059641,"ch (US survey)","chain (based on U.S. survey foot)" -M50,5059888,"fur","furlong" -M51,5059889,"ft (US survey)","foot (U.S. survey)" -M52,5059890,"mi (US survey)","mile (based on U.S. survey foot)" -M53,5059891,"m/Pa","metre per pascal" -MTK,5067851,"m²","square metre" -KMK,4934987,"km²","square kilometre" -H30,4731696,"µm²","square micrometre (square micron)" -H59,4732217,"m²/N","square metre per newton" -DAA,4473153,"daa","decare" -CMK,4410699,"cm²","square centimetre" -DMK,4476235,"dm²","square decimetre" -H16,4731190,"dam²","square decametre" -H18,4731192,"hm²","square hectometre" -MMK,5066059,"mm²","square millimetre" -ARE,4280901,"a","are" -HAR,4735314,"ha","hectare" -INK,4804171,"in²","square inch" -FTK,4609099,"ft²","square foot" -YDK,5850187,"yd²","square yard" -MIK,5065035,"mi²","square mile (statute mile)" -M48,5059640,"mi² (US survey)","square mile (based on U.S. survey foot)" -ACR,4277074,"acre","acre" -M47,5059639,"cmil","circular mil" -MTQ,5067857,"m³","cubic metre" -MAL,5062988,"Ml","megalitre" -LTR,5002322,"l","litre" -MMQ,5066065,"mm³","cubic millimetre" -CMQ,4410705,"cm³","cubic centimetre" -DMQ,4476241,"dm³","cubic decimetre" -MLT,5065812,"ml","millilitre" -HLT,4738132,"hl","hectolitre" -CLT,4410452,"cl","centilitre" -DMA,4476225,"dam³","cubic decametre" -H19,4731193,"hm³","cubic hectometre" -H20,4731440,"km³","cubic kilometre" -M71,5060401,"m³/Pa","cubic metre per pascal" -DLT,4475988,"dl","decilitre" -4G,13383,"µl","microlitre" -K6,19254,"kl","kilolitre" -A44,4273204,"dal","decalitre" -G94,4667700,"cm³/bar","cubic centimetre per bar" -G95,4667701,"l/bar","litre per bar" -G96,4667702,"m³/bar","cubic metre per bar" -G97,4667703,"ml/bar","millilitre per bar" -INQ,4804177,"in³","cubic inch" -FTQ,4609105,"ft³","cubic foot" -YDQ,5850193,"yd³","cubic yard" -GLI,4672585,"gal (UK)","gallon (UK)" -GLL,4672588,"gal (US)","gallon (US)" -PT,20564,"pt (US)","pint (US)" -PTI,5264457,"pt (UK)","pint (UK)" -QTI,5329993,"qt (UK)","quart (UK)" -PTL,5264460,"liq pt (US)","liquid pint (US)" -QTL,5329996,"liq qt (US)","liquid quart (US)" -PTD,5264452,"dry pt (US)","dry pint (US)" -OZI,5200457,"fl oz (UK)","fluid ounce (UK)" -QT,20820,"qt (US)","quart (US)" -J57,4863287,"bbl (UK liq.)","barrel (UK petroleum)" -K21,4928049,"ft³/°F","cubic foot per degree Fahrenheit" -K23,4928051,"ft³/psi","cubic foot per psi" -L43,4994099,"pk (UK)","peck (UK)" -L84,4995124,"British shipping ton","ton (UK shipping)" -L86,4995126,"(US) shipping ton","ton (US shipping)" -M11,5058865,"yd³/°F","cubic yard per degree Fahrenheit" -M14,5058868,"yd³/psi","cubic yard per psi" -OZA,5200449,"fl oz (US)","fluid ounce (US)" -BUI,4347209,"bushel (UK)","bushel (UK)" -BUA,4347201,"bu (US)","bushel (US)" -BLL,4344908,"barrel (US)","barrel (US)" -BLD,4344900,"bbl (US)","dry barrel (US)" -GLD,4672580,"dry gal (US)","dry gallon (US)" -QTD,5329988,"dry qt (US)","dry quart (US)" -G26,4665910,"st","stere" -G21,4665905,"cup (US)","cup [unit of volume]" -G24,4665908,"tablespoon (US)","tablespoon (US)" -G25,4665909,"teaspoon (US)","teaspoon (US)" -G23,4665907,"pk (US)","peck" -M67,5060151,"acre-ft (US survey)","acre-foot (based on U.S. survey foot)" -M68,5060152,"cord","cord (128 ft3)" -M69,5060153,"mi³","cubic mile (UK statute)" -M70,5060400,"RT","ton, register" -G27,4665911,"cm³/K","cubic centimetre per kelvin" -G29,4665913,"m³/K","cubic metre per kelvin" -G28,4665912,"l/K","litre per kelvin" -G30,4666160,"ml/K","millilitre per kelvin" -J36,4862774,"µl/l","microlitre per litre" -J87,4864055,"cm³/m³","cubic centimetre per cubic metre" -J91,4864305,"dm³/m³","cubic decimetre per cubic metre" -K62,4929074,"l/l","litre per litre" -L19,4993337,"ml/l","millilitre per litre" -L21,4993585,"mm³/m³","cubic millimetre per cubic metre" -SEC,5457219,"s","second [unit of time]" -MIN,5065038,"min","minute [unit of time]" -HUR,4740434,"h","hour" -DAY,4473177,"d","day" -B52,4338994,"ks","kilosecond" -C26,4403766,"ms","millisecond" -H70,4732720,"ps","picosecond" -B98,4340024,"µs","microsecond" -C47,4404279,"ns","nanosecond" -WEE,5719365,"wk","week" -MON,5066574,"mo","month" -ANN,4279886,"y","year" -D42,4469810,"y (tropical)","tropical year" -L95,4995381,"y (365 days)","common year" -L96,4995382,"y (sidereal)","sidereal year" -M56,5059894,"shake","shake" -2A,12865,"rad/s","radian per second" -M46,5059638,"r/min","revolution per minute" -2B,12866,"rad/s²","radian per second squared" -M45,5059637,"°/s²","degree [unit of angle] per second squared" -MTS,5067859,"m/s","metre per second" -KNT,4935252,"kn","knot" -KMH,4934984,"km/h","kilometre per hour" -C16,4403510,"mm/s","millimetre per second" -2M,12877,"cm/s","centimetre per second" -H49,4731961,"cm/h","centimetre per hour" -H81,4732977,"mm/min","millimetre per minute" -2X,12888,"m/min","metre per minute" -M59,5059897,"(m/s)/Pa","metre per second pascal" -H66,4732470,"mm/y","millimetre per year" -H67,4732471,"mm/h","millimetre per hour" -FR,18002,"ft/min","foot per minute" -IU,18773,"in/s","inch per second" -FS,18003,"ft/s","foot per second" -HM,18509,"mile/h","mile per hour (statute mile)" -J84,4864052,"(cm/s)/K","centimetre per second kelvin" -J85,4864053,"(cm/s)/bar","centimetre per second bar" -K14,4927796,"ft/h","foot per hour" -K18,4927800,"(ft/s)/°F","foot per second degree Fahrenheit" -K19,4927801,"(ft/s)/psi","foot per second psi" -K47,4928567,"(in/s)/°F","inch per second degree Fahrenheit" -K48,4928568,"(in/s)/psi","inch per second psi" -L12,4993330,"(m/s)/K","metre per second kelvin" -L13,4993331,"(m/s)/bar","metre per second bar" -M22,5059122,"(ml/min)/cm²","millilitre per square centimetre minute" -M57,5059895,"mi/min","mile per minute" -M58,5059896,"mi/s","mile per second" -M60,5060144,"m/h","metre per hour" -M61,5060145,"in/y","inch per year" -M62,5060146,"km/s","kilometre per second" -M63,5060147,"in/min","inch per minute" -M64,5060148,"yd/s","yard per second" -M65,5060149,"yd/min","yard per minute" -M66,5060150,"yd/h","yard per hour" -MSK,5067595,"m/s²","metre per second squared" -A76,4273974,"Gal","gal" -C11,4403505,"mGal","milligal" -M38,5059384,"km/s²","kilometre per second squared" -M39,5059385,"cm/s²","centimetre per second squared" -M41,5059633,"mm/s²","millimetre per second squared" -A73,4273971,"ft/s²","foot per second squared" -IV,18774,"in/s²","inch per second squared" -K40,4928560,"gn","standard acceleration of free fall" -M40,5059632,"yd/s²","yard per second squared" -M42,5059634,"mi/s²","mile (statute mile) per second squared" -C92,4405554,"m⁻¹","reciprocal metre" -Q32,5321522,"fl","femtolitre" -Q33,5321523,"pl","picolitre" -Q34,5321524,"nl","nanolitre" -AWG,4282183,"AWG","american wire gauge" -NM3,5131571,"Normalised cubic metre","Normalised cubic metre" -SM3,5459251,"Standard cubic metre","Standard cubic metre" -HTZ,4740186,"Hz","hertz" -KHZ,4933722,"kHz","kilohertz" -MHZ,5064794,"MHz","megahertz" -D29,4469305,"THz","terahertz" -A86,4274230,"GHz","gigahertz" -MTZ,5067866,"mHz","millihertz" -H10,4731184,"1/h","reciprocal hour" -H11,4731185,"1/mo","reciprocal month" -H09,4730937,"1/y","reciprocal year" -H85,4732981,"1/wk","reciprocal week" -C97,4405559,"s⁻¹","reciprocal second" -RPS,5394515,"r/s","revolutions per second" -RPM,5394509,"r/min","revolutions per minute" -C94,4405556,"min⁻¹","reciprocal minute" -C50,4404528,"Np","neper" -2N,12878,"dB","decibel" -M72,5060402,"B","bel" -C51,4404529,"Np/s","neper per second" -KGM,4933453,"kg","kilogram" -MC,19779,"µg","microgram" -DJ,17482,"dag","decagram" -DG,17479,"dg","decigram" -GRM,4674125,"g","gram" -CGM,4409165,"cg","centigram" -TNE,5525061,"t","tonne (metric ton)" -DTN,4478030,"dt or dtn","decitonne" -MGM,5064525,"mg","milligram" -HGM,4736845,"hg","hectogram" -KTN,4936782,"kt","kilotonne" -2U,12885,"Mg","megagram" -LBR,4997714,"lb","pound" -GRN,4674126,"gr","grain" -ONZ,5197402,"oz","ounce (avoirdupois)" -CWI,4413257,"cwt (UK)","hundred weight (UK)" -CWA,4413249,"cwt (US)","hundred pound (cwt) / hundred weight (US)" -LTN,5002318,"ton (UK)","ton (UK) or long ton (US)" -STI,5461065,"st","stone (UK)" -STN,5461070,"ton (US)","ton (US) or short ton (UK/US)" -APZ,4280410,"tr oz","troy ounce or apothecary ounce" -F13,4600115,"slug","slug" -K64,4929076,"lb/°F","pound (avoirdupois) per degree Fahrenheit" -L69,4994617,"t/K","tonne per kelvin" -L87,4995127,"ton (US)/°F","ton short per degree Fahrenheit" -M85,5060661,"ton, assay","ton, assay" -M86,5060662,"pfd","pfund" -KMQ,4934993,"kg/m³","kilogram per cubic metre" -23,12851,"g/cm³","gram per cubic centimetre" -D41,4469809,"t/m³","tonne per cubic metre" -GJ,18250,"g/ml","gram per millilitre" -B35,4338485,"kg/l or kg/L","kilogram per litre" -GL,18252,"g/l","gram per litre" -A93,4274483,"g/m³","gram per cubic metre" -GP,18256,"mg/m³","milligram per cubic metre" -B72,4339506,"Mg/m³","megagram per cubic metre" -B34,4338484,"kg/dm³","kilogram per cubic decimetre" -H64,4732468,"mg/g","milligram per gram" -H29,4731449,"µg/l","microgram per litre" -M1,19761,"mg/l","milligram per litre" -GQ,18257,"µg/m³","microgram per cubic metre" -G11,4665649,"g/(cm³·bar)","gram per cubic centimetre bar" -G33,4666163,"g/(cm³·K)","gram per cubic centimetre kelvin" -F23,4600371,"g/dm³","gram per cubic decimetre" -G12,4665650,"g/(dm³·bar)","gram per cubic decimetre bar" -G34,4666164,"g/(dm³·K)","gram per cubic decimetre kelvin" -G14,4665652,"g/(m³·bar)","gram per cubic metre bar" -G36,4666166,"g/(m³·K)","gram per cubic metre kelvin" -G13,4665651,"g/(l·bar)","gram per litre bar" -G35,4666165,"g/(l·K)","gram per litre kelvin" -G15,4665653,"g/(ml·bar)","gram per millilitre bar" -G37,4666167,"g/(ml·K)","gram per millilitre kelvin" -G31,4666161,"kg/cm³","kilogram per cubic centimetre" -G16,4665654,"kg/(cm³·bar)","kilogram per cubic centimetre bar" -G38,4666168,"kg/(cm³·K)","kilogram per cubic centimetre kelvin" -G18,4665656,"kg/(m³·bar)","kilogram per cubic metre bar" -G40,4666416,"kg/(m³·K)","kilogram per cubic metre kelvin" -H54,4732212,"(kg/dm³)/K","kilogram per cubic decimetre kelvin" -H55,4732213,"(kg/dm³)/bar","kilogram per cubic decimetre bar" -F14,4600116,"g/K","gram per kelvin" -F15,4600117,"kg/K","kilogram per kelvin" -F24,4600372,"kg/kmol","kilogram per kilomole" -G17,4665655,"kg/(l·bar)","kilogram per litre bar" -G39,4666169,"kg/(l·K)","kilogram per litre kelvin" -H53,4732211,"kg/bar","kilogram per bar" -F18,4600120,"kg·cm²","kilogram square centimetre" -F19,4600121,"kg·mm²","kilogram square millimetre" -F74,4601652,"g/bar","gram per bar" -F75,4601653,"mg/bar","milligram per bar" -F16,4600118,"mg/K","milligram per kelvin" -M73,5060403,"(kg/m³)/Pa","kilogram per cubic metre pascal" -87,14391,"lb/ft³","pound per cubic foot" -GE,18245,"lb/gal (US)","pound per gallon (US)" -LA,19521,"lb/in³","pound per cubic inch" -G32,4666162,"oz/yd³","ounce (avoirdupois) per cubic yard" -J34,4862772,"(µg/m³)/K","microgram per cubic metre kelvin" -J35,4862773,"(µg/m³)/bar","microgram per cubic metre bar" -K41,4928561,"gr/gal (US)","grain per gallon (US)" -K69,4929081,"(lb/ft³)/°F","pound (avoirdupois) per cubic foot degree Fahrenheit" -K70,4929328,"(lb/ft³)/psi","pound (avoirdupois) per cubic foot psi" -K71,4929329,"lb/gal (UK)","pound (avoirdupois) per gallon (UK)" -K75,4929333,"(lb/in³)/°F","pound (avoirdupois) per cubic inch degree Fahrenheit" -K76,4929334,"(lb/in³)/psi","pound (avoirdupois) per cubic inch psi" -K84,4929588,"lb/yd³","pound per cubic yard" -L17,4993335,"(mg/m³)/K","milligram per cubic metre kelvin" -L18,4993336,"(mg/m³)/bar","milligram per cubic metre bar" -L37,4993847,"oz/gal (UK)","ounce (avoirdupois) per gallon (UK)" -L38,4993848,"oz/gal (US)","ounce (avoirdupois) per gallon (US)" -L39,4993849,"oz/in³","ounce (avoirdupois) per cubic inch" -L65,4994613,"slug/ft³","slug per cubic foot" -L76,4994870,"(t/m³)/K","tonne per cubic metre kelvin" -L77,4994871,"(t/m³)/bar","tonne per cubic metre bar" -L92,4995378,"ton.l/yd³ (UK)","ton (UK long) per cubic yard" -L93,4995379,"ton.s/yd³ (US)","ton (US short) per cubic yard" -K77,4929335,"lb/psi","pound (avoirdupois) per psi" -L70,4994864,"t/bar","tonne per bar" -L91,4995377,"ton (US)/psi","ton short per psi" -M74,5060404,"kg/Pa","kilogram per pascal" -C62,4404786,"1","one" -A39,4272953,"m³/kg","cubic metre per kilogram" -22,12850,"dl/g","decilitre per gram" -H65,4732469,"ml/m³","millilitre per cubic metre" -H83,4732979,"l/kg","litre per kilogram" -KX,19288,"ml/kg","millilitre per kilogram" -H15,4731189,"cm²/g","square centimetre per gram" -N28,5124664,"dm³/kg","cubic decimetre per kilogram" -N29,5124665,"ft³/lb","cubic foot per pound" -N30,5124912,"in³/lb","cubic inch per pound" -KL,19276,"kg/m","kilogram per metre" -GF,18246,"g/m","gram per metre (gram per 100 centimetres)" -H76,4732726,"g/mm","gram per millimetre" -KW,19287,"kg/mm","kilogram per millimetre" -C12,4403506,"mg/m","milligram per metre" -M31,5059377,"kg/km","kilogram per kilometre" -P2,20530,"lb/ft","pound per foot" -PO,20559,"lb/in","pound per inch of length" -M83,5060659,"den","denier" -M84,5060660,"lb/yd","pound per yard" -GO,18255,"mg/m²","milligram per square metre" -25,12853,"g/cm²","gram per square centimetre" -H63,4732467,"mg/cm²","milligram per square centimetre" -GM,18253,"g/m²","gram per square metre" -28,12856,"kg/m²","kilogram per square metre" -D5,17461,"kg/cm²","kilogram per square centimetre" -ON,20302,"oz/yd²","ounce per square yard" -37,13111,"oz/ft²","ounce per square foot" -B31,4338481,"kg·m/s","kilogram metre per second" -M98,5060920,"kg·(cm/s)","kilogram centimetre per second" -M99,5060921,"g·(cm/s)","gram centimetre per second" -N10,5124400,"lb·(ft/s)","pound foot per second" -N11,5124401,"lb·(in/s)","pound inch per second" -B33,4338483,"kg·m²/s","kilogram metre squared per second" -B32,4338482,"kg·m²","kilogram metre squared" -F20,4600368,"lb·in²","pound inch squared" -K65,4929077,"lb·ft²","pound (avoirdupois) square foot" -NEW,5129559,"N","newton" -B73,4339507,"MN","meganewton" -B47,4338743,"kN","kilonewton" -C20,4403760,"mN","millinewton" -B92,4340018,"µN","micronewton" -DU,17493,"dyn","dyne" -C78,4405048,"lbf","pound-force" -B37,4338487,"kgf","kilogram-force" -B51,4338993,"kp","kilopond" -L40,4994096,"ozf","ounce (avoirdupois)-force" -L94,4995380,"ton.sh-force","ton-force (US short)" -M75,5060405,"kip","kilopound-force" -M76,5060406,"pdl","poundal" -M77,5060407,"kg·m/s²","kilogram metre per second squared" -M78,5060408,"p","pond" -F17,4600119,"lbf/ft","pound-force per foot" -F48,4600888,"lbf/in","pound-force per inch" -C54,4404532,"N·m²/kg²","newton metre squared per kilogram squared" -NU,20053,"N·m","newton metre" -H40,4731952,"N/A","newton per ampere" -B74,4339508,"MN·m","meganewton metre" -B48,4338744,"kN·m","kilonewton metre" -D83,4470835,"mN·m","millinewton metre" -B93,4340019,"µN·m","micronewton metre" -DN,17486,"dN·m","decinewton metre" -J72,4863794,"cN·m","centinewton metre" -M94,5060916,"kg·m","kilogram metre" -F88,4601912,"N·cm","newton centimetre" -F90,4602160,"N·m/A","newton metre per ampere" -F89,4601913,"Nm/°","newton metre per degree" -G19,4665657,"N·m/kg","newton metre per kilogram" -F47,4600887,"N/mm","newton per millimetre" -M93,5060915,"N·m/rad","newton metre per radian" -H41,4731953,"N·m·W⁻⁰‧⁵","newton metre watt to the power minus 0,5" -B38,4338488,"kgf·m","kilogram-force metre" -IA,18753,"in·lb","inch pound (pound inch)" -4Q,13393,"oz·in","ounce inch" -4R,13394,"oz·ft","ounce foot" -F22,4600370,"lbf·ft/A","pound-force foot per ampere" -F21,4600369,"lbf·in","pound-force inch" -G20,4665904,"lbf·ft/lb","pound-force foot per pound" -J94,4864308,"dyn·cm","dyne centimetre" -L41,4994097,"ozf·in","ounce (avoirdupois)-force inch" -M92,5060914,"lbf·ft","pound-force foot" -M95,5060917,"pdl·ft","poundal foot" -M96,5060918,"pdl·in","poundal inch" -M97,5060919,"dyn·m","dyne metre" -C57,4404535,"N·s","newton second" -C53,4404531,"N·m·s","newton metre second" -74,14132,"mPa","millipascal" -MPA,5066817,"MPa","megapascal" -PAL,5259596,"Pa","pascal" -KPA,4935745,"kPa","kilopascal" -BAR,4342098,"bar","bar [unit of pressure]" -HBA,4735553,"hbar","hectobar" -MBR,5063250,"mbar","millibar" -KBA,4932161,"kbar","kilobar" -ATM,4281421,"atm","standard atmosphere" -A89,4274233,"GPa","gigapascal" -B96,4340022,"µPa","micropascal" -A97,4274487,"hPa","hectopascal" -H75,4732725,"daPa","decapascal" -B85,4339765,"µbar","microbar" -C55,4404533,"N/m²","newton per square metre" -C56,4404534,"N/mm²","newton per square millimetre" -H07,4730935,"Pa·s/bar","pascal second per bar" -F94,4602164,"hPa·m³/s","hectopascal cubic metre per second" -F93,4602163,"hPa·l/s","hectopascal litre per second" -F82,4601906,"hPa/K","hectopascal per kelvin" -F83,4601907,"kPa/K","kilopascal per kelvin" -F98,4602168,"MPa·m³/s","megapascal cubic metre per second" -F97,4602167,"MPa·l/s","megapascal litre per second" -F85,4601909,"MPa/K","megapascal per kelvin" -F96,4602166,"mbar·m³/s","millibar cubic metre per second" -F95,4602165,"mbar·l/s","millibar litre per second" -F84,4601908,"mbar/K","millibar per kelvin" -G01,4665393,"Pa·m³/s","pascal cubic metre per second" -F99,4602169,"Pa·l/s","pascal litre per second" -F77,4601655,"Pa.s/K","pascal second per kelvin" -E01,4534321,"N/cm²","newton per square centimetre" -FP,18000,"lb/ft²","pound per square foot" -PS,20563,"lbf/in²","pound-force per square inch" -B40,4338736,"kgf/m²","kilogram-force per square metre" -UA,21825,"Torr","torr" -ATT,4281428,"at","technical atmosphere" -80,14384,"lb/in²","pound per square inch absolute" -H78,4732728,"cm H₂O","conventional centimetre of water" -HP,18512,"mm H₂O","conventional millimetre of water" -HN,18510,"mm Hg","conventional millimetre of mercury" -F79,4601657,"inHg","inch of mercury" -F78,4601656,"inH₂O","inch of water" -J89,4864057,"cm Hg","centimetre of mercury" -K24,4928052,"ft H₂O","foot of water" -K25,4928053,"ft Hg","foot of mercury" -K31,4928305,"gf/cm²","gram-force per square centimetre" -E42,4535346,"kgf/cm²","kilogram-force per square centimetre" -E41,4535345,"kgf·m/cm²","kilogram-force per square millimetre" -K85,4929589,"lbf/ft²","pound-force per square foot" -K86,4929590,"psi/°F","pound-force per square inch degree Fahrenheit" -84,14388,"klbf/in²","kilopound-force per square inch" -N13,5124403,"cmHg (0 ºC)","centimetre of mercury (0 ºC)" -N14,5124404,"cmH₂O (4 °C)","centimetre of water (4 ºC)" -N15,5124405,"ftH₂O (39,2 ºF)","foot of water (39.2 ºF)" -N16,5124406,"inHG (32 ºF)","inch of mercury (32 ºF)" -N17,5124407,"inHg (60 ºF)","inch of mercury (60 ºF)" -N18,5124408,"inH₂O (39,2 ºF)","inch of water (39.2 ºF)" -N19,5124409,"inH₂O (60 ºF)","inch of water (60 ºF)" -N20,5124656,"ksi","kip per square inch" -N21,5124657,"pdl/ft²","poundal per square foot" -N22,5124658,"oz/in²","ounce (avoirdupois) per square inch" -N23,5124659,"mH₂O","conventional metre of water" -N24,5124660,"g/mm²","gram per square millimetre" -N25,5124661,"lb/yd²","pound per square yard" -N26,5124662,"pdl/in²","poundal per square inch" -E99,4536633,"hPa/bar","hectopascal per bar" -F05,4599861,"MPa/bar","megapascal per bar" -F04,4599860,"mbar/bar","millibar per bar" -F07,4599863,"Pa/bar","pascal per bar" -F03,4599859,"kPa/bar","kilopascal per bar" -L52,4994354,"psi/psi","psi per psi" -J56,4863286,"bar/bar","bar per bar" -C96,4405558,"Pa⁻¹","reciprocal pascal or pascal to the power minus one" -F58,4601144,"1/bar","reciprocal bar" -B83,4339763,"m⁴","metre to the fourth power" -G77,4667191,"mm⁴","millimetre to the fourth power" -D69,4470329,"in⁴","inch to the fourth power" -N27,5124663,"ft⁴","foot to the fourth power" -C65,4404789,"Pa·s","pascal second" -N37,5124919,"kg/(m·s)","kilogram per metre second" -N38,5124920,"kg/(m·min)","kilogram per metre minute" -C24,4403764,"mPa·s","millipascal second" -N36,5124918,"(N/m²)·s","newton second per square metre" -N39,5124921,"kg/(m·d)","kilogram per metre day" -N40,5125168,"kg/(m·h)","kilogram per metre hour" -N41,5125169,"g/(cm·s)","gram per centimetre second" -89,14393,"P","poise" -C7,17207,"cP","centipoise" -F06,4599862,"P/bar","poise per bar" -F86,4601910,"P/K","poise per kelvin" -J32,4862770,"µP","micropoise" -J73,4863795,"cP/K","centipoise per kelvin" -J74,4863796,"cP/bar","centipoise per bar" -K67,4929079,"lb/(ft·h)","pound per foot hour" -K68,4929080,"lb/(ft·s)","pound per foot second" -K91,4929841,"lbf·s/ft²","pound-force second per square foot" -K92,4929842,"lbf·s/in²","pound-force second per square inch" -L15,4993333,"mPa·s/K","millipascal second per kelvin" -L16,4993334,"mPa·s/bar","millipascal second per bar" -L64,4994612,"slug/(ft·s)","slug per foot second" -N34,5124916,"(pdl/ft²)·s","poundal second per square foot" -N35,5124917,"P/Pa","poise per pascal" -N42,5125170,"(pdl/in²)·s","poundal second per square inch" -N43,5125171,"lb/(ft·min)","pound per foot minute" -N44,5125172,"lb/(ft·d)","pound per foot day" -S4,21300,"m²/s","square metre per second" -M82,5060658,"(m²/s)/Pa","square metre per second pascal" -C17,4403511,"mm²/s","millimetre squared per second" -G41,4666417,"m²/(s·bar)","square metre per second bar" -G09,4665401,"m²/(s·K)","square metre per second kelvin" -91,14641,"St","stokes" -4C,13379,"cSt","centistokes" -G46,4666422,"St/bar","stokes per bar" -G10,4665648,"St/K","stokes per kelvin" -S3,21299,"ft²/s","square foot per second" -G08,4665400,"in²/s","square inch per second" -M79,5060409,"ft²/h","square foot per hour" -M80,5060656,"St/Pa","stokes per pascal" -M81,5060657,"cm²/s","square centimetre per second" -4P,13392,"N/m","newton per metre" -C22,4403762,"mN/m","millinewton per metre" -M23,5059123,"N/cm","newton per centimetre" -N31,5124913,"kN/m","kilonewton per metre" -DX,17496,"dyn/cm","dyne per centimetre" -N32,5124914,"pdl/in","poundal per inch" -N33,5124915,"lbf/yd","pound-force per yard" -M34,5059380,"N·m/m²","newton metre per square metre" -JOU,4869973,"J","joule" -KJO,4934223,"kJ","kilojoule" -A68,4273720,"EJ","exajoule" -C68,4404792,"PJ","petajoule" -D30,4469552,"TJ","terajoule" -GV,18262,"GJ","gigajoule" -3B,13122,"MJ","megajoule" -C15,4403509,"mJ","millijoule" -A70,4273968,"fJ","femtojoule" -A13,4272435,"aJ","attojoule" -WHR,5720146,"W·h","watt hour" -MWH,5068616,"MW·h","megawatt hour (1000 kW.h)" -KWH,4937544,"kW·h","kilowatt hour" -GWH,4675400,"GW·h","gigawatt hour" -D32,4469554,"TW·h","terawatt hour" -A53,4273459,"eV","electronvolt" -B71,4339505,"MeV","megaelectronvolt" -A85,4274229,"GeV","gigaelectronvolt" -B29,4338233,"keV","kiloelectronvolt" -A57,4273463,"erg","erg" -85,14389,"ft·lbf","foot pound-force" -N46,5125174,"ft·pdl","foot poundal" -N47,5125175,"in·pdl","inch poundal" -WTT,5723220,"W","watt" -KWT,4937556,"kW","kilowatt" -MAW,5062999,"MW","megawatt" -A90,4274480,"GW","gigawatt" -C31,4404017,"mW","milliwatt" -D80,4470832,"µW","microwatt" -F80,4601904,"water horse power","water horse power" -A63,4273715,"erg/s","erg per second" -A74,4273972,"ft·lbf/s","foot pound-force per second" -B39,4338489,"kgf·m/s","kilogram-force metre per second" -HJ,18506,"metric hp","metric horse power" -A25,4272693,"CV","cheval vapeur" -BHP,4343888,"BHP","brake horse power" -K15,4927797,"ft·lbf/h","foot pound-force per hour" -K16,4927798,"ft·lbf/min","foot pound-force per minute" -K42,4928562,"boiler hp","horsepower (boiler)" -N12,5124402,"PS","Pferdestaerke" -KGS,4933459,"kg/s","kilogram per second" -H56,4732214,"kg/(m²·s)","kilogram per square metre second" -M87,5060663,"(kg/s)/Pa","kilogram per second pascal" -4M,13389,"mg/h","milligram per hour" -F26,4600374,"g/d","gram per day" -F62,4601394,"g/(d·bar)","gram per day bar" -F35,4600629,"g/(d·K)","gram per day kelvin" -F27,4600375,"g/h","gram per hour" -F63,4601395,"g/(h·bar)","gram per hour bar" -F36,4600630,"g/(h·K)","gram per hour kelvin" -F28,4600376,"g/min","gram per minute" -F64,4601396,"g/(min·bar)","gram per minute bar" -F37,4600631,"g/(min·K)","gram per minute kelvin" -F29,4600377,"g/s","gram per second" -F65,4601397,"g/(s·bar)","gram per second bar" -F38,4600632,"g/(s·K)","gram per second kelvin" -F30,4600624,"kg/d","kilogram per day" -F66,4601398,"kg/(d·bar)","kilogram per day bar" -F39,4600633,"kg/(d·K)","kilogram per day kelvin" -E93,4536627,"kg/h","kilogram per hour" -F67,4601399,"kg/(h·bar)","kilogram per hour bar" -F40,4600880,"kg/(h·K)","kilogram per hour kelvin" -F31,4600625,"kg/min","kilogram per minute" -F68,4601400,"kg/(min·bar)","kilogram per minute bar" -F41,4600881,"kg/(min·K)","kilogram per minute kelvin" -F69,4601401,"kg/(s·bar)","kilogram per second bar" -F42,4600882,"kg/(s·K)","kilogram per second kelvin" -F32,4600626,"mg/d","milligram per day" -F70,4601648,"mg/(d·bar)","milligram per day bar" -F43,4600883,"mg/(d·K)","milligram per day kelvin" -F71,4601649,"mg/(h·bar)","milligram per hour bar" -F44,4600884,"mg/(h·K)","milligram per hour kelvin" -F33,4600627,"mg/min","milligram per minute" -F72,4601650,"mg/(min·bar)","milligram per minute bar" -F45,4600885,"mg/(min·K)","milligram per minute kelvin" -F34,4600628,"mg/s","milligram per second" -F73,4601651,"mg/(s·bar)","milligram per second bar" -F46,4600886,"mg/(s·K)","milligram per second kelvin" -F25,4600373,"g/Hz","gram per hertz" -4W,13399,"ton (US) /h","ton (US) per hour" -4U,13397,"lb/h","pound per hour" -K66,4929078,"lb/d","pound (avoirdupois) per day" -K73,4929331,"(lb/h)/°F","pound (avoirdupois) per hour degree Fahrenheit" -K74,4929332,"(lb/h)/psi","pound (avoirdupois) per hour psi" -K78,4929336,"lb/min","pound (avoirdupois) per minute" -K79,4929337,"lb/(min·°F)","pound (avoirdupois) per minute degree Fahrenheit" -K80,4929584,"(lb/min)/psi","pound (avoirdupois) per minute psi" -K81,4929585,"lb/s","pound (avoirdupois) per second" -K82,4929586,"(lb/s)/°F","pound (avoirdupois) per second degree Fahrenheit" -K83,4929587,"(lb/s)/psi","pound (avoirdupois) per second psi" -L33,4993843,"oz/d","ounce (avoirdupois) per day" -L34,4993844,"oz/h","ounce (avoirdupois) per hour" -L35,4993845,"oz/min","ounce (avoirdupois) per minute" -L36,4993846,"oz/s","ounce (avoirdupois) per second" -L63,4994611,"slug/d","slug per day" -L66,4994614,"slug/h","slug per hour" -L67,4994615,"slug/min","slug per minute" -L68,4994616,"slug/s","slug per second" -L71,4994865,"t/d","tonne per day" -L72,4994866,"(t/d)/K","tonne per day kelvin" -L73,4994867,"(t/d)/bar","tonne per day bar" -E18,4534584,"t/h","tonne per hour" -L74,4994868,"(t/h)/K","tonne per hour kelvin" -L75,4994869,"(t/h)/bar","tonne per hour bar" -L78,4994872,"t/min","tonne per minute" -L79,4994873,"(t/min)/K","tonne per minute kelvin" -L80,4995120,"(t/min)/bar","tonne per minute bar" -L81,4995121,"t/s","tonne per second" -L82,4995122,"(t/s)/K","tonne per second kelvin" -L83,4995123,"(t/s)/bar","tonne per second bar" -L85,4995125,"ton (UK)/d","ton long per day" -L88,4995128,"ton (US)/d","ton short per day" -L89,4995129,"ton (US)/(h·°F)","ton short per hour degree Fahrenheit" -L90,4995376,"(ton (US)/h)/psi","ton short per hour psi" -M88,5060664,"t/mo","tonne per month" -M89,5060665,"t/y","tonne per year" -M90,5060912,"klb/h","kilopound per hour" -J33,4862771,"µg/kg","microgram per kilogram" -L32,4993842,"ng/kg","nanogram per kilogram" -NA,20033,"mg/kg","milligram per kilogram" -M29,5059129,"kg/kg","kilogram per kilogram" -M91,5060913,"lb/lb","pound per pound" -MQS,5067091,"m³/s","cubic metre per second" -MQH,5067080,"m³/h","cubic metre per hour" -40,13360,"ml/s","millilitre per second" -41,13361,"ml/min","millilitre per minute" -LD,19524,"l/d","litre per day" -2J,12874,"cm³/s","cubic centimetre per second" -4X,13400,"kl/h","kilolitre per hour" -L2,19506,"l/min","litre per minute" -G47,4666423,"cm³/d","cubic centimetre per day" -G78,4667192,"cm³/(d·bar)","cubic centimetre per day bar" -G61,4666929,"cm³/(d·K)","cubic centimetre per day kelvin" -G48,4666424,"cm³/h","cubic centimetre per hour" -G79,4667193,"cm³/(h·bar)","cubic centimetre per hour bar" -G62,4666930,"cm³/(h·K)","cubic centimetre per hour kelvin" -G49,4666425,"cm³/min","cubic centimetre per minute" -G80,4667440,"cm³/(min·bar)","cubic centimetre per minute bar" -G63,4666931,"cm³/(min·K)","cubic centimetre per minute kelvin" -G81,4667441,"cm³/(s·bar)","cubic centimetre per second bar" -G64,4666932,"cm³/(s·K)","cubic centimetre per second kelvin" -E92,4536626,"dm³/h","cubic decimetre per hour" -G52,4666674,"m³/d","cubic metre per day" -G86,4667446,"m³/(d·bar)","cubic metre per day bar" -G69,4666937,"m³/(d·K)","cubic metre per day kelvin" -G87,4667447,"m³/(h·bar)","cubic metre per hour bar" -G70,4667184,"m³/(h·K)","cubic metre per hour kelvin" -G53,4666675,"m³/min","cubic metre per minute" -G88,4667448,"m³/(min·bar)","cubic metre per minute bar" -G71,4667185,"m³/(min·K)","cubic metre per minute kelvin" -G89,4667449,"m³/(s·bar)","cubic metre per second bar" -G72,4667186,"m³/(s·K)","cubic metre per second kelvin" -G82,4667442,"l/(d·bar)","litre per day bar" -G65,4666933,"l/(d·K)","litre per day kelvin" -G83,4667443,"l/(h·bar)","litre per hour bar" -G66,4666934,"l/(h·K)","litre per hour kelvin" -G84,4667444,"l/(min·bar)","litre per minute bar" -G67,4666935,"l/(min·K)","litre per minute kelvin" -G51,4666673,"l/s","litre per second" -G85,4667445,"l/(s·bar)","litre per second bar" -G68,4666936,"l/(s·K)","litre per second kelvin" -G54,4666676,"ml/d","millilitre per day" -G90,4667696,"ml/(d·bar)","millilitre per day bar" -G73,4667187,"ml/(d·K)","millilitre per day kelvin" -G55,4666677,"ml/h","millilitre per hour" -G91,4667697,"ml/(h·bar)","millilitre per hour bar" -G74,4667188,"ml/(h·K)","millilitre per hour kelvin" -G92,4667698,"ml/(min·bar)","millilitre per minute bar" -G75,4667189,"ml/(min·K)","millilitre per minute kelvin" -G93,4667699,"ml/(s·bar)","millilitre per second bar" -G76,4667190,"ml/(s·K)","millilitre per second kelvin" -2K,12875,"ft³/h","cubic foot per hour" -2L,12876,"ft³/min","cubic foot per minute" -5A,13633,"barrel (US)/min","barrel (US) per minute" -G2,18226,"gal (US) /min","US gallon per minute" -G3,18227,"gal (UK) /min","Imperial gallon per minute" -G56,4666678,"in³/h","cubic inch per hour" -G57,4666679,"in³/min","cubic inch per minute" -G58,4666680,"in³/s","cubic inch per second" -G50,4666672,"gal/h","gallon (US) per hour" -J58,4863288,"bbl (UK liq.)/min","barrel (UK petroleum) per minute" -J59,4863289,"bbl (UK liq.)/d","barrel (UK petroleum) per day" -J60,4863536,"bbl (UK liq.)/h","barrel (UK petroleum) per hour" -J61,4863537,"bbl (UK liq.)/s","barrel (UK petroleum) per second" -J62,4863538,"bbl (US)/h","barrel (US petroleum) per hour" -J63,4863539,"bbl (US)/s","barrel (US petroleum) per second" -J64,4863540,"bu (UK)/d","bushel (UK) per day" -J65,4863541,"bu (UK)/h","bushel (UK) per hour" -J66,4863542,"bu (UK)/min","bushel (UK) per minute" -J67,4863543,"bu (UK)/s","bushel (UK) per second" -J68,4863544,"bu (US dry)/d","bushel (US dry) per day" -J69,4863545,"bu (US dry)/h","bushel (US dry) per hour" -J70,4863792,"bu (US dry)/min","bushel (US dry) per minute" -J71,4863793,"bu (US dry)/s","bushel (US dry) per second" -J90,4864304,"dm³/d","cubic decimetre per day" -J92,4864306,"dm³/min","cubic decimetre per minute" -J93,4864307,"dm³/s","cubic decimetre per second" -N45,5125173,"(m³/s)/Pa","cubic metre per second pascal" -J95,4864309,"fl oz (UK)/d","ounce (UK fluid) per day" -J96,4864310,"fl oz (UK)/h","ounce (UK fluid) per hour" -J97,4864311,"fl oz (UK)/min","ounce (UK fluid) per minute" -J98,4864312,"fl oz (UK)/s","ounce (UK fluid) per second" -J99,4864313,"fl oz (US)/d","ounce (US fluid) per day" -K10,4927792,"fl oz (US)/h","ounce (US fluid) per hour" -K11,4927793,"fl oz (US)/min","ounce (US fluid) per minute" -K12,4927794,"fl oz (US)/s","ounce (US fluid) per second" -K22,4928050,"ft³/d","cubic foot per day" -K26,4928054,"gal (UK)/d","gallon (UK) per day" -K27,4928055,"gal (UK)/h","gallon (UK) per hour" -K28,4928056,"gal (UK)/s","gallon (UK) per second" -K30,4928304,"gal (US liq.)/s","gallon (US liquid) per second" -K32,4928306,"gi (UK)/d","gill (UK) per day" -K33,4928307,"gi (UK)/h","gill (UK) per hour" -K34,4928308,"gi (UK)/min","gill (UK) per minute" -K35,4928309,"gi (UK)/s","gill (UK) per second" -K36,4928310,"gi (US)/d","gill (US) per day" -K37,4928311,"gi (US)/h","gill (US) per hour" -K38,4928312,"gi (US)/min","gill (US) per minute" -K39,4928313,"gi (US)/s","gill (US) per second" -K94,4929844,"qt (UK liq.)/d","quart (UK liquid) per day" -K95,4929845,"qt (UK liq.)/h","quart (UK liquid) per hour" -K96,4929846,"qt (UK liq.)/min","quart (UK liquid) per minute" -K97,4929847,"qt (UK liq.)/s","quart (UK liquid) per second" -K98,4929848,"qt (US liq.)/d","quart (US liquid) per day" -K99,4929849,"qt (US liq.)/h","quart (US liquid) per hour" -L10,4993328,"qt (US liq.)/min","quart (US liquid) per minute" -L11,4993329,"qt (US liq.)/s","quart (US liquid) per second" -L44,4994100,"pk (UK)/d","peck (UK) per day" -L45,4994101,"pk (UK)/h","peck (UK) per hour" -L46,4994102,"pk (UK)/min","peck (UK) per minute" -L47,4994103,"pk (UK)/s","peck (UK) per second" -L48,4994104,"pk (US dry)/d","peck (US dry) per day" -L49,4994105,"pk (US dry)/h","peck (US dry) per hour" -L50,4994352,"pk (US dry)/min","peck (US dry) per minute" -L51,4994353,"pk (US dry)/s","peck (US dry) per second" -L53,4994355,"pt (UK)/d","pint (UK) per day" -L54,4994356,"pt (UK)/h","pint (UK) per hour" -L55,4994357,"pt (UK)/min","pint (UK) per minute" -L56,4994358,"pt (UK)/s","pint (UK) per second" -L57,4994359,"pt (US liq.)/d","pint (US liquid) per day" -L58,4994360,"pt (US liq.)/h","pint (US liquid) per hour" -L59,4994361,"pt (US liq.)/min","pint (US liquid) per minute" -L60,4994608,"pt (US liq.)/s","pint (US liquid) per second" -M12,5058866,"yd³/d","cubic yard per day" -M13,5058867,"yd³/h","cubic yard per hour" -M15,5058869,"yd³/min","cubic yard per minute" -M16,5058870,"yd³/s","cubic yard per second" -H60,4732464,"m³/m³","cubic metre per cubic metre" -F92,4602162,"bar·m³/s","bar cubic metre per second" -F91,4602161,"bar·l/s","bar litre per second" -K87,4929591,"psi·in³/s","psi cubic inch per second" -K88,4929592,"psi·l/s","psi litre per second" -K89,4929593,"psi·m³/s","psi cubic metre per second" -K90,4929840,"psi·yd³/s","psi cubic yard per second" -Q29,5321273,"µg/hg","microgram per hectogram" -Q37,5321527,"Standard cubic metre per day","Standard cubic metre per day" -Q38,5321528,"Standard cubic metre per hour","Standard cubic metre per hour" -Q39,5321529,"Normalized cubic metre per day","Normalized cubic metre per day" -Q40,5321776,"Normalized cubic metre per hour","Normalized cubic metre per hour" -KWN,4937550,"Kilowatt hour per normalized cubic metre","Kilowatt hour per normalized cubic metre" -KWS,4937555,"Kilowatt hour per standard cubic metre","Kilowatt hour per standard cubic metre" -Q41,5321777,"Joule per normalised cubic metre","Joule per normalised cubic metre" -Q42,5321778,"Joule per standard cubic metre","Joule per standard cubic metre" -MNJ,5066314,"MJ/m³","Mega Joule per Normalised cubic Metre" -KEL,4932940,"K","kelvin" -CEL,4408652,"°C","degree Celsius" -H12,4731186,"°C/h","degree Celsius per hour" -F60,4601392,"°C/bar","degree Celsius per bar" -E98,4536632,"°C/K","degree Celsius per kelvin" -H13,4731187,"°C/min","degree Celsius per minute" -H14,4731188,"°C/s","degree Celsius per second" -F61,4601393,"K/bar","kelvin per bar" -F10,4600112,"K/h","kelvin per hour" -F02,4599858,"K/K","kelvin per kelvin" -F11,4600113,"K/min","kelvin per minute" -F12,4600114,"K/s","kelvin per second" -N79,5125945,"K/Pa","kelvin per pascal" -J20,4862512,"°F/K","degree Fahrenheit per kelvin" -J21,4862513,"°F/bar","degree Fahrenheit per bar" -J26,4862518,"1/°F","reciprocal degree Fahrenheit" -A48,4273208,"°R","degree Rankine" -FAH,4604232,"°F","degree Fahrenheit" -J23,4862515,"°F/h","degree Fahrenheit per hour" -J24,4862516,"°F/min","degree Fahrenheit per minute" -J25,4862517,"°F/s","degree Fahrenheit per second" -J28,4862520,"°R/h","degree Rankine per hour" -J29,4862521,"°R/min","degree Rankine per minute" -J30,4862768,"°R/s","degree Rankine per second" -C91,4405553,"K⁻¹","reciprocal kelvin or kelvin to the power minus one" -M20,5059120,"1/MK","reciprocal megakelvin or megakelvin to the power minus one" -C64,4404788,"Pa/K","pascal per kelvin" -F81,4601905,"bar/K","bar per kelvin" -J55,4863285,"W·s","watt second" -BTU,4346965,"BtuIT","British thermal unit (international table)" -A1,16689,"cal₁₅","15 °C calorie" -D70,4470576,"calIT","calorie (international table)" -J39,4862777,"Btu","British thermal unit (mean)" -J75,4863797,"cal","calorie (mean)" -K51,4928817,"kcal","kilocalorie (mean)" -E14,4534580,"kcalIT","kilocalorie (international table)" -K53,4928819,"kcalth","kilocalorie (thermochemical)" -N66,5125686,"Btu (39 ºF)","British thermal unit (39 ºF)" -N67,5125687,"Btu (59 ºF)","British thermal unit (59 ºF)" -N68,5125688,"Btu (60 ºF)","British thermal unit (60 ºF)" -N69,5125689,"cal₂₀","calorie (20 ºC)" -N70,5125936,"quad","quad (1015 BtuIT)" -N71,5125937,"thm (EC)","therm (EC)" -N72,5125938,"thm (US)","therm (U.S.)" -D35,4469557,"calth","calorie (thermochemical)" -2I,12873,"BtuIT/h","British thermal unit (international table) per hour" -J44,4863028,"BtuIT/min","British thermal unit (international table) per minute" -J45,4863029,"BtuIT/s","British thermal unit (international table) per second" -J47,4863031,"Btuth/h","British thermal unit (thermochemical) per hour" -J51,4863281,"Btuth/min","British thermal unit (thermochemical) per minute" -J52,4863282,"Btuth/s","British thermal unit (thermochemical) per second" -J81,4864049,"calth/min","calorie (thermochemical) per minute" -J82,4864050,"calth/s","calorie (thermochemical) per second" -E15,4534581,"kcalth/h","kilocalorie (thermochemical) per hour" -K54,4928820,"kcalth/min","kilocalorie (thermochemical) per minute" -K55,4928821,"kcalth/s","kilocalorie (thermochemical) per second" -D54,4470068,"W/m²","watt per square metre" -N48,5125176,"W/cm²","watt per square centimetre" -N49,5125177,"W/in²","watt per square inch" -N50,5125424,"BtuIT/(ft²·h)","British thermal unit (international table) per square foot hour" -N51,5125425,"Btuth/(ft²·h)","British thermal unit (thermochemical) per square foot hour" -N52,5125426,"Btuth/(ft²·min)","British thermal unit (thermochemical) per square foot minute" -N53,5125427,"BtuIT/(ft²·s)","British thermal unit (international table) per square foot second" -N54,5125428,"Btuth/(ft²·s)","British thermal unit (thermochemical) per square foot second" -N55,5125429,"BtuIT/(in²·s)","British thermal unit (international table) per square inch second" -N56,5125430,"calth/(cm²·min)","calorie (thermochemical) per square centimetre minute" -N57,5125431,"calth/(cm²·s)","calorie (thermochemical) per square centimetre second" -D53,4470067,"W/(m·K)","watt per metre kelvin" -N80,5126192,"W/(m·°C)","watt per metre degree Celsius" -N81,5126193,"kW/(m·K)","kilowatt per metre kelvin" -N82,5126194,"kW/(m·°C)","kilowatt per metre degree Celsius" -A22,4272690,"BtuIT/(s·ft·°R)","British thermal unit (international table) per second foot degree Rankine" -D71,4470577,"calIT/(s·cm·K)","calorie (international table) per second centimetre kelvin" -D38,4469560,"calth/(s·cm·K)","calorie (thermochemical) per second centimetre kelvin" -J40,4863024,"BtuIT·ft/(h·ft²·°F)","British thermal unit (international table) foot per hour square foot degree Fahrenheit" -J41,4863025,"BtuIT·in/(h·ft²·°F)","British thermal unit (international table) inch per hour square foot degree Fahrenheit" -J42,4863026,"BtuIT·in/(s·ft²·°F)","British thermal unit (international table) inch per second square foot degree Fahrenheit" -J46,4863030,"Btuth·ft/(h·ft²·°F)","British thermal unit (thermochemical) foot per hour square foot degree Fahrenheit" -J48,4863032,"Btuth·in/(h·ft²·°F)","British thermal unit (thermochemical) inch per hour square foot degree Fahrenheit" -J49,4863033,"Btuth·in/(s·ft²·°F)","British thermal unit (thermochemical) inch per second square foot degree Fahrenheit" -J78,4863800,"calth/(cm·s·°C)","calorie (thermochemical) per centimetre second degree Celsius" -K52,4928818,"kcal/(m·h·°C)","kilocalorie (international table) per hour metre degree Celsius" -D55,4470069,"W/(m²·K)","watt per square metre kelvin" -N78,5125944,"kW/(m²·K)","kilowatt per square metre kelvin" -D72,4470578,"calIT/(s·cm²·K)","calorie (international table) per second square centimetre kelvin" -D39,4469561,"calth/(s·cm²·K)","calorie (thermochemical) per second square centimetre kelvin" -A20,4272688,"BtuIT/(s·ft²·°R)","British thermal unit (international table) per second square foot degree Rankine" -A23,4272691,"BtuIT/(h·ft²·°R)","British thermal unit (international table) per hour square foot degree Rankine" -N74,5125940,"BtuIT/(h·ft²·ºF)","British thermal unit (international table) per hour square foot degree Fahrenheit" -N75,5125941,"Btuth/(h·ft²·ºF)","British thermal unit (thermochemical) per hour square foot degree Fahrenheit" -N76,5125942,"BtuIT/(s·ft²·ºF)","British thermal unit (international table) per second square foot degree Fahrenheit" -N77,5125943,"Btuth/(s·ft²·ºF)","British thermal unit (thermochemical) per second square foot degree Fahrenheit" -D19,4469049,"m²·K/W","square metre kelvin per watt" -J19,4862265,"°F·h·ft²/Btuth","degree Fahrenheit hour square foot per British thermal unit (thermochemical)" -J22,4862514,"°F·h·ft²/BtuIT","degree Fahrenheit hour square foot per British thermal unit (international table)" -J83,4864051,"clo","clo" -L14,4993332,"m²·h·°C/kcal","square metre hour degree Celsius per kilocalorie (international table)" -B21,4338225,"K/W","kelvin per watt" -H35,4731701,"K·m/W","kelvin metre per watt" -N84,5126196,"ºF/(BtuIT/h)","degree Fahrenheit hour per British thermal unit (international table)" -N85,5126197,"ºF/(Btuth/h)","degree Fahrenheit hour per British thermal unit (thermochemical)" -N86,5126198,"ºF/(BtuIT/s)","degree Fahrenheit second per British thermal unit (international table)" -N87,5126199,"ºF/(Btuth/s)","degree Fahrenheit second per British thermal unit (thermochemical)" -N88,5126200,"ºF·h·ft²/(BtuIT·in)","degree Fahrenheit hour square foot per British thermal unit (international table) inch" -N89,5126201,"ºF·h·ft²/(Btuth·in)","degree Fahrenheit hour square foot per British thermal unit (thermochemical) inch" -D52,4470066,"W/K","watt per kelvin" -E97,4536631,"mm/(°C·m)","millimetre per degree Celcius metre" -F53,4601139,"mm/K","millimetre per kelvin" -N83,5126195,"m/(°C·m)","metre per degree Celcius metre" -JE,19013,"J/K","joule per kelvin" -B41,4338737,"kJ/K","kilojoule per kelvin" -J43,4863027,"BtuIT/(lb·°F)","British thermal unit (international table) per pound degree Fahrenheit" -J50,4863280,"Btuth/(lb·°F)","British thermal unit (thermochemical) per pound degree Fahrenheit" -J76,4863798,"calIT/(g·°C)","calorie (international table) per gram degree Celsius" -J79,4863801,"calth/(g·°C)","calorie (thermochemical) per gram degree Celsius" -N60,5125680,"BtuIT/ºF","British thermal unit (international table) per degree Fahrenheit" -N61,5125681,"Btuth/ºF","British thermal unit (thermochemical) per degree Fahrenheit" -N62,5125682,"BtuIT/ºR","British thermal unit (international table) per degree Rankine" -N63,5125683,"Btuth/ºR","British thermal unit (thermochemical) per degree Rankine" -N64,5125684,"(Btuth/°R)/lb","British thermal unit (thermochemical) per pound degree Rankine" -N65,5125685,"(kcalIT/K)/g","kilocalorie (international table) per gram kelvin" -B11,4337969,"J/(kg·K)","joule per kilogram kelvin" -B43,4338739,"kJ/(kg·K)","kilojoule per kilogram kelvin" -A21,4272689,"Btu/IT(lb·°R)","British thermal unit (international table) per pound degree Rankine" -D76,4470582,"calIT/(g·K)","calorie (international table) per gram kelvin" -D37,4469559,"calth/(g·K)","calorie (thermochemical) per gram kelvin" -J2,18994,"J/kg","joule per kilogram" -D95,4471093,"J/g","joule per gram" -JK,19019,"MJ/kg","megajoule per kilogram" -B42,4338738,"kJ/kg","kilojoule per kilogram" -AZ,16730,"BtuIT/lb","British thermal unit (international table) per pound" -D75,4470581,"calIT/g","calorie (international table) per gram" -N73,5125939,"Btuth/lb","British thermal unit (thermochemical) per pound" -B36,4338486,"calth/g","calorie (thermochemical) per gram" -N58,5125432,"BtuIT/ft³","British thermal unit (international table) per cubic foot" -N59,5125433,"Btuth/ft³","British thermal unit (thermochemical) per cubic foot" -Q31,5321521,"kJ/g","kilojoule per gram" -AMP,4279632,"A","ampere" -B22,4338226,"kA","kiloampere" -H38,4731704,"MA","megaampere" -4K,13387,"mA","milliampere" -B84,4339764,"µA","microampere" -C39,4404025,"nA","nanoampere" -C70,4405040,"pA","picoampere" -N96,5126454,"Bi","biot" -N97,5126455,"Gi","gilbert" -COU,4411221,"C","coulomb" -A8,16696,"A·s","ampere second" -H32,4731698,"A²·s","ampere squared second" -AMH,4279624,"A·h","ampere hour" -TAH,5521736,"kA·h","kiloampere hour (thousand ampere hour)" -D77,4470583,"MC","megacoulomb" -D86,4470838,"mC","millicoulomb" -B26,4338230,"kC","kilocoulomb" -B86,4339766,"µC","microcoulomb" -C40,4404272,"nC","nanocoulomb" -C71,4405041,"pC","picocoulomb" -E09,4534329,"mA·h","milliampere hour" -N95,5126453,"A·min","ampere minute" -N94,5126452,"Fr","franklin" -A29,4272697,"C/m³","coulomb per cubic metre" -A84,4274228,"GC/m³","gigacoulomb per cubic metre" -A30,4272944,"C/mm³","coulomb per cubic millimetre" -B69,4339257,"MC/m³","megacoulomb per cubic metre" -A28,4272696,"C/cm³","coulomb per cubic centimetre" -B27,4338231,"kC/m³","kilocoulomb per cubic metre" -D88,4470840,"mC/m³","millicoulomb per cubic metre" -B87,4339767,"µC/m³","microcoulomb per cubic metre" -A34,4272948,"C/m²","coulomb per square metre" -B70,4339504,"MC/m²","megacoulomb per square metre" -A35,4272949,"C/mm²","coulomb per square millimetre" -A33,4272947,"C/cm²","coulomb per square centimetre" -B28,4338232,"kC/m²","kilocoulomb per square metre" -D89,4470841,"mC/m²","millicoulomb per square metre" -B88,4339768,"µC/m²","microcoulomb per square metre" -D50,4470064,"V/m","volt per metre" -H45,4731957,"V·s/m","volt second per metre" -D45,4469813,"V²/K²","volt squared per kelvin squared" -D51,4470065,"V/mm","volt per millimetre" -H24,4731444,"V/µs","volt per microsecond" -H62,4732466,"mV/min","millivolt per minute" -H46,4731958,"V/s","volt per second" -B79,4339513,"MV/m","megavolt per metre" -B55,4338997,"kV/m","kilovolt per metre" -D47,4469815,"V/cm","volt per centimetre" -C30,4404016,"mV/m","millivolt per metre" -C3,17203,"µV/m","microvolt per metre" -G60,4666928,"V/bar","volt per bar" -N98,5126456,"V/Pa","volt per pascal" -F87,4601911,"V/(l·min)","volt per litre minute" -H22,4731442,"V/(lbf/in²)","volt square inch per pound-force" -H23,4731443,"V/in","volt per inch" -VLT,5655636,"V","volt" -B78,4339512,"MV","megavolt" -KVT,4937300,"kV","kilovolt" -2Z,12890,"mV","millivolt" -D82,4470834,"µV","microvolt" -N99,5126457,"pV","picovolt" -FAR,4604242,"F","farad" -H48,4731960,"aF","attofarad" -C10,4403504,"mF","millifarad" -4O,13391,"µF","microfarad" -C41,4404273,"nF","nanofarad" -4T,13396,"pF","picofarad" -N90,5126448,"kF","kilofarad" -A69,4273721,"F/m","farad per metre" -H28,4731448,"µF/km","microfarad per kilometre" -H33,4731699,"F/km","farad per kilometre" -B89,4339769,"µF/m","microfarad per metre" -C42,4404274,"nF/m","nanofarad per metre" -C72,4405042,"pF/m","picofarad per metre" -A26,4272694,"C·m","coulomb metre" -A41,4273201,"A/m²","ampere per square metre" -H31,4731697,"A/kg","ampere per kilogram" -B66,4339254,"MA/m²","megaampere per square metre" -A7,16695,"A/mm²","ampere per square millimetre" -A4,16692,"A/cm²","ampere per square centimetre" -B23,4338227,"kA/m²","kiloampere per square metre" -G59,4666681,"mA/(l·min)","milliampere per litre minute" -N93,5126451,"A/Pa","ampere per pascal" -F57,4601143,"mA/(lbf/in²)","milliampere per pound-force per square inch" -F59,4601145,"mA/bar","milliampere per bar" -AE,16709,"A/m","ampere per metre" -B24,4338228,"kA/m","kiloampere per metre" -A3,16691,"A/mm","ampere per millimetre" -A2,16690,"A/cm","ampere per centimetre" -F76,4601654,"mA/mm","milliampere per millimetre" -F08,4599864,"mA/in","milliampere per inch" -P10,5255472,"C/m","coulomb per metre" -D33,4469555,"T","tesla" -C29,4403769,"mT","millitesla" -D81,4470833,"µT","microtesla" -C48,4404280,"nT","nanotesla" -P13,5255475,"kT","kilotesla" -P12,5255474,"γ","gamma" -WEB,5719362,"Wb","weber" -C33,4404019,"mWb","milliweber" -P11,5255473,"kWb","kiloweber" -D59,4470073,"Wb/m","weber per metre" -B56,4338998,"kWb/m","kiloweber per metre" -D60,4470320,"Wb/mm","weber per millimetre" -81,14385,"H","henry" -C14,4403508,"mH","millihenry" -B90,4340016,"µH","microhenry" -C43,4404275,"nH","nanohenry" -C73,4405043,"pH","picohenry" -H03,4730931,"H/kΩ","henry per kiloohm" -H04,4730932,"H/Ω","henry per ohm" -G98,4667704,"µH/kΩ","microhenry per kiloohm" -G99,4667705,"µH/Ω","microhenry per ohm" -H05,4730933,"mH/kΩ","millihenry per kiloohm" -H06,4730934,"mH/Ω","millihenry per ohm" -P24,5255732,"kH","kilohenry" -A98,4274488,"H/m","henry per metre" -B91,4340017,"µH/m","microhenry per metre" -C44,4404276,"nH/m","nanohenry per metre" -A5,16693,"A·m²","ampere square metre" -B8,16952,"J/m³","joule per cubic metre" -OHM,5195853,"Ω","ohm" -A87,4274231,"GΩ","gigaohm" -B75,4339509,"MΩ","megaohm" -H44,4731956,"TΩ","teraohm" -B49,4338745,"kΩ","kiloohm" -E45,4535349,"mΩ","milliohm" -B94,4340020,"µΩ","microohm" -P22,5255730,"nΩ","nanoohm" -M26,5059126,"GΩ/m","gigaohm per metre" -SIE,5458245,"S","siemens" -B53,4338995,"kS","kilosiemens" -C27,4403767,"mS","millisiemens" -B99,4340025,"µS","microsiemens" -G42,4666418,"µS/cm","microsiemens per centimetre" -G43,4666419,"µS/m","microsiemens per metre" -N92,5126450,"pS","picosiemens" -NQ,20049,"mho","mho" -NR,20050,"micromho","micromho" -C61,4404785,"Ω·m","ohm metre" -A88,4274232,"GΩ·m","gigaohm metre" -B76,4339510,"MΩ·m","megaohm metre" -H88,4732984,"MΩ·km","megaohm kilometre" -B50,4338992,"kΩ·m","kiloohm metre" -C60,4404784,"Ω·cm","ohm centimetre" -C23,4403763,"mΩ·m","milliohm metre" -B95,4340021,"µΩ·m","microohm metre" -C46,4404278,"nΩ·m","nanoohm metre" -M24,5059124,"Ω·km","ohm kilometre" -P23,5255731,"Ω·cmil/ft","ohm circular-mil per foot" -F56,4601142,"Ω/km","ohm per kilometre" -H26,4731446,"Ω/m","ohm per metre" -H37,4731703,"MΩ/m","megaohm per metre" -F54,4601140,"mΩ/m","milliohm per metre" -H36,4731702,"MΩ/km","megaohm per kilometre" -F55,4601141,"Ω/mi","ohm per mile (statute mile)" -D10,4469040,"S/m","siemens per metre" -H43,4731955,"S/cm","siemens per centimetre" -H61,4732465,"mS/cm","millisiemens per centimetre" -B77,4339511,"MS/m","megasiemens per metre" -B54,4338996,"kS/m","kilosiemens per metre" -G45,4666421,"nS/m","nanosiemens per metre" -G44,4666420,"nS/cm","nanosiemens per centimetre" -L42,4994098,"pS/m","picosiemens per metre" -C89,4405305,"H⁻¹","reciprocal henry" -P14,5255476,"J/s","joule per second" -D31,4469553,"TW","terawatt" -P15,5255477,"J/min","joule per minute" -P16,5255478,"J/h","joule per hour" -P17,5255479,"J/d","joule per day" -P18,5255480,"kJ/s","kilojoule per second" -P19,5255481,"kJ/min","kilojoule per minute" -P20,5255728,"kJ/h","kilojoule per hour" -P21,5255729,"kJ/d","kilojoule per day" -K43,4928563,"electric hp","horsepower (electric)" -C49,4404281,"nW","nanowatt" -C75,4405045,"pW","picowatt" -D46,4469814,"V·A","volt - ampere" -MVA,5068353,"MV·A","megavolt - ampere" -KVA,4937281,"kV·A","kilovolt - ampere" -M35,5059381,"mV·A","millivolt - ampere" -D44,4469812,"var","var" -K5,19253,"kvar","kilovolt ampere (reactive)" -KVR,4937298,"kvar","kilovar" -MAR,5062994,"kvar","megavar" -N91,5126449,"1/J","reciprocal joule" -M30,5059376,"1/(V·A·s)","reciprocal volt - ampere reciprocal second" -M17,5058871,"kHz·m","kilohertz metre" -M18,5058872,"GHz·m","gigahertz metre" -M27,5059127,"MHz·m","megahertz metre" -M21,5059121,"1/kVAh","reciprocal kilovolt - ampere reciprocal hour" -H34,4731700,"Hz·m","hertz metre" -H39,4731705,"MHz·km","megahertz kilometre" -C84,4405300,"rad/m","radian per metre" -JM,19021,"MJ/m³","megajoule per cubic metre" -B14,4337972,"J/m⁴","joule per metre to the fourth power" -B13,4337971,"J/m²","joule per square metre" -D1,17457,"s⁻¹/sr","reciprocal second per steradian" -D2,17458,"s⁻¹/(sr·m²)","reciprocal second per steradian metre squared" -C99,4405561,"s⁻¹/m²","reciprocal second per metre squared" -C93,4405555,"m⁻²","reciprocal square metre" -H47,4731959,"W/m³","watt per cubic metre" -H74,4732724,"W/m","watt per metre" -E43,4535347,"J/cm²","joule per square centimetre" -P37,5255991,"BtuIT/ft²","British thermal unit (international table) per square foot" -P38,5255992,"Btuth/ft²","British thermal unit (thermochemical) per square foot" -P39,5255993,"calth/cm²","calorie (thermochemical) per square centimetre" -P40,5256240,"Ly","langley" -D57,4470071,"W/sr","watt per steradian" -D58,4470072,"W/(sr·m²)","watt per steradian square metre" -D56,4470070,"W/(m²·K⁴)","watt per square metre kelvin to the fourth power" -D18,4469048,"m·K","metre kelvin" -CDL,4408396,"cd","candela" -P33,5255987,"kcd","kilocandela" -P34,5255988,"mcd","millicandela" -P35,5255989,"HK","Hefner-Kerze" -P36,5255990,"IK","international candle" -LUM,5002573,"lm","lumen" -B62,4339250,"lm·s","lumen second" -B59,4339001,"lm·h","lumen hour" -A24,4272692,"cd/m²","candela per square metre" -P28,5255736,"cd/in²","candela per square inch" -P29,5255737,"ftL","footlambert" -P30,5255984,"Lb","lambert" -P31,5255985,"sb","stilb" -P32,5255986,"cd/ft²","candela per square foot" -B60,4339248,"lm/m²","lumen per square metre" -LUX,5002584,"lx","lux" -KLX,4934744,"klx","kilolux" -P25,5255733,"lm/ft²","lumen per square foot" -P26,5255734,"ph","phot" -P27,5255735,"ftc","footcandle" -B64,4339252,"lx·s","lux second" -B63,4339251,"lx·h","lux hour" -B61,4339249,"lm/W","lumen per watt" -D22,4469298,"m²/mol","square metre per mole" -C59,4404537,"octave","octave" -D9,17465,"dyn/cm²","dyne per square centimetre" -A60,4273712,"erg/cm³","erg per cubic centimetre" -C32,4404018,"mW/m²","milliwatt per square metre" -D85,4470837,"µW/m²","microwatt per square metre" -C76,4405046,"pW/m²","picowatt per square metre" -A64,4273716,"erg/(s·cm²)","erg per second square centimetre" -C67,4404791,"Pa· s/m","pascal second per metre" -A50,4273456,"dyn·s/cm³","dyne second per cubic centimetre" -C66,4404790,"Pa·s/m³","pascal second per cubic metre" -A52,4273458,"dyn·s/cm⁵","dyne second per centimetre to the fifth power" -M32,5059378,"Pa·s/l","pascal second per litre" -C58,4404536,"N·s/m","newton second per metre" -A51,4273457,"dyn·s/cm","dyne second per centimetre" -P43,5256243,"B/m","bel per metre" -H51,4732209,"dB/km","decibel per kilometre" -H52,4732210,"dB/m","decibel per metre" -C69,4404793,"phon","phon" -D15,4469045,"sone","sone" -P42,5256242,"Pa²·s","pascal squared second" -P41,5256241,"dec","decade (logarithmic)" -C34,4404020,"mol","mole" -B45,4338741,"kmol","kilomole" -C18,4403512,"mmol","millimole" -FH,17992,"µmol","micromole" -Z9,23097,"nmol","nanomole" -P44,5256244,"lbmol","pound mole" -C95,4405557,"mol⁻¹","reciprocal mole" -D74,4470580,"kg/mol","kilogram per mole" -A94,4274484,"g/mol","gram per mole" -A40,4273200,"m³/mol","cubic metre per mole" -A37,4272951,"dm³/mol","cubic decimetre per mole" -A36,4272950,"cm³/mol","cubic centimetre per mole" -B58,4339000,"l/mol","litre per mole" -B15,4337973,"J/mol","joule per mole" -B44,4338740,"kJ/mol","kilojoule per mole" -B16,4337974,"J/(mol·K)","joule per mole kelvin" -C86,4405302,"m⁻³","reciprocal cubic metre" -H50,4732208,"cm⁻³","reciprocal cubic centimetre" -L20,4993584,"1/mm³","reciprocal cubic millimetre" -K20,4928048,"1/ft³","reciprocal cubic foot" -K49,4928569,"1/in³","reciprocal cubic inch" -K63,4929075,"1/l","reciprocal litre" -M10,5058864,"1/yd³","reciprocal cubic yard" -C36,4404022,"mol/m³","mole per cubic metre" -C38,4404024,"mol/l","mole per litre" -C35,4404021,"mol/dm³","mole per cubic decimetre" -B46,4338742,"kmol/m³","kilomole per cubic metre" -E95,4536629,"mol/s","mole per second" -M33,5059379,"mmol/l","millimole per litre" -P51,5256497,"(mol/kg)/Pa","mol per kilogram pascal" -P52,5256498,"(mol/m³)/Pa","mol per cubic metre pascal" -K59,4928825,"(kmol/m³)/K","kilomole per cubic metre kelvin" -K60,4929072,"(kmol/m³)/bar","kilomole per cubic metre bar" -K93,4929843,"1/psi","reciprocal psi" -L24,4993588,"(mol/kg)/K","mole per kilogram kelvin" -L25,4993589,"(mol/kg)/bar","mole per kilogram bar" -L26,4993590,"(mol/l)/K","mole per litre kelvin" -L27,4993591,"(mol/l)/bar","mole per litre bar" -L28,4993592,"(mol/m³)/K","mole per cubic metre kelvin" -L29,4993593,"(mol/m³)/bar","mole per cubic metre bar" -C19,4403513,"mol/kg","mole per kilogram" -D93,4471091,"s/m³","second per cubic metre" -D87,4470839,"mmol/kg","millimole per kilogram" -H68,4732472,"mmol/g","millimole per gram" -P47,5256247,"kmol/kg","kilomole per kilogram" -P48,5256248,"lbmol/lb","pound mole per pound" -KAT,4931924,"kat","katal" -E94,4536628,"kmol/s","kilomole per second" -P45,5256245,"lbmol/s","pound mole per second" -P46,5256246,"lbmol/h","pound mole per minute" -D43,4469811,"u","unified atomic mass unit" -A27,4272695,"C·m²/V","coulomb metre squared per volt" -A32,4272946,"C/mol","coulomb per mole" -D12,4469042,"S·m²/mol","siemens square metre per mole" -K58,4928824,"kmol/h","kilomole per hour" -K61,4929073,"kmol/min","kilomole per minute" -L23,4993587,"mol/h","mole per hour" -L30,4993840,"mol/min","mole per minute" -C82,4405298,"rad·m²/mol","radian square metre per mole" -C83,4405299,"rad·m²/kg","radian square metre per kilogram" -P49,5256249,"N·m²/A","newton square metre per ampere" -P50,5256496,"Wb·m","weber metre" -Q30,5321520,"pH","pH (potential of Hydrogen)" -B18,4337976,"J·s","joule second" -A10,4272432,"A·m²/(J·s)","ampere square metre per joule second" -CUR,4412754,"Ci","curie" -MCU,5063509,"mCi","millicurie" -M5,19765,"µCi","microcurie" -2R,12882,"kCi","kilocurie" -BQL,4346188,"Bq","becquerel" -GBQ,4670033,"GBq","gigabecquerel" -2Q,12881,"kBq","kilobecquerel" -4N,13390,"MBq","megabecquerel" -H08,4730936,"µBq","microbecquerel" -A42,4273202,"Ci/kg","curie per kilogram" -A18,4272440,"Bq/kg","becquerel per kilogram" -B67,4339255,"MBq/kg","megabecquerel per kilogram" -B25,4338229,"kBq/kg","kilobecquerel per kilogram" -A19,4272441,"Bq/m³","becquerel per cubic metre" -A14,4272436,"b","barn" -D24,4469300,"m²/sr","square metre per steradian" -A17,4272439,"b/sr","barn per steradian" -D20,4469296,"m²/J","square metre per joule" -A15,4272437,"b/eV","barn per electronvolt" -D16,4469046,"cm²/erg","square centimetre per erg" -D25,4469301,"m²/(sr·J)","square metre per steradian joule" -A16,4272438,"b/(sr·eV)","barn per steradian electronvolt" -D17,4469047,"cm²/(sr·erg)","square centimetre per steradian erg" -B81,4339761,"m⁻²/s","reciprocal metre squared reciprocal second" -A65,4273717,"erg/(cm²·s)","erg per square centimetre second" -D21,4469297,"m²/kg","square metre per kilogram" -B12,4337970,"J/m","joule per metre" -A54,4273460,"eV/m","electronvolt per metre" -A58,4273464,"erg/cm","erg per centimetre" -D73,4470579,"J·m²","joule square metre" -A55,4273461,"eV·m²","electronvolt square metre" -A66,4273718,"erg·cm²","erg square centimetre" -B20,4338224,"J·m²/kg","joule square metre per kilogram" -A56,4273462,"eV·m²/kg","electronvolt square metre per kilogram" -A67,4273719,"erg·cm²/g","erg square centimetre per gram" -D26,4469302,"m²/(V·s)","square metre per volt second" -H58,4732216,"m/(V·s)","metre per volt second" -C87,4405303,"m⁻³/s","reciprocal cubic metre per second" -A95,4274485,"Gy","gray" -C13,4403507,"mGy","milligray" -C80,4405296,"rad","rad" -A61,4273713,"erg/g","erg per gram" -D13,4469043,"Sv","sievert" -C28,4403768,"mSv","millisievert" -D91,4471089,"rem","rem" -L31,4993841,"mrem","milliroentgen aequivalent men" -A96,4274486,"Gy/s","gray per second" -A62,4273714,"erg/g·s","erg per gram second" -CKG,4410183,"C/kg","coulomb per kilogram" -C8,17208,"mC/kg","millicoulomb per kilogram" -2C,12867,"R","roentgen" -2Y,12889,"mR","milliroentgen" -J53,4863283,"C·m²/kg","coulomb square metre per kilogram" -KR,19282,"kR","kiloroentgen" -A31,4272945,"C/(kg·s)","coulomb per kilogram second" -D6,17462,"R/s","roentgen per second" -P54,5256500,"mGy/s","milligray per second" -P55,5256501,"µGy/s","microgray per second" -P56,5256502,"nGy/s","nanogray per second" -P57,5256503,"Gy/min","gray per minute" -P58,5256504,"mGy/min","milligray per minute" -P59,5256505,"µGy/min","microgray per minute" -P60,5256752,"nGy/min","nanogray per minute" -P61,5256753,"Gy/h","gray per hour" -P62,5256754,"mGy/h","milligray per hour" -P63,5256755,"µGy/h","microgray per hour" -P64,5256756,"nGy/h","nanogray per hour" -P65,5256757,"Sv/s","sievert per second" -P66,5256758,"mSv/s","millisievert per second" -P67,5256759,"µSv/s","microsievert per second" -P68,5256760,"nSv/s","nanosievert per second" -P69,5256761,"rem/s","rem per second" -P70,5257008,"Sv/h","sievert per hour" -P71,5257009,"mSv/h","millisievert per hour" -P72,5257010,"µSv/h","microsievert per hour" -P73,5257011,"nSv/h","nanosievert per hour" -P74,5257012,"Sv/min","sievert per minute" -P75,5257013,"mSv/min","millisievert per minute" -P76,5257014,"µSv/min","microsievert per minute" -P77,5257015,"nSv/min","nanosievert per minute" -P78,5257016,"1/in²","reciprocal square inch" -P53,5256499,"unit pole","unit pole" -C85,4405301,"Å⁻¹","reciprocal angstrom" -D94,4471092,"s/(rad·m³)","second per cubic metre radian" -C90,4405552,"J⁻¹/m³","reciprocal joule per cubic metre" -C88,4405304,"eV⁻¹/m³","reciprocal electron volt per cubic metre" -A38,4272952,"m³/C","cubic metre per coulomb" -D48,4469816,"V/K","volt per kelvin" -D49,4469817,"mV/K","millivolt per kelvin" -A6,16694,"A/(m²·K²)","ampere per square metre kelvin squared" -33,13107,"kPa·m²/g","kilopascal square metre per gram" -P79,5257017,"Pa/(kg/m²)","pascal square metre per kilogram" -34,13108,"kPa/mm","kilopascal per millimetre" -H42,4731954,"Pa/m","pascal per metre" -H69,4732473,"pPa/km","picopascal per kilometre" -P80,5257264,"mPa/m","millipascal per metre" -P81,5257265,"kPa/m","kilopascal per metre" -P82,5257266,"hPa/m","hectopascal per metre" -P83,5257267,"Atm/m","standard atmosphere per metre" -P84,5257268,"at/m","technical atmosphere per metre" -P85,5257269,"Torr/m","torr per metre" -P86,5257270,"psi/in","psi per inch" -35,13109,"ml/(cm²·s)","millilitre per square centimetre second" -P87,5257271,"(m³/s)/m²","cubic metre per second square metre" -OPM,5197901,"o/min","oscillations per minute" -KNM,4935245,"KN/m2","kilonewton per square metre" -Q35,5321525,"MW/min","megawatts per minute" -10,12592,"group","group" -11,12593,"outfit","outfit" -13,12595,"ration","ration" -14,12596,"shot","shot" -15,12597,"stick, military","stick, military" -20,12848,"twenty foot container","twenty foot container" -21,12849,"forty foot container","forty foot container" -24,12852,"theoretical pound","theoretical pound" -27,12855,"theoretical ton","theoretical ton" -38,13112,"oz/(ft²/cin)","ounce per square foot per 0,01inch" -56,13622,"sitas","sitas" -57,13623,"mesh","mesh" -58,13624,"net kilogram","net kilogram" -59,13625,"ppm","part per million" -60,13872,"percent weight","percent weight" -61,13873,"ppb","part per billion (US)" -64,13876,"pound per square inch, gauge","pound per square inch, gauge" -66,13878,"Oe","oersted" -76,14134,"Gs","gauss" -78,14136,"kGs","kilogauss" -1I,12617,"fixed rate","fixed rate" -2G,12871,"V","volt AC" -2H,12872,"V","volt DC" -2P,12880,"kbyte","kilobyte" -3C,13123,"manmonth","manmonth" -4L,13388,"Mbyte","megabyte" -5B,13634,"batch","batch" -5E,13637,"MMSCF/day","MMSCF/day" -5J,13642,"hydraulic horse power","hydraulic horse power" -A43,4273203,"dwt","deadweight tonnage" -A47,4273207,"dtex (g/10km)","decitex" -A49,4273209,"den (g/9 km)","denier" -A59,4273465,"8-part cloud cover","8-part cloud cover" -A75,4273973,"freight ton","freight ton" -A77,4273975,"Gaussian CGS (Centimetre-Gram-Second system) unit of displacement","Gaussian CGS (Centimetre-Gram-Second system) unit of displacement" -A78,4273976,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric current","Gaussian CGS (Centimetre-Gram-Second system) unit of electric current" -A79,4273977,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric charge","Gaussian CGS (Centimetre-Gram-Second system) unit of electric charge" -A80,4274224,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric field strength","Gaussian CGS (Centimetre-Gram-Second system) unit of electric field strength" -A81,4274225,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric polarization","Gaussian CGS (Centimetre-Gram-Second system) unit of electric polarization" -A82,4274226,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric potential","Gaussian CGS (Centimetre-Gram-Second system) unit of electric potential" -A83,4274227,"Gaussian CGS (Centimetre-Gram-Second system) unit of magnetization","Gaussian CGS (Centimetre-Gram-Second system) unit of magnetization" -A9,16697,"rate","rate" -A99,4274489,"bit","bit" -AA,16705,"ball","ball" -AB,16706,"pk","bulk pack" -ACT,4277076,"activity","activity" -AD,16708,"byte","byte" -AH,16712,"additional minute","additional minute" -AI,16713,"average minute per call","average minute per call" -AL,16716,"access line","access line" -AQ,16721,"anti-hemophilic factor (AHF) unit","anti-hemophilic factor (AHF) unit" -AS,16723,"assortment","assortment" -ASM,4281165,"alcoholic strength by mass","alcoholic strength by mass" -ASU,4281173,"alcoholic strength by volume","alcoholic strength by volume" -AY,16729,"assembly","assembly" -B1,16945,"barrel (US)/d","barrel (US) per day" -B10,4337968,"bit/s","bit per second" -B17,4337975,"credit","credit" -B19,4337977,"digit","digit" -B3,16947,"batting pound","batting pound" -B30,4338480,"Gibit","gibibit" -B4,16948,"barrel, imperial","barrel, imperial" -B65,4339253,"Mx","maxwell" -B68,4339256,"Gbit","gigabit" -B7,16951,"cycle","cycle" -B80,4339760,"Gbit/s","gigabit per second" -B82,4339762,"inch per linear foot","inch per linear foot" -BB,16962,"base box","base box" -BFT,4343380,"fbm","board foot" -BIL,4344140,"billion (EUR)","billion (EUR)" -BP,16976,"hundred board foot","hundred board foot" -BPM,4345933,"BPM","beats per minute" -C0,17200,"call","call" -C21,4403761,"Kibit","kibibit" -C37,4404023,"kbit","kilobit" -C74,4405044,"kbit/s","kilobit per second" -C79,4405049,"kVAh","kilovolt ampere hour" -C9,17209,"coil group","coil group" -CCT,4408148,"carrying capacity in metric ton","carrying capacity in metric ton" -CEN,4408654,"hundred","hundred" -CG,17223,"card","card" -CLF,4410438,"hundred leave","hundred leave" -CNP,4410960,"hundred pack","hundred pack" -CNT,4410964,"cental (UK)","cental (UK)" -CTG,4412487,"content gram","content gram" -CTM,4412493,"metric carat","metric carat" -CTN,4412494,"content ton (metric)","content ton (metric)" -D03,4468787,"kW·h/h","kilowatt hour per hour" -D04,4468788,"lot [unit of weight]","lot [unit of weight]" -D11,4469041,"Mibit","mebibit" -D23,4469299,"pen gram (protein)","pen gram (protein)" -D34,4469556,"tex (g/km)","tex" -D36,4469558,"Mbit","megabit" -D63,4470323,"book","book" -D65,4470325,"round","round" -D68,4470328,"number of words","number of words" -D78,4470584,"MJ/s","megajoule per second" -DAD,4473156,"ten day","ten day" -DB,17474,"dry pound","dry pound" -DEC,4474179,"decade","decade" -DMO,4476239,"standard kilolitre","standard kilolitre" -DPC,4476995,"dozen piece","dozen piece" -DPR,4477010,"dozen pair","dozen pair" -DPT,4477012,"displacement tonnage","displacement tonnage" -DRA,4477505,"dram (US)","dram (US)" -DRI,4477513,"dram (UK)","dram (UK)" -DRL,4477516,"dozen roll","dozen roll" -DT,17492,"dry ton","dry ton" -DWT,4478804,"pennyweight","pennyweight" -DZN,4479566,"DOZ","dozen" -DZP,4479568,"dozen pack","dozen pack" -E07,4534327,"MW·h/h","megawatt hour per hour" -E08,4534328,"MW/Hz","megawatt per hertz" -E10,4534576,"deg da","degree day" -E11,4534577,"gigacalorie","gigacalorie" -E12,4534578,"mille","mille" -E16,4534582,"BtuIT/h","million Btu(IT) per hour" -E17,4534583,"ft³/s","cubic foot per second" -E19,4534585,"ping","ping" -E20,4534832,"Mbit/s","megabit per second" -E21,4534833,"shares","shares" -E22,4534834,"TEU","TEU" -E23,4534835,"tyre","tyre" -E25,4534837,"active unit","active unit" -E27,4534839,"dose","dose" -E28,4534840,"air dry ton","air dry ton" -E30,4535088,"strand","strand" -E31,4535089,"m²/l","square metre per litre" -E32,4535090,"l/h","litre per hour" -E33,4535091,"foot per thousand","foot per thousand" -E34,4535092,"Gbyte","gigabyte" -E35,4535093,"Tbyte","terabyte" -E36,4535094,"Pbyte","petabyte" -E37,4535095,"pixel","pixel" -E38,4535096,"megapixel","megapixel" -E39,4535097,"dpi","dots per inch" -E4,17716,"gross kilogram","gross kilogram" -E40,4535344,"ppht","part per hundred thousand" -E44,4535348,"kgf·m/cm²","kilogram-force metre per square centimetre" -E46,4535350,"kW·h/m³","kilowatt hour per cubic metre" -E47,4535351,"kW·h/K","kilowatt hour per kelvin" -E48,4535352,"service unit","service unit" -E49,4535353,"working day","working day" -E50,4535600,"accounting unit","accounting unit" -E51,4535601,"job","job" -E52,4535602,"run foot","run foot" -E53,4535603,"test","test" -E54,4535604,"trip","trip" -E55,4535605,"use","use" -E56,4535606,"well","well" -E57,4535607,"zone","zone" -E58,4535608,"Ebit/s","exabit per second" -E59,4535609,"Eibyte","exbibyte" -E60,4535856,"Pibyte","pebibyte" -E61,4535857,"Tibyte","tebibyte" -E62,4535858,"Gibyte","gibibyte" -E63,4535859,"Mibyte","mebibyte" -E64,4535860,"Kibyte","kibibyte" -E65,4535861,"Eibit/m","exbibit per metre" -E66,4535862,"Eibit/m²","exbibit per square metre" -E67,4535863,"Eibit/m³","exbibit per cubic metre" -E68,4535864,"Gbyte/s","gigabyte per second" -E69,4535865,"Gibit/m","gibibit per metre" -E70,4536112,"Gibit/m²","gibibit per square metre" -E71,4536113,"Gibit/m³","gibibit per cubic metre" -E72,4536114,"Kibit/m","kibibit per metre" -E73,4536115,"Kibit/m²","kibibit per square metre" -E74,4536116,"Kibit/m³","kibibit per cubic metre" -E75,4536117,"Mibit/m","mebibit per metre" -E76,4536118,"Mibit/m²","mebibit per square metre" -E77,4536119,"Mibit/m³","mebibit per cubic metre" -E78,4536120,"Pbit","petabit" -E79,4536121,"Pbit/s","petabit per second" -E80,4536368,"Pibit/m","pebibit per metre" -E81,4536369,"Pibit/m²","pebibit per square metre" -E82,4536370,"Pibit/m³","pebibit per cubic metre" -E83,4536371,"Tbit","terabit" -E84,4536372,"Tbit/s","terabit per second" -E85,4536373,"Tibit/m","tebibit per metre" -E86,4536374,"Tibit/m³","tebibit per cubic metre" -E87,4536375,"Tibit/m²","tebibit per square metre" -E88,4536376,"bit/m","bit per metre" -E89,4536377,"bit/m²","bit per square metre" -E90,4536624,"cm⁻¹","reciprocal centimetre" -E91,4536625,"d⁻¹","reciprocal day" -EA,17729,"each","each" -EB,17730,"electronic mail box","electronic mail box" -EQ,17745,"equivalent gallon","equivalent gallon" -F01,4599857,"bit/m³","bit per cubic metre" -FBM,4604493,"fibre metre","fibre metre" -FC,17987,"kft³","thousand cubic foot" -FF,17990,"hundred cubic metre","hundred cubic metre" -FIT,4606292,"FIT","failures in time" -FL,17996,"flake ton","flake ton" -GB,18242,"gal (US)/d","gallon (US) per day" -GDW,4670551,"gram, dry weight","gram, dry weight" -GFI,4671049,"gi F/S","gram of fissile isotope" -GGR,4671314,"great gross","great gross" -GIA,4671809,"gi (US)","gill (US)" -GIC,4671811,"gram, including container","gram, including container" -GII,4671817,"gi (UK)","gill (UK)" -GIP,4671824,"gram, including inner packaging","gram, including inner packaging" -GRO,4674127,"gr","gross" -GRT,4674132,"gross register ton","gross register ton" -GT,18260,"gross ton","gross ton" -H21,4731441,"blank","blank" -H25,4731445,"%/K","percent per kelvin" -H71,4732721,"%/mo","percent per month" -H72,4732722,"%/hbar","percent per hectobar" -H73,4732723,"%/daK","percent per decakelvin" -H77,4732727,"MW","module width" -H80,4732976,"U or RU","rack unit" -H82,4732978,"bp","big point" -H87,4732983,"piece","piece" -H89,4732985,"%/Ω","percent per ohm" -H90,4733232,"%/°","percent per degree" -H91,4733233,"%/10000","percent per ten thousand" -H92,4733234,"%/100000","percent per one hundred thousand" -H93,4733235,"%/100","percent per hundred" -H94,4733236,"%/1000","percent per thousand" -H95,4733237,"%/V","percent per volt" -H96,4733238,"%/bar","percent per bar" -H98,4733240,"%/in","percent per inch" -H99,4733241,"%/m","percent per metre" -HA,18497,"hank","hank" -HBX,4735576,"hundred boxes","hundred boxes" -HC,18499,"hundred count","hundred count" -HDW,4736087,"hundred kilogram, dry weight","hundred kilogram, dry weight" -HEA,4736321,"head","head" -HH,18504,"hundred cubic foot","hundred cubic foot" -HIU,4737365,"hundred international unit","hundred international unit" -HKM,4737869,"hundred kilogram, net mass","hundred kilogram, net mass" -HMQ,4738385,"Mm³","million cubic metre" -HPA,4739137,"hectolitre of pure alcohol","hectolitre of pure alcohol" -IE,18757,"person","person" -ISD,4805444,"international sugar degree","international sugar degree" -IUG,4805959,"international unit per gram","international unit per gram" -J10,4862256,"%/mm","percent per millimetre" -J12,4862258,"‰/psi","per mille per psi" -J13,4862259,"°API","degree API" -J14,4862260,"°Bé","degree Baume (origin scale)" -J15,4862261,"°Bé (US heavy)","degree Baume (US heavy)" -J16,4862262,"°Bé (US light)","degree Baume (US light)" -J17,4862263,"°Balling","degree Balling" -J18,4862264,"°Bx","degree Brix" -J27,4862519,"°Oechsle","degree Oechsle" -J31,4862769,"°Tw","degree Twaddell" -J38,4862776,"Bd","baud" -J54,4863284,"MBd","megabaud" -JNT,4869716,"pipeline joint","pipeline joint" -JPS,4870227,"hundred metre","hundred metre" -JWL,4872012,"number of jewels","number of jewels" -K1,19249,"kilowatt demand","kilowatt demand" -K2,19250,"kilovolt ampere reactive demand","kilovolt ampere reactive demand" -K3,19251,"kvar·h","kilovolt ampere reactive hour" -K50,4928816,"kBd","kilobaud" -KA,19265,"cake","cake" -KB,19266,"kilocharacter","kilocharacter" -KCC,4932419,"kg C₅ H₁₄ClNO","kilogram of choline chloride" -KDW,4932695,"kg/net eda","kilogram drained net weight" -KHY,4933721,"kg H₂O₂","kilogram of hydrogen peroxide" -KI,19273,"kilogram per millimetre width","kilogram per millimetre width" -KIC,4933955,"kilogram, including container","kilogram, including container" -KIP,4933968,"kilogram, including inner packaging","kilogram, including inner packaging" -KJ,19274,"kilosegment","kilosegment" -KLK,4934731,"lactic dry material percentage","lactic dry material percentage" -KMA,4934977,"kg met.am.","kilogram of methylamine" -KNI,4935241,"kg N","kilogram of nitrogen" -KNS,4935251,"kilogram named substance","kilogram named substance" -KO,19279,"milliequivalence caustic potash per gram of product","milliequivalence caustic potash per gram of product" -KPH,4935752,"kg KOH","kilogram of potassium hydroxide (caustic potash)" -KPO,4935759,"kg K₂O","kilogram of potassium oxide" -KPP,4935760,"kilogram of phosphorus pentoxide (phosphoric anhydride)","kilogram of phosphorus pentoxide (phosphoric anhydride)" -KSD,4936516,"kg 90 % sdt","kilogram of substance 90 % dry" -KSH,4936520,"kg NaOH","kilogram of sodium hydroxide (caustic soda)" -KT,19284,"kit","kit" -KUR,4937042,"kg U","kilogram of uranium" -KWY,4937561,"kW/year","kilowatt year" -KWO,4937551,"kg WO₃","kilogram of tungsten trioxide" -LAC,4997443,"lactose excess percentage","lactose excess percentage" -LBT,4997716,"troy pound (US)","troy pound (US)" -LEF,4998470,"leaf","leaf" -LF,19526,"linear foot","linear foot" -LH,19528,"labour hour","labour hour" -LK,19531,"link","link" -LM,19533,"linear metre","linear metre" -LN,19534,"length","length" -LO,19535,"lot [unit of procurement]","lot [unit of procurement]" -LP,19536,"liquid pound","liquid pound" -LPA,5001281,"litre of pure alcohol","litre of pure alcohol" -LR,19538,"layer","layer" -LS,19539,"lump sum","lump sum" -LUB,5002562,"metric ton, lubricating oil","metric ton, lubricating oil" -LY,19545,"linear yard","linear yard" -M19,5058873,"Bft","Beaufort" -M25,5059125,"%/°C","percent per degree Celsius" -M36,5059382,"mo (30 days)","30-day month" -M37,5059383,"y (360 days)","actual/360" -M4,19764,"monetary value","monetary value" -M9,19769,"MBTU/kft³","million Btu per 1000 cubic foot" -MAH,5062984,"Mvar·h","megavolt ampere reactive hour" -MBE,5063237,"thousand standard brick equivalent","thousand standard brick equivalent" -MBF,5063238,"thousand board foot","thousand board foot" -MD,19780,"air dry metric ton","air dry metric ton" -MIL,5065036,"thousand","thousand" -MIO,5065039,"million","million" -MIU,5065045,"million international unit","million international unit" -MLD,5065796,"milliard","milliard" -MND,5066308,"kilogram, dry weight","kilogram, dry weight" -N1,20017,"pen calorie","pen calorie" -N3,20019,"print point","print point" -NAR,5128530,"number of articles","number of articles" -NCL,5129036,"number of cells","number of cells" -NF,20038,"message","message" -NIL,5130572,"()","nil" -NIU,5130581,"number of international units","number of international units" -NL,20044,"load","load" -NMP,5131600,"number of packs","number of packs" -NPR,5132370,"number of pairs","number of pairs" -NPT,5132372,"number of parts","number of parts" -NT,20052,"net ton","net ton" -NTT,5133396,"net register ton","net register ton" -NX,20056,"‰","part per thousand" -OA,20289,"panel","panel" -ODE,5194821,"ozone depletion equivalent","ozone depletion equivalent" -ODG,5194823,"ODS Grams","ODS Grams" -ODK,5194827,"ODS Kilograms","ODS Kilograms" -ODM,5194829,"ODS Milligrams","ODS Milligrams" -OT,20308,"overtime hour","overtime hour" -OZ,20314,"ounce av","ounce av" -P1,20529,"% or pct","percent" -P5,20533,"five pack","five pack" -P88,5257272,"rhe","rhe" -P89,5257273,"lbf·ft/in","pound-force foot per inch" -P90,5257520,"lbf·in/in","pound-force inch per inch" -P91,5257521,"perm (0 ºC)","perm (0 ºC)" -P92,5257522,"perm (23 ºC)","perm (23 ºC)" -P93,5257523,"byte/s","byte per second" -P94,5257524,"kbyte/s","kilobyte per second" -P95,5257525,"Mbyte/s","megabyte per second" -P96,5257526,"1/V","reciprocal volt" -P97,5257527,"1/rad","reciprocal radian" -P98,5257528,"PaΣνB","pascal to the power sum of stoichiometric numbers" -P99,5257529,"(mol/m³)∑νB","mole per cubiv metre to the power sum of stoichiometric numbers" -PD,20548,"pad","pad" -PFL,5260876,"proof litre","proof litre" -PGL,5261132,"proof gallon","proof gallon" -PI,20553,"pitch","pitch" -PLA,5262401,"°P","degree Plato" -PQ,20561,"ppi","page per inch" -PR,20562,"pair","pair" -PTN,5264462,"PTN","portion" -Q10,5321008,"J/T","joule per tesla" -Q11,5321009,"E","erlang" -Q12,5321010,"o","octet" -Q13,5321011,"o/s","octet per second" -Q14,5321012,"Sh","shannon" -Q15,5321013,"Hart","hartley" -Q16,5321014,"nat","natural unit of information" -Q17,5321015,"Sh/s","shannon per second" -Q18,5321016,"Hart/s","hartley per second" -Q19,5321017,"nat/s","natural unit of information per second" -Q20,5321264,"s/kg","second per kilogramm" -Q21,5321265,"W·m²","watt square metre" -Q22,5321266,"1/(Hz·rad·m³)","second per radian cubic metre" -Q23,5321267,"1/Wb","weber to the power minus one" -Q24,5321268,"1/in","reciprocal inch" -Q25,5321269,"dpt","dioptre" -Q26,5321270,"1/1","one per one" -Q27,5321271,"N·m/m²","newton metre per metre" -Q28,5321272,"kg/(m²·Pa·s)","kilogram per square metre pascal second" -Q36,5321526,"m2/m3","square metre per cubic metre" -Q3,20787,"meal","meal" -QA,20801,"page - facsimile","page - facsimile" -QAN,5325134,"quarter (of a year)","quarter (of a year)" -QB,20802,"page - hardcopy","page - hardcopy" -QR,20818,"qr","quire" -QTR,5330002,"Qr (UK)","quarter (UK)" -R1,21041,"pica","pica" -R9,21049,"thousand cubic metre","thousand cubic metre" -RH,21064,"running or operating hour","running or operating hour" -RM,21069,"ream","ream" -ROM,5394253,"room","room" -RP,21072,"pound per ream","pound per ream" -RT,21076,"revenue ton mile","revenue ton mile" -SAN,5456206,"half year (6 months)","half year (6 months)" -SCO,5456719,"score","score" -SCR,5456722,"scruple","scruple" -SET,5457236,"set","set" -SG,21319,"segment","segment" -SHT,5458004,"shipping ton","shipping ton" -SQ,21329,"square","square" -SQR,5460306,"square, roofing","square, roofing" -SR,21330,"strip","strip" -STC,5461059,"stick","stick" -STK,5461067,"stick, cigarette","stick, cigarette" -STL,5461068,"standard litre","standard litre" -STW,5461079,"straw","straw" -SW,21335,"skein","skein" -SX,21336,"shipment","shipment" -SYR,5462354,"syringe","syringe" -T0,21552,"telecommunication line in service","telecommunication line in service" -T3,21555,"thousand piece","thousand piece" -TAN,5521742,"TAN","total acid number" -TI,21577,"thousand square inch","thousand square inch" -TIC,5523779,"metric ton, including container","metric ton, including container" -TIP,5523792,"metric ton, including inner packaging","metric ton, including inner packaging" -TKM,5524301,"t·km","tonne kilometre" -TMS,5524819,"kilogram of imported meat, less offal","kilogram of imported meat, less offal" -TP,21584,"ten pack","ten pack" -TPI,5525577,"TPI","teeth per inch" -TPR,5525586,"ten pair","ten pair" -TQD,5525828,"km³/d","thousand cubic metre per day" -TRL,5526092,"trillion (EUR)","trillion (EUR)" -TST,5526356,"ten set","ten set" -TTS,5526611,"ten thousand sticks","ten thousand sticks" -U1,21809,"treatment","treatment" -U2,21810,"tablet","tablet" -UB,21826,"telecommunication line in service average","telecommunication line in service average" -UC,21827,"telecommunication port","telecommunication port" -VA,22081,"V·A / kg","volt - ampere per kilogram" -VP,22096,"percent volume","percent volume" -W2,22322,"wet kilo","wet kilo" -WA,22337,"W/kg","watt per kilogram" -WB,22338,"wet pound","wet pound" -WCD,5718852,"cord","cord" -WE,22341,"wet ton","wet ton" -WG,22343,"wine gallon","wine gallon" -WM,22349,"working month","working month" -WSD,5722948,"std","standard" -WW,22359,"millilitre of water","millilitre of water" -Z11,5910833,"hanging container","hanging container" -ZP,23120,"page","page" -ZZ,23130,"mutually defined","mutually defined" -MRW,5067351,"m·wk","Metre Week" -MKW,5065559,"m²· wk","Square Metre Week" -MQW,5067095,"m³·wk","Cubic Metre Week" -HWE,4740933,"piece·k","Piece Week" -MRD,5067332,"m·day","Metre Day" -MKD,5065540,"m²·d","Square Metre Day" -MQD,5067076,"m³·d","Cubic Metre Day" -HAD,4735300,"piece·d","Piece Day" -MRM,5067341,"m·mo","Metre Month" -MKM,5065549,"m²·mo","Square Metre Month" -MQM,5067085,"m³·mo","Cubic Metre Month" -HMO,4738383,"piece·mo","Piece Month" -DBW,4473431,"dBW","Decibel watt" -DBM,4473421,"dBm","Decibel-milliwatts" -FNU,4607573,"FNU","Formazin nephelometric unit" -NTU,5133397,"NTU","Nephelometric turbidity unit" diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA.csv b/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA.csv deleted file mode 100644 index f1923775..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodeSets/UNECE_to_OPCUA.csv +++ /dev/null @@ -1,1828 +0,0 @@ -UNECECode,UnitId,DisplayName,Description -C81,4405297,"rad","radian" -C25,4403765,"mrad","milliradian" -B97,4340023,"µrad","microradian" -DD,17476,"°","degree [unit of angle]" -D61,4470321,"'","minute [unit of angle]" -D62,4470322,"""","second [unit of angle]" -A91,4274481,"gon","gon" -M43,5059635,"mil","mil" -M44,5059636,"rev","revolution" -D27,4469303,"sr","steradian" -H57,4732215,"in/revolution","inch per two pi radiant" -MTR,5067858,"m","metre" -E96,4536630,"°/s","degree per second" -H27,4731447,"°/m","degree per metre" -M55,5059893,"m/rad","metre per radiant" -DMT,4476244,"dm","decimetre" -CMT,4410708,"cm","centimetre" -4H,13384,"µm","micrometre (micron)" -MMT,5066068,"mm","millimetre" -HMT,4738388,"hm","hectometre" -KMT,4934996,"km","kilometre" -C45,4404277,"nm","nanometre" -C52,4404530,"pm","picometre" -A71,4273969,"fm","femtometre" -A45,4273205,"dam","decametre" -NMI,5131593,"n mile","nautical mile" -A11,4272433,"Å","angstrom" -A12,4272434,"ua","astronomical unit" -C63,4404787,"pc","parsec" -F52,4601138,"m/K","metre per kelvin" -F50,4601136,"µm/K","micrometre per kelvin" -F51,4601137,"cm/K","centimetre per kelvin" -G06,4665398,"mm/bar","millimetre per bar" -H84,4732980,"g·mm","gram millimetre" -G04,4665396,"cm/bar","centimetre per bar" -G05,4665397,"m/bar","metre per bar" -H79,4732729,"Fg","French gauge" -AK,16715,"fth","fathom" -X1,22577,"ch (UK)","Gunter's chain" -INH,4804168,"in","inch" -M7,19767,"µin","micro-inch" -FOT,4607828,"ft","foot" -YRD,5853764,"yd","yard" -SMI,5459273,"mile","mile (statute mile)" -77,14135,"mil","milli-inch" -B57,4338999,"ly","light year" -F49,4600889,"rd (US)","rod [unit of distance]" -MAM,5062989,"Mm","megametre" -K13,4927795,"ft/°F","foot per degree Fahrenheit" -K17,4927799,"ft/psi","foot per psi" -K45,4928565,"in/°F","inch per degree Fahrenheit" -K46,4928566,"in/psi","inch per psi" -L98,4995384,"yd/°F","yard per degree Fahrenheit" -L99,4995385,"yd/psi","yard per psi" -M49,5059641,"ch (US survey)","chain (based on U.S. survey foot)" -M50,5059888,"fur","furlong" -M51,5059889,"ft (US survey)","foot (U.S. survey)" -M52,5059890,"mi (US survey)","mile (based on U.S. survey foot)" -M53,5059891,"m/Pa","metre per pascal" -MTK,5067851,"m²","square metre" -KMK,4934987,"km²","square kilometre" -H30,4731696,"µm²","square micrometre (square micron)" -H59,4732217,"m²/N","square metre per newton" -DAA,4473153,"daa","decare" -CMK,4410699,"cm²","square centimetre" -DMK,4476235,"dm²","square decimetre" -H16,4731190,"dam²","square decametre" -H18,4731192,"hm²","square hectometre" -MMK,5066059,"mm²","square millimetre" -ARE,4280901,"a","are" -HAR,4735314,"ha","hectare" -INK,4804171,"in²","square inch" -FTK,4609099,"ft²","square foot" -YDK,5850187,"yd²","square yard" -MIK,5065035,"mi²","square mile (statute mile)" -M48,5059640,"mi² (US survey)","square mile (based on U.S. survey foot)" -ACR,4277074,"acre","acre" -M47,5059639,"cmil","circular mil" -MTQ,5067857,"m³","cubic metre" -MAL,5062988,"Ml","megalitre" -LTR,5002322,"l","litre" -MMQ,5066065,"mm³","cubic millimetre" -CMQ,4410705,"cm³","cubic centimetre" -DMQ,4476241,"dm³","cubic decimetre" -MLT,5065812,"ml","millilitre" -HLT,4738132,"hl","hectolitre" -CLT,4410452,"cl","centilitre" -DMA,4476225,"dam³","cubic decametre" -H19,4731193,"hm³","cubic hectometre" -H20,4731440,"km³","cubic kilometre" -M71,5060401,"m³/Pa","cubic metre per pascal" -DLT,4475988,"dl","decilitre" -4G,13383,"µl","microlitre" -K6,19254,"kl","kilolitre" -A44,4273204,"dal","decalitre" -G94,4667700,"cm³/bar","cubic centimetre per bar" -G95,4667701,"l/bar","litre per bar" -G96,4667702,"m³/bar","cubic metre per bar" -G97,4667703,"ml/bar","millilitre per bar" -INQ,4804177,"in³","cubic inch" -FTQ,4609105,"ft³","cubic foot" -YDQ,5850193,"yd³","cubic yard" -GLI,4672585,"gal (UK)","gallon (UK)" -GLL,4672588,"gal (US)","gallon (US)" -PT,20564,"pt (US)","pint (US)" -PTI,5264457,"pt (UK)","pint (UK)" -QTI,5329993,"qt (UK)","quart (UK)" -PTL,5264460,"liq pt (US)","liquid pint (US)" -QTL,5329996,"liq qt (US)","liquid quart (US)" -PTD,5264452,"dry pt (US)","dry pint (US)" -OZI,5200457,"fl oz (UK)","fluid ounce (UK)" -QT,20820,"qt (US)","quart (US)" -J57,4863287,"bbl (UK liq.)","barrel (UK petroleum)" -K21,4928049,"ft³/°F","cubic foot per degree Fahrenheit" -K23,4928051,"ft³/psi","cubic foot per psi" -L43,4994099,"pk (UK)","peck (UK)" -L84,4995124,"British shipping ton","ton (UK shipping)" -L86,4995126,"(US) shipping ton","ton (US shipping)" -M11,5058865,"yd³/°F","cubic yard per degree Fahrenheit" -M14,5058868,"yd³/psi","cubic yard per psi" -OZA,5200449,"fl oz (US)","fluid ounce (US)" -BUI,4347209,"bushel (UK)","bushel (UK)" -BUA,4347201,"bu (US)","bushel (US)" -BLL,4344908,"barrel (US)","barrel (US)" -BLD,4344900,"bbl (US)","dry barrel (US)" -GLD,4672580,"dry gal (US)","dry gallon (US)" -QTD,5329988,"dry qt (US)","dry quart (US)" -G26,4665910,"st","stere" -G21,4665905,"cup (US)","cup [unit of volume]" -G24,4665908,"tablespoon (US)","tablespoon (US)" -G25,4665909,"teaspoon (US)","teaspoon (US)" -G23,4665907,"pk (US)","peck" -M67,5060151,"acre-ft (US survey)","acre-foot (based on U.S. survey foot)" -M68,5060152,"cord","cord (128 ft3)" -M69,5060153,"mi³","cubic mile (UK statute)" -M70,5060400,"RT","ton, register" -G27,4665911,"cm³/K","cubic centimetre per kelvin" -G29,4665913,"m³/K","cubic metre per kelvin" -G28,4665912,"l/K","litre per kelvin" -G30,4666160,"ml/K","millilitre per kelvin" -J36,4862774,"µl/l","microlitre per litre" -J87,4864055,"cm³/m³","cubic centimetre per cubic metre" -J91,4864305,"dm³/m³","cubic decimetre per cubic metre" -K62,4929074,"l/l","litre per litre" -L19,4993337,"ml/l","millilitre per litre" -L21,4993585,"mm³/m³","cubic millimetre per cubic metre" -SEC,5457219,"s","second [unit of time]" -MIN,5065038,"min","minute [unit of time]" -HUR,4740434,"h","hour" -DAY,4473177,"d","day" -B52,4338994,"ks","kilosecond" -C26,4403766,"ms","millisecond" -H70,4732720,"ps","picosecond" -B98,4340024,"µs","microsecond" -C47,4404279,"ns","nanosecond" -WEE,5719365,"wk","week" -MON,5066574,"mo","month" -ANN,4279886,"y","year" -D42,4469810,"y (tropical)","tropical year" -L95,4995381,"y (365 days)","common year" -L96,4995382,"y (sidereal)","sidereal year" -M56,5059894,"shake","shake" -2A,12865,"rad/s","radian per second" -M46,5059638,"r/min","revolution per minute" -2B,12866,"rad/s²","radian per second squared" -M45,5059637,"°/s²","degree [unit of angle] per second squared" -MTS,5067859,"m/s","metre per second" -KNT,4935252,"kn","knot" -KMH,4934984,"km/h","kilometre per hour" -C16,4403510,"mm/s","millimetre per second" -2M,12877,"cm/s","centimetre per second" -H49,4731961,"cm/h","centimetre per hour" -H81,4732977,"mm/min","millimetre per minute" -2X,12888,"m/min","metre per minute" -M59,5059897,"(m/s)/Pa","metre per second pascal" -H66,4732470,"mm/y","millimetre per year" -H67,4732471,"mm/h","millimetre per hour" -FR,18002,"ft/min","foot per minute" -IU,18773,"in/s","inch per second" -FS,18003,"ft/s","foot per second" -HM,18509,"mile/h","mile per hour (statute mile)" -J84,4864052,"(cm/s)/K","centimetre per second kelvin" -J85,4864053,"(cm/s)/bar","centimetre per second bar" -K14,4927796,"ft/h","foot per hour" -K18,4927800,"(ft/s)/°F","foot per second degree Fahrenheit" -K19,4927801,"(ft/s)/psi","foot per second psi" -K47,4928567,"(in/s)/°F","inch per second degree Fahrenheit" -K48,4928568,"(in/s)/psi","inch per second psi" -L12,4993330,"(m/s)/K","metre per second kelvin" -L13,4993331,"(m/s)/bar","metre per second bar" -M22,5059122,"(ml/min)/cm²","millilitre per square centimetre minute" -M57,5059895,"mi/min","mile per minute" -M58,5059896,"mi/s","mile per second" -M60,5060144,"m/h","metre per hour" -M61,5060145,"in/y","inch per year" -M62,5060146,"km/s","kilometre per second" -M63,5060147,"in/min","inch per minute" -M64,5060148,"yd/s","yard per second" -M65,5060149,"yd/min","yard per minute" -M66,5060150,"yd/h","yard per hour" -MSK,5067595,"m/s²","metre per second squared" -A76,4273974,"Gal","gal" -C11,4403505,"mGal","milligal" -M38,5059384,"km/s²","kilometre per second squared" -M39,5059385,"cm/s²","centimetre per second squared" -M41,5059633,"mm/s²","millimetre per second squared" -A73,4273971,"ft/s²","foot per second squared" -IV,18774,"in/s²","inch per second squared" -K40,4928560,"gn","standard acceleration of free fall" -M40,5059632,"yd/s²","yard per second squared" -M42,5059634,"mi/s²","mile (statute mile) per second squared" -C92,4405554,"m⁻¹","reciprocal metre" -Q32,5321522,"fl","femtolitre" -Q33,5321523,"pl","picolitre" -Q34,5321524,"nl","nanolitre" -AWG,4282183,"AWG","american wire gauge" -NM3,5131571,"Normalised cubic metre","Normalised cubic metre" -SM3,5459251,"Standard cubic metre","Standard cubic metre" -HTZ,4740186,"Hz","hertz" -KHZ,4933722,"kHz","kilohertz" -MHZ,5064794,"MHz","megahertz" -D29,4469305,"THz","terahertz" -A86,4274230,"GHz","gigahertz" -MTZ,5067866,"mHz","millihertz" -H10,4731184,"1/h","reciprocal hour" -H11,4731185,"1/mo","reciprocal month" -H09,4730937,"1/y","reciprocal year" -H85,4732981,"1/wk","reciprocal week" -C97,4405559,"s⁻¹","reciprocal second" -RPS,5394515,"r/s","revolutions per second" -RPM,5394509,"r/min","revolutions per minute" -C94,4405556,"min⁻¹","reciprocal minute" -C50,4404528,"Np","neper" -2N,12878,"dB","decibel" -M72,5060402,"B","bel" -C51,4404529,"Np/s","neper per second" -KGM,4933453,"kg","kilogram" -MC,19779,"µg","microgram" -DJ,17482,"dag","decagram" -DG,17479,"dg","decigram" -GRM,4674125,"g","gram" -CGM,4409165,"cg","centigram" -TNE,5525061,"t","tonne (metric ton)" -DTN,4478030,"dt or dtn","decitonne" -MGM,5064525,"mg","milligram" -HGM,4736845,"hg","hectogram" -KTN,4936782,"kt","kilotonne" -2U,12885,"Mg","megagram" -LBR,4997714,"lb","pound" -GRN,4674126,"gr","grain" -ONZ,5197402,"oz","ounce (avoirdupois)" -CWI,4413257,"cwt (UK)","hundred weight (UK)" -CWA,4413249,"cwt (US)","hundred pound (cwt) / hundred weight (US)" -LTN,5002318,"ton (UK)","ton (UK) or long ton (US)" -STI,5461065,"st","stone (UK)" -STN,5461070,"ton (US)","ton (US) or short ton (UK/US)" -APZ,4280410,"tr oz","troy ounce or apothecary ounce" -F13,4600115,"slug","slug" -K64,4929076,"lb/°F","pound (avoirdupois) per degree Fahrenheit" -L69,4994617,"t/K","tonne per kelvin" -L87,4995127,"ton (US)/°F","ton short per degree Fahrenheit" -M85,5060661,"ton, assay","ton, assay" -M86,5060662,"pfd","pfund" -KMQ,4934993,"kg/m³","kilogram per cubic metre" -23,12851,"g/cm³","gram per cubic centimetre" -D41,4469809,"t/m³","tonne per cubic metre" -GJ,18250,"g/ml","gram per millilitre" -B35,4338485,"kg/l or kg/L","kilogram per litre" -GL,18252,"g/l","gram per litre" -A93,4274483,"g/m³","gram per cubic metre" -GP,18256,"mg/m³","milligram per cubic metre" -B72,4339506,"Mg/m³","megagram per cubic metre" -B34,4338484,"kg/dm³","kilogram per cubic decimetre" -H64,4732468,"mg/g","milligram per gram" -H29,4731449,"µg/l","microgram per litre" -M1,19761,"mg/l","milligram per litre" -GQ,18257,"µg/m³","microgram per cubic metre" -G11,4665649,"g/(cm³·bar)","gram per cubic centimetre bar" -G33,4666163,"g/(cm³·K)","gram per cubic centimetre kelvin" -F23,4600371,"g/dm³","gram per cubic decimetre" -G12,4665650,"g/(dm³·bar)","gram per cubic decimetre bar" -G34,4666164,"g/(dm³·K)","gram per cubic decimetre kelvin" -G14,4665652,"g/(m³·bar)","gram per cubic metre bar" -G36,4666166,"g/(m³·K)","gram per cubic metre kelvin" -G13,4665651,"g/(l·bar)","gram per litre bar" -G35,4666165,"g/(l·K)","gram per litre kelvin" -G15,4665653,"g/(ml·bar)","gram per millilitre bar" -G37,4666167,"g/(ml·K)","gram per millilitre kelvin" -G31,4666161,"kg/cm³","kilogram per cubic centimetre" -G16,4665654,"kg/(cm³·bar)","kilogram per cubic centimetre bar" -G38,4666168,"kg/(cm³·K)","kilogram per cubic centimetre kelvin" -G18,4665656,"kg/(m³·bar)","kilogram per cubic metre bar" -G40,4666416,"kg/(m³·K)","kilogram per cubic metre kelvin" -H54,4732212,"(kg/dm³)/K","kilogram per cubic decimetre kelvin" -H55,4732213,"(kg/dm³)/bar","kilogram per cubic decimetre bar" -F14,4600116,"g/K","gram per kelvin" -F15,4600117,"kg/K","kilogram per kelvin" -F24,4600372,"kg/kmol","kilogram per kilomole" -G17,4665655,"kg/(l·bar)","kilogram per litre bar" -G39,4666169,"kg/(l·K)","kilogram per litre kelvin" -H53,4732211,"kg/bar","kilogram per bar" -F18,4600120,"kg·cm²","kilogram square centimetre" -F19,4600121,"kg·mm²","kilogram square millimetre" -F74,4601652,"g/bar","gram per bar" -F75,4601653,"mg/bar","milligram per bar" -F16,4600118,"mg/K","milligram per kelvin" -M73,5060403,"(kg/m³)/Pa","kilogram per cubic metre pascal" -87,14391,"lb/ft³","pound per cubic foot" -GE,18245,"lb/gal (US)","pound per gallon (US)" -LA,19521,"lb/in³","pound per cubic inch" -G32,4666162,"oz/yd³","ounce (avoirdupois) per cubic yard" -J34,4862772,"(µg/m³)/K","microgram per cubic metre kelvin" -J35,4862773,"(µg/m³)/bar","microgram per cubic metre bar" -K41,4928561,"gr/gal (US)","grain per gallon (US)" -K69,4929081,"(lb/ft³)/°F","pound (avoirdupois) per cubic foot degree Fahrenheit" -K70,4929328,"(lb/ft³)/psi","pound (avoirdupois) per cubic foot psi" -K71,4929329,"lb/gal (UK)","pound (avoirdupois) per gallon (UK)" -K75,4929333,"(lb/in³)/°F","pound (avoirdupois) per cubic inch degree Fahrenheit" -K76,4929334,"(lb/in³)/psi","pound (avoirdupois) per cubic inch psi" -K84,4929588,"lb/yd³","pound per cubic yard" -L17,4993335,"(mg/m³)/K","milligram per cubic metre kelvin" -L18,4993336,"(mg/m³)/bar","milligram per cubic metre bar" -L37,4993847,"oz/gal (UK)","ounce (avoirdupois) per gallon (UK)" -L38,4993848,"oz/gal (US)","ounce (avoirdupois) per gallon (US)" -L39,4993849,"oz/in³","ounce (avoirdupois) per cubic inch" -L65,4994613,"slug/ft³","slug per cubic foot" -L76,4994870,"(t/m³)/K","tonne per cubic metre kelvin" -L77,4994871,"(t/m³)/bar","tonne per cubic metre bar" -L92,4995378,"ton.l/yd³ (UK)","ton (UK long) per cubic yard" -L93,4995379,"ton.s/yd³ (US)","ton (US short) per cubic yard" -K77,4929335,"lb/psi","pound (avoirdupois) per psi" -L70,4994864,"t/bar","tonne per bar" -L91,4995377,"ton (US)/psi","ton short per psi" -M74,5060404,"kg/Pa","kilogram per pascal" -C62,4404786,"1","one" -A39,4272953,"m³/kg","cubic metre per kilogram" -22,12850,"dl/g","decilitre per gram" -H65,4732469,"ml/m³","millilitre per cubic metre" -H83,4732979,"l/kg","litre per kilogram" -KX,19288,"ml/kg","millilitre per kilogram" -H15,4731189,"cm²/g","square centimetre per gram" -N28,5124664,"dm³/kg","cubic decimetre per kilogram" -N29,5124665,"ft³/lb","cubic foot per pound" -N30,5124912,"in³/lb","cubic inch per pound" -KL,19276,"kg/m","kilogram per metre" -GF,18246,"g/m","gram per metre (gram per 100 centimetres)" -H76,4732726,"g/mm","gram per millimetre" -KW,19287,"kg/mm","kilogram per millimetre" -C12,4403506,"mg/m","milligram per metre" -M31,5059377,"kg/km","kilogram per kilometre" -P2,20530,"lb/ft","pound per foot" -PO,20559,"lb/in","pound per inch of length" -M83,5060659,"den","denier" -M84,5060660,"lb/yd","pound per yard" -GO,18255,"mg/m²","milligram per square metre" -25,12853,"g/cm²","gram per square centimetre" -H63,4732467,"mg/cm²","milligram per square centimetre" -GM,18253,"g/m²","gram per square metre" -28,12856,"kg/m²","kilogram per square metre" -D5,17461,"kg/cm²","kilogram per square centimetre" -ON,20302,"oz/yd²","ounce per square yard" -37,13111,"oz/ft²","ounce per square foot" -B31,4338481,"kg·m/s","kilogram metre per second" -M98,5060920,"kg·(cm/s)","kilogram centimetre per second" -M99,5060921,"g·(cm/s)","gram centimetre per second" -N10,5124400,"lb·(ft/s)","pound foot per second" -N11,5124401,"lb·(in/s)","pound inch per second" -B33,4338483,"kg·m²/s","kilogram metre squared per second" -B32,4338482,"kg·m²","kilogram metre squared" -F20,4600368,"lb·in²","pound inch squared" -K65,4929077,"lb·ft²","pound (avoirdupois) square foot" -NEW,5129559,"N","newton" -B73,4339507,"MN","meganewton" -B47,4338743,"kN","kilonewton" -C20,4403760,"mN","millinewton" -B92,4340018,"µN","micronewton" -DU,17493,"dyn","dyne" -C78,4405048,"lbf","pound-force" -B37,4338487,"kgf","kilogram-force" -B51,4338993,"kp","kilopond" -L40,4994096,"ozf","ounce (avoirdupois)-force" -L94,4995380,"ton.sh-force","ton-force (US short)" -M75,5060405,"kip","kilopound-force" -M76,5060406,"pdl","poundal" -M77,5060407,"kg·m/s²","kilogram metre per second squared" -M78,5060408,"p","pond" -F17,4600119,"lbf/ft","pound-force per foot" -F48,4600888,"lbf/in","pound-force per inch" -C54,4404532,"N·m²/kg²","newton metre squared per kilogram squared" -NU,20053,"N·m","newton metre" -H40,4731952,"N/A","newton per ampere" -B74,4339508,"MN·m","meganewton metre" -B48,4338744,"kN·m","kilonewton metre" -D83,4470835,"mN·m","millinewton metre" -B93,4340019,"µN·m","micronewton metre" -DN,17486,"dN·m","decinewton metre" -J72,4863794,"cN·m","centinewton metre" -M94,5060916,"kg·m","kilogram metre" -F88,4601912,"N·cm","newton centimetre" -F90,4602160,"N·m/A","newton metre per ampere" -F89,4601913,"Nm/°","newton metre per degree" -G19,4665657,"N·m/kg","newton metre per kilogram" -F47,4600887,"N/mm","newton per millimetre" -M93,5060915,"N·m/rad","newton metre per radian" -H41,4731953,"N·m·W⁻⁰‧⁵","newton metre watt to the power minus 0,5" -B38,4338488,"kgf·m","kilogram-force metre" -IA,18753,"in·lb","inch pound (pound inch)" -4Q,13393,"oz·in","ounce inch" -4R,13394,"oz·ft","ounce foot" -F22,4600370,"lbf·ft/A","pound-force foot per ampere" -F21,4600369,"lbf·in","pound-force inch" -G20,4665904,"lbf·ft/lb","pound-force foot per pound" -J94,4864308,"dyn·cm","dyne centimetre" -L41,4994097,"ozf·in","ounce (avoirdupois)-force inch" -M92,5060914,"lbf·ft","pound-force foot" -M95,5060917,"pdl·ft","poundal foot" -M96,5060918,"pdl·in","poundal inch" -M97,5060919,"dyn·m","dyne metre" -C57,4404535,"N·s","newton second" -C53,4404531,"N·m·s","newton metre second" -74,14132,"mPa","millipascal" -MPA,5066817,"MPa","megapascal" -PAL,5259596,"Pa","pascal" -KPA,4935745,"kPa","kilopascal" -BAR,4342098,"bar","bar [unit of pressure]" -HBA,4735553,"hbar","hectobar" -MBR,5063250,"mbar","millibar" -KBA,4932161,"kbar","kilobar" -ATM,4281421,"atm","standard atmosphere" -A89,4274233,"GPa","gigapascal" -B96,4340022,"µPa","micropascal" -A97,4274487,"hPa","hectopascal" -H75,4732725,"daPa","decapascal" -B85,4339765,"µbar","microbar" -C55,4404533,"N/m²","newton per square metre" -C56,4404534,"N/mm²","newton per square millimetre" -H07,4730935,"Pa·s/bar","pascal second per bar" -F94,4602164,"hPa·m³/s","hectopascal cubic metre per second" -F93,4602163,"hPa·l/s","hectopascal litre per second" -F82,4601906,"hPa/K","hectopascal per kelvin" -F83,4601907,"kPa/K","kilopascal per kelvin" -F98,4602168,"MPa·m³/s","megapascal cubic metre per second" -F97,4602167,"MPa·l/s","megapascal litre per second" -F85,4601909,"MPa/K","megapascal per kelvin" -F96,4602166,"mbar·m³/s","millibar cubic metre per second" -F95,4602165,"mbar·l/s","millibar litre per second" -F84,4601908,"mbar/K","millibar per kelvin" -G01,4665393,"Pa·m³/s","pascal cubic metre per second" -F99,4602169,"Pa·l/s","pascal litre per second" -F77,4601655,"Pa.s/K","pascal second per kelvin" -E01,4534321,"N/cm²","newton per square centimetre" -FP,18000,"lb/ft²","pound per square foot" -PS,20563,"lbf/in²","pound-force per square inch" -B40,4338736,"kgf/m²","kilogram-force per square metre" -UA,21825,"Torr","torr" -ATT,4281428,"at","technical atmosphere" -80,14384,"lb/in²","pound per square inch absolute" -H78,4732728,"cm H₂O","conventional centimetre of water" -HP,18512,"mm H₂O","conventional millimetre of water" -HN,18510,"mm Hg","conventional millimetre of mercury" -F79,4601657,"inHg","inch of mercury" -F78,4601656,"inH₂O","inch of water" -J89,4864057,"cm Hg","centimetre of mercury" -K24,4928052,"ft H₂O","foot of water" -K25,4928053,"ft Hg","foot of mercury" -K31,4928305,"gf/cm²","gram-force per square centimetre" -E42,4535346,"kgf/cm²","kilogram-force per square centimetre" -E41,4535345,"kgf·m/cm²","kilogram-force per square millimetre" -K85,4929589,"lbf/ft²","pound-force per square foot" -K86,4929590,"psi/°F","pound-force per square inch degree Fahrenheit" -84,14388,"klbf/in²","kilopound-force per square inch" -N13,5124403,"cmHg (0 ºC)","centimetre of mercury (0 ºC)" -N14,5124404,"cmH₂O (4 °C)","centimetre of water (4 ºC)" -N15,5124405,"ftH₂O (39,2 ºF)","foot of water (39.2 ºF)" -N16,5124406,"inHG (32 ºF)","inch of mercury (32 ºF)" -N17,5124407,"inHg (60 ºF)","inch of mercury (60 ºF)" -N18,5124408,"inH₂O (39,2 ºF)","inch of water (39.2 ºF)" -N19,5124409,"inH₂O (60 ºF)","inch of water (60 ºF)" -N20,5124656,"ksi","kip per square inch" -N21,5124657,"pdl/ft²","poundal per square foot" -N22,5124658,"oz/in²","ounce (avoirdupois) per square inch" -N23,5124659,"mH₂O","conventional metre of water" -N24,5124660,"g/mm²","gram per square millimetre" -N25,5124661,"lb/yd²","pound per square yard" -N26,5124662,"pdl/in²","poundal per square inch" -E99,4536633,"hPa/bar","hectopascal per bar" -F05,4599861,"MPa/bar","megapascal per bar" -F04,4599860,"mbar/bar","millibar per bar" -F07,4599863,"Pa/bar","pascal per bar" -F03,4599859,"kPa/bar","kilopascal per bar" -L52,4994354,"psi/psi","psi per psi" -J56,4863286,"bar/bar","bar per bar" -C96,4405558,"Pa⁻¹","reciprocal pascal or pascal to the power minus one" -F58,4601144,"1/bar","reciprocal bar" -B83,4339763,"m⁴","metre to the fourth power" -G77,4667191,"mm⁴","millimetre to the fourth power" -D69,4470329,"in⁴","inch to the fourth power" -N27,5124663,"ft⁴","foot to the fourth power" -C65,4404789,"Pa·s","pascal second" -N37,5124919,"kg/(m·s)","kilogram per metre second" -N38,5124920,"kg/(m·min)","kilogram per metre minute" -C24,4403764,"mPa·s","millipascal second" -N36,5124918,"(N/m²)·s","newton second per square metre" -N39,5124921,"kg/(m·d)","kilogram per metre day" -N40,5125168,"kg/(m·h)","kilogram per metre hour" -N41,5125169,"g/(cm·s)","gram per centimetre second" -89,14393,"P","poise" -C7,17207,"cP","centipoise" -F06,4599862,"P/bar","poise per bar" -F86,4601910,"P/K","poise per kelvin" -J32,4862770,"µP","micropoise" -J73,4863795,"cP/K","centipoise per kelvin" -J74,4863796,"cP/bar","centipoise per bar" -K67,4929079,"lb/(ft·h)","pound per foot hour" -K68,4929080,"lb/(ft·s)","pound per foot second" -K91,4929841,"lbf·s/ft²","pound-force second per square foot" -K92,4929842,"lbf·s/in²","pound-force second per square inch" -L15,4993333,"mPa·s/K","millipascal second per kelvin" -L16,4993334,"mPa·s/bar","millipascal second per bar" -L64,4994612,"slug/(ft·s)","slug per foot second" -N34,5124916,"(pdl/ft²)·s","poundal second per square foot" -N35,5124917,"P/Pa","poise per pascal" -N42,5125170,"(pdl/in²)·s","poundal second per square inch" -N43,5125171,"lb/(ft·min)","pound per foot minute" -N44,5125172,"lb/(ft·d)","pound per foot day" -S4,21300,"m²/s","square metre per second" -M82,5060658,"(m²/s)/Pa","square metre per second pascal" -C17,4403511,"mm²/s","millimetre squared per second" -G41,4666417,"m²/(s·bar)","square metre per second bar" -G09,4665401,"m²/(s·K)","square metre per second kelvin" -91,14641,"St","stokes" -4C,13379,"cSt","centistokes" -G46,4666422,"St/bar","stokes per bar" -G10,4665648,"St/K","stokes per kelvin" -S3,21299,"ft²/s","square foot per second" -G08,4665400,"in²/s","square inch per second" -M79,5060409,"ft²/h","square foot per hour" -M80,5060656,"St/Pa","stokes per pascal" -M81,5060657,"cm²/s","square centimetre per second" -4P,13392,"N/m","newton per metre" -C22,4403762,"mN/m","millinewton per metre" -M23,5059123,"N/cm","newton per centimetre" -N31,5124913,"kN/m","kilonewton per metre" -DX,17496,"dyn/cm","dyne per centimetre" -N32,5124914,"pdl/in","poundal per inch" -N33,5124915,"lbf/yd","pound-force per yard" -M34,5059380,"N·m/m²","newton metre per square metre" -JOU,4869973,"J","joule" -KJO,4934223,"kJ","kilojoule" -A68,4273720,"EJ","exajoule" -C68,4404792,"PJ","petajoule" -D30,4469552,"TJ","terajoule" -GV,18262,"GJ","gigajoule" -3B,13122,"MJ","megajoule" -C15,4403509,"mJ","millijoule" -A70,4273968,"fJ","femtojoule" -A13,4272435,"aJ","attojoule" -WHR,5720146,"W·h","watt hour" -MWH,5068616,"MW·h","megawatt hour (1000 kW.h)" -KWH,4937544,"kW·h","kilowatt hour" -GWH,4675400,"GW·h","gigawatt hour" -D32,4469554,"TW·h","terawatt hour" -A53,4273459,"eV","electronvolt" -B71,4339505,"MeV","megaelectronvolt" -A85,4274229,"GeV","gigaelectronvolt" -B29,4338233,"keV","kiloelectronvolt" -A57,4273463,"erg","erg" -85,14389,"ft·lbf","foot pound-force" -N46,5125174,"ft·pdl","foot poundal" -N47,5125175,"in·pdl","inch poundal" -WTT,5723220,"W","watt" -KWT,4937556,"kW","kilowatt" -MAW,5062999,"MW","megawatt" -A90,4274480,"GW","gigawatt" -C31,4404017,"mW","milliwatt" -D80,4470832,"µW","microwatt" -F80,4601904,"water horse power","water horse power" -A63,4273715,"erg/s","erg per second" -A74,4273972,"ft·lbf/s","foot pound-force per second" -B39,4338489,"kgf·m/s","kilogram-force metre per second" -HJ,18506,"metric hp","metric horse power" -A25,4272693,"CV","cheval vapeur" -BHP,4343888,"BHP","brake horse power" -K15,4927797,"ft·lbf/h","foot pound-force per hour" -K16,4927798,"ft·lbf/min","foot pound-force per minute" -K42,4928562,"boiler hp","horsepower (boiler)" -N12,5124402,"PS","Pferdestaerke" -KGS,4933459,"kg/s","kilogram per second" -H56,4732214,"kg/(m²·s)","kilogram per square metre second" -M87,5060663,"(kg/s)/Pa","kilogram per second pascal" -4M,13389,"mg/h","milligram per hour" -F26,4600374,"g/d","gram per day" -F62,4601394,"g/(d·bar)","gram per day bar" -F35,4600629,"g/(d·K)","gram per day kelvin" -F27,4600375,"g/h","gram per hour" -F63,4601395,"g/(h·bar)","gram per hour bar" -F36,4600630,"g/(h·K)","gram per hour kelvin" -F28,4600376,"g/min","gram per minute" -F64,4601396,"g/(min·bar)","gram per minute bar" -F37,4600631,"g/(min·K)","gram per minute kelvin" -F29,4600377,"g/s","gram per second" -F65,4601397,"g/(s·bar)","gram per second bar" -F38,4600632,"g/(s·K)","gram per second kelvin" -F30,4600624,"kg/d","kilogram per day" -F66,4601398,"kg/(d·bar)","kilogram per day bar" -F39,4600633,"kg/(d·K)","kilogram per day kelvin" -E93,4536627,"kg/h","kilogram per hour" -F67,4601399,"kg/(h·bar)","kilogram per hour bar" -F40,4600880,"kg/(h·K)","kilogram per hour kelvin" -F31,4600625,"kg/min","kilogram per minute" -F68,4601400,"kg/(min·bar)","kilogram per minute bar" -F41,4600881,"kg/(min·K)","kilogram per minute kelvin" -F69,4601401,"kg/(s·bar)","kilogram per second bar" -F42,4600882,"kg/(s·K)","kilogram per second kelvin" -F32,4600626,"mg/d","milligram per day" -F70,4601648,"mg/(d·bar)","milligram per day bar" -F43,4600883,"mg/(d·K)","milligram per day kelvin" -F71,4601649,"mg/(h·bar)","milligram per hour bar" -F44,4600884,"mg/(h·K)","milligram per hour kelvin" -F33,4600627,"mg/min","milligram per minute" -F72,4601650,"mg/(min·bar)","milligram per minute bar" -F45,4600885,"mg/(min·K)","milligram per minute kelvin" -F34,4600628,"mg/s","milligram per second" -F73,4601651,"mg/(s·bar)","milligram per second bar" -F46,4600886,"mg/(s·K)","milligram per second kelvin" -F25,4600373,"g/Hz","gram per hertz" -4W,13399,"ton (US) /h","ton (US) per hour" -4U,13397,"lb/h","pound per hour" -K66,4929078,"lb/d","pound (avoirdupois) per day" -K73,4929331,"(lb/h)/°F","pound (avoirdupois) per hour degree Fahrenheit" -K74,4929332,"(lb/h)/psi","pound (avoirdupois) per hour psi" -K78,4929336,"lb/min","pound (avoirdupois) per minute" -K79,4929337,"lb/(min·°F)","pound (avoirdupois) per minute degree Fahrenheit" -K80,4929584,"(lb/min)/psi","pound (avoirdupois) per minute psi" -K81,4929585,"lb/s","pound (avoirdupois) per second" -K82,4929586,"(lb/s)/°F","pound (avoirdupois) per second degree Fahrenheit" -K83,4929587,"(lb/s)/psi","pound (avoirdupois) per second psi" -L33,4993843,"oz/d","ounce (avoirdupois) per day" -L34,4993844,"oz/h","ounce (avoirdupois) per hour" -L35,4993845,"oz/min","ounce (avoirdupois) per minute" -L36,4993846,"oz/s","ounce (avoirdupois) per second" -L63,4994611,"slug/d","slug per day" -L66,4994614,"slug/h","slug per hour" -L67,4994615,"slug/min","slug per minute" -L68,4994616,"slug/s","slug per second" -L71,4994865,"t/d","tonne per day" -L72,4994866,"(t/d)/K","tonne per day kelvin" -L73,4994867,"(t/d)/bar","tonne per day bar" -E18,4534584,"t/h","tonne per hour" -L74,4994868,"(t/h)/K","tonne per hour kelvin" -L75,4994869,"(t/h)/bar","tonne per hour bar" -L78,4994872,"t/min","tonne per minute" -L79,4994873,"(t/min)/K","tonne per minute kelvin" -L80,4995120,"(t/min)/bar","tonne per minute bar" -L81,4995121,"t/s","tonne per second" -L82,4995122,"(t/s)/K","tonne per second kelvin" -L83,4995123,"(t/s)/bar","tonne per second bar" -L85,4995125,"ton (UK)/d","ton long per day" -L88,4995128,"ton (US)/d","ton short per day" -L89,4995129,"ton (US)/(h·°F)","ton short per hour degree Fahrenheit" -L90,4995376,"(ton (US)/h)/psi","ton short per hour psi" -M88,5060664,"t/mo","tonne per month" -M89,5060665,"t/y","tonne per year" -M90,5060912,"klb/h","kilopound per hour" -J33,4862771,"µg/kg","microgram per kilogram" -L32,4993842,"ng/kg","nanogram per kilogram" -NA,20033,"mg/kg","milligram per kilogram" -M29,5059129,"kg/kg","kilogram per kilogram" -M91,5060913,"lb/lb","pound per pound" -MQS,5067091,"m³/s","cubic metre per second" -MQH,5067080,"m³/h","cubic metre per hour" -40,13360,"ml/s","millilitre per second" -41,13361,"ml/min","millilitre per minute" -LD,19524,"l/d","litre per day" -2J,12874,"cm³/s","cubic centimetre per second" -4X,13400,"kl/h","kilolitre per hour" -L2,19506,"l/min","litre per minute" -G47,4666423,"cm³/d","cubic centimetre per day" -G78,4667192,"cm³/(d·bar)","cubic centimetre per day bar" -G61,4666929,"cm³/(d·K)","cubic centimetre per day kelvin" -G48,4666424,"cm³/h","cubic centimetre per hour" -G79,4667193,"cm³/(h·bar)","cubic centimetre per hour bar" -G62,4666930,"cm³/(h·K)","cubic centimetre per hour kelvin" -G49,4666425,"cm³/min","cubic centimetre per minute" -G80,4667440,"cm³/(min·bar)","cubic centimetre per minute bar" -G63,4666931,"cm³/(min·K)","cubic centimetre per minute kelvin" -G81,4667441,"cm³/(s·bar)","cubic centimetre per second bar" -G64,4666932,"cm³/(s·K)","cubic centimetre per second kelvin" -E92,4536626,"dm³/h","cubic decimetre per hour" -G52,4666674,"m³/d","cubic metre per day" -G86,4667446,"m³/(d·bar)","cubic metre per day bar" -G69,4666937,"m³/(d·K)","cubic metre per day kelvin" -G87,4667447,"m³/(h·bar)","cubic metre per hour bar" -G70,4667184,"m³/(h·K)","cubic metre per hour kelvin" -G53,4666675,"m³/min","cubic metre per minute" -G88,4667448,"m³/(min·bar)","cubic metre per minute bar" -G71,4667185,"m³/(min·K)","cubic metre per minute kelvin" -G89,4667449,"m³/(s·bar)","cubic metre per second bar" -G72,4667186,"m³/(s·K)","cubic metre per second kelvin" -G82,4667442,"l/(d·bar)","litre per day bar" -G65,4666933,"l/(d·K)","litre per day kelvin" -G83,4667443,"l/(h·bar)","litre per hour bar" -G66,4666934,"l/(h·K)","litre per hour kelvin" -G84,4667444,"l/(min·bar)","litre per minute bar" -G67,4666935,"l/(min·K)","litre per minute kelvin" -G51,4666673,"l/s","litre per second" -G85,4667445,"l/(s·bar)","litre per second bar" -G68,4666936,"l/(s·K)","litre per second kelvin" -G54,4666676,"ml/d","millilitre per day" -G90,4667696,"ml/(d·bar)","millilitre per day bar" -G73,4667187,"ml/(d·K)","millilitre per day kelvin" -G55,4666677,"ml/h","millilitre per hour" -G91,4667697,"ml/(h·bar)","millilitre per hour bar" -G74,4667188,"ml/(h·K)","millilitre per hour kelvin" -G92,4667698,"ml/(min·bar)","millilitre per minute bar" -G75,4667189,"ml/(min·K)","millilitre per minute kelvin" -G93,4667699,"ml/(s·bar)","millilitre per second bar" -G76,4667190,"ml/(s·K)","millilitre per second kelvin" -2K,12875,"ft³/h","cubic foot per hour" -2L,12876,"ft³/min","cubic foot per minute" -5A,13633,"barrel (US)/min","barrel (US) per minute" -G2,18226,"gal (US) /min","US gallon per minute" -G3,18227,"gal (UK) /min","Imperial gallon per minute" -G56,4666678,"in³/h","cubic inch per hour" -G57,4666679,"in³/min","cubic inch per minute" -G58,4666680,"in³/s","cubic inch per second" -G50,4666672,"gal/h","gallon (US) per hour" -J58,4863288,"bbl (UK liq.)/min","barrel (UK petroleum) per minute" -J59,4863289,"bbl (UK liq.)/d","barrel (UK petroleum) per day" -J60,4863536,"bbl (UK liq.)/h","barrel (UK petroleum) per hour" -J61,4863537,"bbl (UK liq.)/s","barrel (UK petroleum) per second" -J62,4863538,"bbl (US)/h","barrel (US petroleum) per hour" -J63,4863539,"bbl (US)/s","barrel (US petroleum) per second" -J64,4863540,"bu (UK)/d","bushel (UK) per day" -J65,4863541,"bu (UK)/h","bushel (UK) per hour" -J66,4863542,"bu (UK)/min","bushel (UK) per minute" -J67,4863543,"bu (UK)/s","bushel (UK) per second" -J68,4863544,"bu (US dry)/d","bushel (US dry) per day" -J69,4863545,"bu (US dry)/h","bushel (US dry) per hour" -J70,4863792,"bu (US dry)/min","bushel (US dry) per minute" -J71,4863793,"bu (US dry)/s","bushel (US dry) per second" -J90,4864304,"dm³/d","cubic decimetre per day" -J92,4864306,"dm³/min","cubic decimetre per minute" -J93,4864307,"dm³/s","cubic decimetre per second" -N45,5125173,"(m³/s)/Pa","cubic metre per second pascal" -J95,4864309,"fl oz (UK)/d","ounce (UK fluid) per day" -J96,4864310,"fl oz (UK)/h","ounce (UK fluid) per hour" -J97,4864311,"fl oz (UK)/min","ounce (UK fluid) per minute" -J98,4864312,"fl oz (UK)/s","ounce (UK fluid) per second" -J99,4864313,"fl oz (US)/d","ounce (US fluid) per day" -K10,4927792,"fl oz (US)/h","ounce (US fluid) per hour" -K11,4927793,"fl oz (US)/min","ounce (US fluid) per minute" -K12,4927794,"fl oz (US)/s","ounce (US fluid) per second" -K22,4928050,"ft³/d","cubic foot per day" -K26,4928054,"gal (UK)/d","gallon (UK) per day" -K27,4928055,"gal (UK)/h","gallon (UK) per hour" -K28,4928056,"gal (UK)/s","gallon (UK) per second" -K30,4928304,"gal (US liq.)/s","gallon (US liquid) per second" -K32,4928306,"gi (UK)/d","gill (UK) per day" -K33,4928307,"gi (UK)/h","gill (UK) per hour" -K34,4928308,"gi (UK)/min","gill (UK) per minute" -K35,4928309,"gi (UK)/s","gill (UK) per second" -K36,4928310,"gi (US)/d","gill (US) per day" -K37,4928311,"gi (US)/h","gill (US) per hour" -K38,4928312,"gi (US)/min","gill (US) per minute" -K39,4928313,"gi (US)/s","gill (US) per second" -K94,4929844,"qt (UK liq.)/d","quart (UK liquid) per day" -K95,4929845,"qt (UK liq.)/h","quart (UK liquid) per hour" -K96,4929846,"qt (UK liq.)/min","quart (UK liquid) per minute" -K97,4929847,"qt (UK liq.)/s","quart (UK liquid) per second" -K98,4929848,"qt (US liq.)/d","quart (US liquid) per day" -K99,4929849,"qt (US liq.)/h","quart (US liquid) per hour" -L10,4993328,"qt (US liq.)/min","quart (US liquid) per minute" -L11,4993329,"qt (US liq.)/s","quart (US liquid) per second" -L44,4994100,"pk (UK)/d","peck (UK) per day" -L45,4994101,"pk (UK)/h","peck (UK) per hour" -L46,4994102,"pk (UK)/min","peck (UK) per minute" -L47,4994103,"pk (UK)/s","peck (UK) per second" -L48,4994104,"pk (US dry)/d","peck (US dry) per day" -L49,4994105,"pk (US dry)/h","peck (US dry) per hour" -L50,4994352,"pk (US dry)/min","peck (US dry) per minute" -L51,4994353,"pk (US dry)/s","peck (US dry) per second" -L53,4994355,"pt (UK)/d","pint (UK) per day" -L54,4994356,"pt (UK)/h","pint (UK) per hour" -L55,4994357,"pt (UK)/min","pint (UK) per minute" -L56,4994358,"pt (UK)/s","pint (UK) per second" -L57,4994359,"pt (US liq.)/d","pint (US liquid) per day" -L58,4994360,"pt (US liq.)/h","pint (US liquid) per hour" -L59,4994361,"pt (US liq.)/min","pint (US liquid) per minute" -L60,4994608,"pt (US liq.)/s","pint (US liquid) per second" -M12,5058866,"yd³/d","cubic yard per day" -M13,5058867,"yd³/h","cubic yard per hour" -M15,5058869,"yd³/min","cubic yard per minute" -M16,5058870,"yd³/s","cubic yard per second" -H60,4732464,"m³/m³","cubic metre per cubic metre" -F92,4602162,"bar·m³/s","bar cubic metre per second" -F91,4602161,"bar·l/s","bar litre per second" -K87,4929591,"psi·in³/s","psi cubic inch per second" -K88,4929592,"psi·l/s","psi litre per second" -K89,4929593,"psi·m³/s","psi cubic metre per second" -K90,4929840,"psi·yd³/s","psi cubic yard per second" -Q29,5321273,"µg/hg","microgram per hectogram" -Q37,5321527,"Standard cubic metre per day","Standard cubic metre per day" -Q38,5321528,"Standard cubic metre per hour","Standard cubic metre per hour" -Q39,5321529,"Normalized cubic metre per day","Normalized cubic metre per day" -Q40,5321776,"Normalized cubic metre per hour","Normalized cubic metre per hour" -KWN,4937550,"Kilowatt hour per normalized cubic metre","Kilowatt hour per normalized cubic metre" -KWS,4937555,"Kilowatt hour per standard cubic metre","Kilowatt hour per standard cubic metre" -Q41,5321777,"Joule per normalised cubic metre","Joule per normalised cubic metre" -Q42,5321778,"Joule per standard cubic metre","Joule per standard cubic metre" -MNJ,5066314,"MJ/m³","Mega Joule per Normalised cubic Metre" -KEL,4932940,"K","kelvin" -CEL,4408652,"°C","degree Celsius" -H12,4731186,"°C/h","degree Celsius per hour" -F60,4601392,"°C/bar","degree Celsius per bar" -E98,4536632,"°C/K","degree Celsius per kelvin" -H13,4731187,"°C/min","degree Celsius per minute" -H14,4731188,"°C/s","degree Celsius per second" -F61,4601393,"K/bar","kelvin per bar" -F10,4600112,"K/h","kelvin per hour" -F02,4599858,"K/K","kelvin per kelvin" -F11,4600113,"K/min","kelvin per minute" -F12,4600114,"K/s","kelvin per second" -N79,5125945,"K/Pa","kelvin per pascal" -J20,4862512,"°F/K","degree Fahrenheit per kelvin" -J21,4862513,"°F/bar","degree Fahrenheit per bar" -J26,4862518,"1/°F","reciprocal degree Fahrenheit" -A48,4273208,"°R","degree Rankine" -FAH,4604232,"°F","degree Fahrenheit" -J23,4862515,"°F/h","degree Fahrenheit per hour" -J24,4862516,"°F/min","degree Fahrenheit per minute" -J25,4862517,"°F/s","degree Fahrenheit per second" -J28,4862520,"°R/h","degree Rankine per hour" -J29,4862521,"°R/min","degree Rankine per minute" -J30,4862768,"°R/s","degree Rankine per second" -C91,4405553,"K⁻¹","reciprocal kelvin or kelvin to the power minus one" -M20,5059120,"1/MK","reciprocal megakelvin or megakelvin to the power minus one" -C64,4404788,"Pa/K","pascal per kelvin" -F81,4601905,"bar/K","bar per kelvin" -J55,4863285,"W·s","watt second" -BTU,4346965,"BtuIT","British thermal unit (international table)" -A1,16689,"cal₁₅","15 °C calorie" -D70,4470576,"calIT","calorie (international table)" -J39,4862777,"Btu","British thermal unit (mean)" -J75,4863797,"cal","calorie (mean)" -K51,4928817,"kcal","kilocalorie (mean)" -E14,4534580,"kcalIT","kilocalorie (international table)" -K53,4928819,"kcalth","kilocalorie (thermochemical)" -N66,5125686,"Btu (39 ºF)","British thermal unit (39 ºF)" -N67,5125687,"Btu (59 ºF)","British thermal unit (59 ºF)" -N68,5125688,"Btu (60 ºF)","British thermal unit (60 ºF)" -N69,5125689,"cal₂₀","calorie (20 ºC)" -N70,5125936,"quad","quad (1015 BtuIT)" -N71,5125937,"thm (EC)","therm (EC)" -N72,5125938,"thm (US)","therm (U.S.)" -D35,4469557,"calth","calorie (thermochemical)" -2I,12873,"BtuIT/h","British thermal unit (international table) per hour" -J44,4863028,"BtuIT/min","British thermal unit (international table) per minute" -J45,4863029,"BtuIT/s","British thermal unit (international table) per second" -J47,4863031,"Btuth/h","British thermal unit (thermochemical) per hour" -J51,4863281,"Btuth/min","British thermal unit (thermochemical) per minute" -J52,4863282,"Btuth/s","British thermal unit (thermochemical) per second" -J81,4864049,"calth/min","calorie (thermochemical) per minute" -J82,4864050,"calth/s","calorie (thermochemical) per second" -E15,4534581,"kcalth/h","kilocalorie (thermochemical) per hour" -K54,4928820,"kcalth/min","kilocalorie (thermochemical) per minute" -K55,4928821,"kcalth/s","kilocalorie (thermochemical) per second" -D54,4470068,"W/m²","watt per square metre" -N48,5125176,"W/cm²","watt per square centimetre" -N49,5125177,"W/in²","watt per square inch" -N50,5125424,"BtuIT/(ft²·h)","British thermal unit (international table) per square foot hour" -N51,5125425,"Btuth/(ft²·h)","British thermal unit (thermochemical) per square foot hour" -N52,5125426,"Btuth/(ft²·min)","British thermal unit (thermochemical) per square foot minute" -N53,5125427,"BtuIT/(ft²·s)","British thermal unit (international table) per square foot second" -N54,5125428,"Btuth/(ft²·s)","British thermal unit (thermochemical) per square foot second" -N55,5125429,"BtuIT/(in²·s)","British thermal unit (international table) per square inch second" -N56,5125430,"calth/(cm²·min)","calorie (thermochemical) per square centimetre minute" -N57,5125431,"calth/(cm²·s)","calorie (thermochemical) per square centimetre second" -D53,4470067,"W/(m·K)","watt per metre kelvin" -N80,5126192,"W/(m·°C)","watt per metre degree Celsius" -N81,5126193,"kW/(m·K)","kilowatt per metre kelvin" -N82,5126194,"kW/(m·°C)","kilowatt per metre degree Celsius" -A22,4272690,"BtuIT/(s·ft·°R)","British thermal unit (international table) per second foot degree Rankine" -D71,4470577,"calIT/(s·cm·K)","calorie (international table) per second centimetre kelvin" -D38,4469560,"calth/(s·cm·K)","calorie (thermochemical) per second centimetre kelvin" -J40,4863024,"BtuIT·ft/(h·ft²·°F)","British thermal unit (international table) foot per hour square foot degree Fahrenheit" -J41,4863025,"BtuIT·in/(h·ft²·°F)","British thermal unit (international table) inch per hour square foot degree Fahrenheit" -J42,4863026,"BtuIT·in/(s·ft²·°F)","British thermal unit (international table) inch per second square foot degree Fahrenheit" -J46,4863030,"Btuth·ft/(h·ft²·°F)","British thermal unit (thermochemical) foot per hour square foot degree Fahrenheit" -J48,4863032,"Btuth·in/(h·ft²·°F)","British thermal unit (thermochemical) inch per hour square foot degree Fahrenheit" -J49,4863033,"Btuth·in/(s·ft²·°F)","British thermal unit (thermochemical) inch per second square foot degree Fahrenheit" -J78,4863800,"calth/(cm·s·°C)","calorie (thermochemical) per centimetre second degree Celsius" -K52,4928818,"kcal/(m·h·°C)","kilocalorie (international table) per hour metre degree Celsius" -D55,4470069,"W/(m²·K)","watt per square metre kelvin" -N78,5125944,"kW/(m²·K)","kilowatt per square metre kelvin" -D72,4470578,"calIT/(s·cm²·K)","calorie (international table) per second square centimetre kelvin" -D39,4469561,"calth/(s·cm²·K)","calorie (thermochemical) per second square centimetre kelvin" -A20,4272688,"BtuIT/(s·ft²·°R)","British thermal unit (international table) per second square foot degree Rankine" -A23,4272691,"BtuIT/(h·ft²·°R)","British thermal unit (international table) per hour square foot degree Rankine" -N74,5125940,"BtuIT/(h·ft²·ºF)","British thermal unit (international table) per hour square foot degree Fahrenheit" -N75,5125941,"Btuth/(h·ft²·ºF)","British thermal unit (thermochemical) per hour square foot degree Fahrenheit" -N76,5125942,"BtuIT/(s·ft²·ºF)","British thermal unit (international table) per second square foot degree Fahrenheit" -N77,5125943,"Btuth/(s·ft²·ºF)","British thermal unit (thermochemical) per second square foot degree Fahrenheit" -D19,4469049,"m²·K/W","square metre kelvin per watt" -J19,4862265,"°F·h·ft²/Btuth","degree Fahrenheit hour square foot per British thermal unit (thermochemical)" -J22,4862514,"°F·h·ft²/BtuIT","degree Fahrenheit hour square foot per British thermal unit (international table)" -J83,4864051,"clo","clo" -L14,4993332,"m²·h·°C/kcal","square metre hour degree Celsius per kilocalorie (international table)" -B21,4338225,"K/W","kelvin per watt" -H35,4731701,"K·m/W","kelvin metre per watt" -N84,5126196,"ºF/(BtuIT/h)","degree Fahrenheit hour per British thermal unit (international table)" -N85,5126197,"ºF/(Btuth/h)","degree Fahrenheit hour per British thermal unit (thermochemical)" -N86,5126198,"ºF/(BtuIT/s)","degree Fahrenheit second per British thermal unit (international table)" -N87,5126199,"ºF/(Btuth/s)","degree Fahrenheit second per British thermal unit (thermochemical)" -N88,5126200,"ºF·h·ft²/(BtuIT·in)","degree Fahrenheit hour square foot per British thermal unit (international table) inch" -N89,5126201,"ºF·h·ft²/(Btuth·in)","degree Fahrenheit hour square foot per British thermal unit (thermochemical) inch" -D52,4470066,"W/K","watt per kelvin" -E97,4536631,"mm/(°C·m)","millimetre per degree Celcius metre" -F53,4601139,"mm/K","millimetre per kelvin" -N83,5126195,"m/(°C·m)","metre per degree Celcius metre" -JE,19013,"J/K","joule per kelvin" -B41,4338737,"kJ/K","kilojoule per kelvin" -J43,4863027,"BtuIT/(lb·°F)","British thermal unit (international table) per pound degree Fahrenheit" -J50,4863280,"Btuth/(lb·°F)","British thermal unit (thermochemical) per pound degree Fahrenheit" -J76,4863798,"calIT/(g·°C)","calorie (international table) per gram degree Celsius" -J79,4863801,"calth/(g·°C)","calorie (thermochemical) per gram degree Celsius" -N60,5125680,"BtuIT/ºF","British thermal unit (international table) per degree Fahrenheit" -N61,5125681,"Btuth/ºF","British thermal unit (thermochemical) per degree Fahrenheit" -N62,5125682,"BtuIT/ºR","British thermal unit (international table) per degree Rankine" -N63,5125683,"Btuth/ºR","British thermal unit (thermochemical) per degree Rankine" -N64,5125684,"(Btuth/°R)/lb","British thermal unit (thermochemical) per pound degree Rankine" -N65,5125685,"(kcalIT/K)/g","kilocalorie (international table) per gram kelvin" -B11,4337969,"J/(kg·K)","joule per kilogram kelvin" -B43,4338739,"kJ/(kg·K)","kilojoule per kilogram kelvin" -A21,4272689,"Btu/IT(lb·°R)","British thermal unit (international table) per pound degree Rankine" -D76,4470582,"calIT/(g·K)","calorie (international table) per gram kelvin" -D37,4469559,"calth/(g·K)","calorie (thermochemical) per gram kelvin" -J2,18994,"J/kg","joule per kilogram" -D95,4471093,"J/g","joule per gram" -JK,19019,"MJ/kg","megajoule per kilogram" -B42,4338738,"kJ/kg","kilojoule per kilogram" -AZ,16730,"BtuIT/lb","British thermal unit (international table) per pound" -D75,4470581,"calIT/g","calorie (international table) per gram" -N73,5125939,"Btuth/lb","British thermal unit (thermochemical) per pound" -B36,4338486,"calth/g","calorie (thermochemical) per gram" -N58,5125432,"BtuIT/ft³","British thermal unit (international table) per cubic foot" -N59,5125433,"Btuth/ft³","British thermal unit (thermochemical) per cubic foot" -Q31,5321521,"kJ/g","kilojoule per gram" -AMP,4279632,"A","ampere" -B22,4338226,"kA","kiloampere" -H38,4731704,"MA","megaampere" -4K,13387,"mA","milliampere" -B84,4339764,"µA","microampere" -C39,4404025,"nA","nanoampere" -C70,4405040,"pA","picoampere" -N96,5126454,"Bi","biot" -N97,5126455,"Gi","gilbert" -COU,4411221,"C","coulomb" -A8,16696,"A·s","ampere second" -H32,4731698,"A²·s","ampere squared second" -AMH,4279624,"A·h","ampere hour" -TAH,5521736,"kA·h","kiloampere hour (thousand ampere hour)" -D77,4470583,"MC","megacoulomb" -D86,4470838,"mC","millicoulomb" -B26,4338230,"kC","kilocoulomb" -B86,4339766,"µC","microcoulomb" -C40,4404272,"nC","nanocoulomb" -C71,4405041,"pC","picocoulomb" -E09,4534329,"mA·h","milliampere hour" -N95,5126453,"A·min","ampere minute" -N94,5126452,"Fr","franklin" -A29,4272697,"C/m³","coulomb per cubic metre" -A84,4274228,"GC/m³","gigacoulomb per cubic metre" -A30,4272944,"C/mm³","coulomb per cubic millimetre" -B69,4339257,"MC/m³","megacoulomb per cubic metre" -A28,4272696,"C/cm³","coulomb per cubic centimetre" -B27,4338231,"kC/m³","kilocoulomb per cubic metre" -D88,4470840,"mC/m³","millicoulomb per cubic metre" -B87,4339767,"µC/m³","microcoulomb per cubic metre" -A34,4272948,"C/m²","coulomb per square metre" -B70,4339504,"MC/m²","megacoulomb per square metre" -A35,4272949,"C/mm²","coulomb per square millimetre" -A33,4272947,"C/cm²","coulomb per square centimetre" -B28,4338232,"kC/m²","kilocoulomb per square metre" -D89,4470841,"mC/m²","millicoulomb per square metre" -B88,4339768,"µC/m²","microcoulomb per square metre" -D50,4470064,"V/m","volt per metre" -H45,4731957,"V·s/m","volt second per metre" -D45,4469813,"V²/K²","volt squared per kelvin squared" -D51,4470065,"V/mm","volt per millimetre" -H24,4731444,"V/µs","volt per microsecond" -H62,4732466,"mV/min","millivolt per minute" -H46,4731958,"V/s","volt per second" -B79,4339513,"MV/m","megavolt per metre" -B55,4338997,"kV/m","kilovolt per metre" -D47,4469815,"V/cm","volt per centimetre" -C30,4404016,"mV/m","millivolt per metre" -C3,17203,"µV/m","microvolt per metre" -G60,4666928,"V/bar","volt per bar" -N98,5126456,"V/Pa","volt per pascal" -F87,4601911,"V/(l·min)","volt per litre minute" -H22,4731442,"V/(lbf/in²)","volt square inch per pound-force" -H23,4731443,"V/in","volt per inch" -VLT,5655636,"V","volt" -B78,4339512,"MV","megavolt" -KVT,4937300,"kV","kilovolt" -2Z,12890,"mV","millivolt" -D82,4470834,"µV","microvolt" -N99,5126457,"pV","picovolt" -FAR,4604242,"F","farad" -H48,4731960,"aF","attofarad" -C10,4403504,"mF","millifarad" -4O,13391,"µF","microfarad" -C41,4404273,"nF","nanofarad" -4T,13396,"pF","picofarad" -N90,5126448,"kF","kilofarad" -A69,4273721,"F/m","farad per metre" -H28,4731448,"µF/km","microfarad per kilometre" -H33,4731699,"F/km","farad per kilometre" -B89,4339769,"µF/m","microfarad per metre" -C42,4404274,"nF/m","nanofarad per metre" -C72,4405042,"pF/m","picofarad per metre" -A26,4272694,"C·m","coulomb metre" -A41,4273201,"A/m²","ampere per square metre" -H31,4731697,"A/kg","ampere per kilogram" -B66,4339254,"MA/m²","megaampere per square metre" -A7,16695,"A/mm²","ampere per square millimetre" -A4,16692,"A/cm²","ampere per square centimetre" -B23,4338227,"kA/m²","kiloampere per square metre" -G59,4666681,"mA/(l·min)","milliampere per litre minute" -N93,5126451,"A/Pa","ampere per pascal" -F57,4601143,"mA/(lbf/in²)","milliampere per pound-force per square inch" -F59,4601145,"mA/bar","milliampere per bar" -AE,16709,"A/m","ampere per metre" -B24,4338228,"kA/m","kiloampere per metre" -A3,16691,"A/mm","ampere per millimetre" -A2,16690,"A/cm","ampere per centimetre" -F76,4601654,"mA/mm","milliampere per millimetre" -F08,4599864,"mA/in","milliampere per inch" -P10,5255472,"C/m","coulomb per metre" -D33,4469555,"T","tesla" -C29,4403769,"mT","millitesla" -D81,4470833,"µT","microtesla" -C48,4404280,"nT","nanotesla" -P13,5255475,"kT","kilotesla" -P12,5255474,"γ","gamma" -WEB,5719362,"Wb","weber" -C33,4404019,"mWb","milliweber" -P11,5255473,"kWb","kiloweber" -D59,4470073,"Wb/m","weber per metre" -B56,4338998,"kWb/m","kiloweber per metre" -D60,4470320,"Wb/mm","weber per millimetre" -81,14385,"H","henry" -C14,4403508,"mH","millihenry" -B90,4340016,"µH","microhenry" -C43,4404275,"nH","nanohenry" -C73,4405043,"pH","picohenry" -H03,4730931,"H/kΩ","henry per kiloohm" -H04,4730932,"H/Ω","henry per ohm" -G98,4667704,"µH/kΩ","microhenry per kiloohm" -G99,4667705,"µH/Ω","microhenry per ohm" -H05,4730933,"mH/kΩ","millihenry per kiloohm" -H06,4730934,"mH/Ω","millihenry per ohm" -P24,5255732,"kH","kilohenry" -A98,4274488,"H/m","henry per metre" -B91,4340017,"µH/m","microhenry per metre" -C44,4404276,"nH/m","nanohenry per metre" -A5,16693,"A·m²","ampere square metre" -B8,16952,"J/m³","joule per cubic metre" -OHM,5195853,"Ω","ohm" -A87,4274231,"GΩ","gigaohm" -B75,4339509,"MΩ","megaohm" -H44,4731956,"TΩ","teraohm" -B49,4338745,"kΩ","kiloohm" -E45,4535349,"mΩ","milliohm" -B94,4340020,"µΩ","microohm" -P22,5255730,"nΩ","nanoohm" -M26,5059126,"GΩ/m","gigaohm per metre" -SIE,5458245,"S","siemens" -B53,4338995,"kS","kilosiemens" -C27,4403767,"mS","millisiemens" -B99,4340025,"µS","microsiemens" -G42,4666418,"µS/cm","microsiemens per centimetre" -G43,4666419,"µS/m","microsiemens per metre" -N92,5126450,"pS","picosiemens" -NQ,20049,"mho","mho" -NR,20050,"micromho","micromho" -C61,4404785,"Ω·m","ohm metre" -A88,4274232,"GΩ·m","gigaohm metre" -B76,4339510,"MΩ·m","megaohm metre" -H88,4732984,"MΩ·km","megaohm kilometre" -B50,4338992,"kΩ·m","kiloohm metre" -C60,4404784,"Ω·cm","ohm centimetre" -C23,4403763,"mΩ·m","milliohm metre" -B95,4340021,"µΩ·m","microohm metre" -C46,4404278,"nΩ·m","nanoohm metre" -M24,5059124,"Ω·km","ohm kilometre" -P23,5255731,"Ω·cmil/ft","ohm circular-mil per foot" -F56,4601142,"Ω/km","ohm per kilometre" -H26,4731446,"Ω/m","ohm per metre" -H37,4731703,"MΩ/m","megaohm per metre" -F54,4601140,"mΩ/m","milliohm per metre" -H36,4731702,"MΩ/km","megaohm per kilometre" -F55,4601141,"Ω/mi","ohm per mile (statute mile)" -D10,4469040,"S/m","siemens per metre" -H43,4731955,"S/cm","siemens per centimetre" -H61,4732465,"mS/cm","millisiemens per centimetre" -B77,4339511,"MS/m","megasiemens per metre" -B54,4338996,"kS/m","kilosiemens per metre" -G45,4666421,"nS/m","nanosiemens per metre" -G44,4666420,"nS/cm","nanosiemens per centimetre" -L42,4994098,"pS/m","picosiemens per metre" -C89,4405305,"H⁻¹","reciprocal henry" -P14,5255476,"J/s","joule per second" -D31,4469553,"TW","terawatt" -P15,5255477,"J/min","joule per minute" -P16,5255478,"J/h","joule per hour" -P17,5255479,"J/d","joule per day" -P18,5255480,"kJ/s","kilojoule per second" -P19,5255481,"kJ/min","kilojoule per minute" -P20,5255728,"kJ/h","kilojoule per hour" -P21,5255729,"kJ/d","kilojoule per day" -K43,4928563,"electric hp","horsepower (electric)" -C49,4404281,"nW","nanowatt" -C75,4405045,"pW","picowatt" -D46,4469814,"V·A","volt - ampere" -MVA,5068353,"MV·A","megavolt - ampere" -KVA,4937281,"kV·A","kilovolt - ampere" -M35,5059381,"mV·A","millivolt - ampere" -D44,4469812,"var","var" -K5,19253,"kvar","kilovolt ampere (reactive)" -KVR,4937298,"kvar","kilovar" -MAR,5062994,"kvar","megavar" -N91,5126449,"1/J","reciprocal joule" -M30,5059376,"1/(V·A·s)","reciprocal volt - ampere reciprocal second" -M17,5058871,"kHz·m","kilohertz metre" -M18,5058872,"GHz·m","gigahertz metre" -M27,5059127,"MHz·m","megahertz metre" -M21,5059121,"1/kVAh","reciprocal kilovolt - ampere reciprocal hour" -H34,4731700,"Hz·m","hertz metre" -H39,4731705,"MHz·km","megahertz kilometre" -C84,4405300,"rad/m","radian per metre" -JM,19021,"MJ/m³","megajoule per cubic metre" -B14,4337972,"J/m⁴","joule per metre to the fourth power" -B13,4337971,"J/m²","joule per square metre" -D1,17457,"s⁻¹/sr","reciprocal second per steradian" -D2,17458,"s⁻¹/(sr·m²)","reciprocal second per steradian metre squared" -C99,4405561,"s⁻¹/m²","reciprocal second per metre squared" -C93,4405555,"m⁻²","reciprocal square metre" -H47,4731959,"W/m³","watt per cubic metre" -H74,4732724,"W/m","watt per metre" -E43,4535347,"J/cm²","joule per square centimetre" -P37,5255991,"BtuIT/ft²","British thermal unit (international table) per square foot" -P38,5255992,"Btuth/ft²","British thermal unit (thermochemical) per square foot" -P39,5255993,"calth/cm²","calorie (thermochemical) per square centimetre" -P40,5256240,"Ly","langley" -D57,4470071,"W/sr","watt per steradian" -D58,4470072,"W/(sr·m²)","watt per steradian square metre" -D56,4470070,"W/(m²·K⁴)","watt per square metre kelvin to the fourth power" -D18,4469048,"m·K","metre kelvin" -CDL,4408396,"cd","candela" -P33,5255987,"kcd","kilocandela" -P34,5255988,"mcd","millicandela" -P35,5255989,"HK","Hefner-Kerze" -P36,5255990,"IK","international candle" -LUM,5002573,"lm","lumen" -B62,4339250,"lm·s","lumen second" -B59,4339001,"lm·h","lumen hour" -A24,4272692,"cd/m²","candela per square metre" -P28,5255736,"cd/in²","candela per square inch" -P29,5255737,"ftL","footlambert" -P30,5255984,"Lb","lambert" -P31,5255985,"sb","stilb" -P32,5255986,"cd/ft²","candela per square foot" -B60,4339248,"lm/m²","lumen per square metre" -LUX,5002584,"lx","lux" -KLX,4934744,"klx","kilolux" -P25,5255733,"lm/ft²","lumen per square foot" -P26,5255734,"ph","phot" -P27,5255735,"ftc","footcandle" -B64,4339252,"lx·s","lux second" -B63,4339251,"lx·h","lux hour" -B61,4339249,"lm/W","lumen per watt" -D22,4469298,"m²/mol","square metre per mole" -C59,4404537,"octave","octave" -D9,17465,"dyn/cm²","dyne per square centimetre" -A60,4273712,"erg/cm³","erg per cubic centimetre" -C32,4404018,"mW/m²","milliwatt per square metre" -D85,4470837,"µW/m²","microwatt per square metre" -C76,4405046,"pW/m²","picowatt per square metre" -A64,4273716,"erg/(s·cm²)","erg per second square centimetre" -C67,4404791,"Pa· s/m","pascal second per metre" -A50,4273456,"dyn·s/cm³","dyne second per cubic centimetre" -C66,4404790,"Pa·s/m³","pascal second per cubic metre" -A52,4273458,"dyn·s/cm⁵","dyne second per centimetre to the fifth power" -M32,5059378,"Pa·s/l","pascal second per litre" -C58,4404536,"N·s/m","newton second per metre" -A51,4273457,"dyn·s/cm","dyne second per centimetre" -P43,5256243,"B/m","bel per metre" -H51,4732209,"dB/km","decibel per kilometre" -H52,4732210,"dB/m","decibel per metre" -C69,4404793,"phon","phon" -D15,4469045,"sone","sone" -P42,5256242,"Pa²·s","pascal squared second" -P41,5256241,"dec","decade (logarithmic)" -C34,4404020,"mol","mole" -B45,4338741,"kmol","kilomole" -C18,4403512,"mmol","millimole" -FH,17992,"µmol","micromole" -Z9,23097,"nmol","nanomole" -P44,5256244,"lbmol","pound mole" -C95,4405557,"mol⁻¹","reciprocal mole" -D74,4470580,"kg/mol","kilogram per mole" -A94,4274484,"g/mol","gram per mole" -A40,4273200,"m³/mol","cubic metre per mole" -A37,4272951,"dm³/mol","cubic decimetre per mole" -A36,4272950,"cm³/mol","cubic centimetre per mole" -B58,4339000,"l/mol","litre per mole" -B15,4337973,"J/mol","joule per mole" -B44,4338740,"kJ/mol","kilojoule per mole" -B16,4337974,"J/(mol·K)","joule per mole kelvin" -C86,4405302,"m⁻³","reciprocal cubic metre" -H50,4732208,"cm⁻³","reciprocal cubic centimetre" -L20,4993584,"1/mm³","reciprocal cubic millimetre" -K20,4928048,"1/ft³","reciprocal cubic foot" -K49,4928569,"1/in³","reciprocal cubic inch" -K63,4929075,"1/l","reciprocal litre" -M10,5058864,"1/yd³","reciprocal cubic yard" -C36,4404022,"mol/m³","mole per cubic metre" -C38,4404024,"mol/l","mole per litre" -C35,4404021,"mol/dm³","mole per cubic decimetre" -B46,4338742,"kmol/m³","kilomole per cubic metre" -E95,4536629,"mol/s","mole per second" -M33,5059379,"mmol/l","millimole per litre" -P51,5256497,"(mol/kg)/Pa","mol per kilogram pascal" -P52,5256498,"(mol/m³)/Pa","mol per cubic metre pascal" -K59,4928825,"(kmol/m³)/K","kilomole per cubic metre kelvin" -K60,4929072,"(kmol/m³)/bar","kilomole per cubic metre bar" -K93,4929843,"1/psi","reciprocal psi" -L24,4993588,"(mol/kg)/K","mole per kilogram kelvin" -L25,4993589,"(mol/kg)/bar","mole per kilogram bar" -L26,4993590,"(mol/l)/K","mole per litre kelvin" -L27,4993591,"(mol/l)/bar","mole per litre bar" -L28,4993592,"(mol/m³)/K","mole per cubic metre kelvin" -L29,4993593,"(mol/m³)/bar","mole per cubic metre bar" -C19,4403513,"mol/kg","mole per kilogram" -D93,4471091,"s/m³","second per cubic metre" -D87,4470839,"mmol/kg","millimole per kilogram" -H68,4732472,"mmol/g","millimole per gram" -P47,5256247,"kmol/kg","kilomole per kilogram" -P48,5256248,"lbmol/lb","pound mole per pound" -KAT,4931924,"kat","katal" -E94,4536628,"kmol/s","kilomole per second" -P45,5256245,"lbmol/s","pound mole per second" -P46,5256246,"lbmol/h","pound mole per minute" -D43,4469811,"u","unified atomic mass unit" -A27,4272695,"C·m²/V","coulomb metre squared per volt" -A32,4272946,"C/mol","coulomb per mole" -D12,4469042,"S·m²/mol","siemens square metre per mole" -K58,4928824,"kmol/h","kilomole per hour" -K61,4929073,"kmol/min","kilomole per minute" -L23,4993587,"mol/h","mole per hour" -L30,4993840,"mol/min","mole per minute" -C82,4405298,"rad·m²/mol","radian square metre per mole" -C83,4405299,"rad·m²/kg","radian square metre per kilogram" -P49,5256249,"N·m²/A","newton square metre per ampere" -P50,5256496,"Wb·m","weber metre" -Q30,5321520,"pH","pH (potential of Hydrogen)" -B18,4337976,"J·s","joule second" -A10,4272432,"A·m²/(J·s)","ampere square metre per joule second" -CUR,4412754,"Ci","curie" -MCU,5063509,"mCi","millicurie" -M5,19765,"µCi","microcurie" -2R,12882,"kCi","kilocurie" -BQL,4346188,"Bq","becquerel" -GBQ,4670033,"GBq","gigabecquerel" -2Q,12881,"kBq","kilobecquerel" -4N,13390,"MBq","megabecquerel" -H08,4730936,"µBq","microbecquerel" -A42,4273202,"Ci/kg","curie per kilogram" -A18,4272440,"Bq/kg","becquerel per kilogram" -B67,4339255,"MBq/kg","megabecquerel per kilogram" -B25,4338229,"kBq/kg","kilobecquerel per kilogram" -A19,4272441,"Bq/m³","becquerel per cubic metre" -A14,4272436,"b","barn" -D24,4469300,"m²/sr","square metre per steradian" -A17,4272439,"b/sr","barn per steradian" -D20,4469296,"m²/J","square metre per joule" -A15,4272437,"b/eV","barn per electronvolt" -D16,4469046,"cm²/erg","square centimetre per erg" -D25,4469301,"m²/(sr·J)","square metre per steradian joule" -A16,4272438,"b/(sr·eV)","barn per steradian electronvolt" -D17,4469047,"cm²/(sr·erg)","square centimetre per steradian erg" -B81,4339761,"m⁻²/s","reciprocal metre squared reciprocal second" -A65,4273717,"erg/(cm²·s)","erg per square centimetre second" -D21,4469297,"m²/kg","square metre per kilogram" -B12,4337970,"J/m","joule per metre" -A54,4273460,"eV/m","electronvolt per metre" -A58,4273464,"erg/cm","erg per centimetre" -D73,4470579,"J·m²","joule square metre" -A55,4273461,"eV·m²","electronvolt square metre" -A66,4273718,"erg·cm²","erg square centimetre" -B20,4338224,"J·m²/kg","joule square metre per kilogram" -A56,4273462,"eV·m²/kg","electronvolt square metre per kilogram" -A67,4273719,"erg·cm²/g","erg square centimetre per gram" -D26,4469302,"m²/(V·s)","square metre per volt second" -H58,4732216,"m/(V·s)","metre per volt second" -C87,4405303,"m⁻³/s","reciprocal cubic metre per second" -A95,4274485,"Gy","gray" -C13,4403507,"mGy","milligray" -C80,4405296,"rad","rad" -A61,4273713,"erg/g","erg per gram" -D13,4469043,"Sv","sievert" -C28,4403768,"mSv","millisievert" -D91,4471089,"rem","rem" -L31,4993841,"mrem","milliroentgen aequivalent men" -A96,4274486,"Gy/s","gray per second" -A62,4273714,"erg/g·s","erg per gram second" -CKG,4410183,"C/kg","coulomb per kilogram" -C8,17208,"mC/kg","millicoulomb per kilogram" -2C,12867,"R","roentgen" -2Y,12889,"mR","milliroentgen" -J53,4863283,"C·m²/kg","coulomb square metre per kilogram" -KR,19282,"kR","kiloroentgen" -A31,4272945,"C/(kg·s)","coulomb per kilogram second" -D6,17462,"R/s","roentgen per second" -P54,5256500,"mGy/s","milligray per second" -P55,5256501,"µGy/s","microgray per second" -P56,5256502,"nGy/s","nanogray per second" -P57,5256503,"Gy/min","gray per minute" -P58,5256504,"mGy/min","milligray per minute" -P59,5256505,"µGy/min","microgray per minute" -P60,5256752,"nGy/min","nanogray per minute" -P61,5256753,"Gy/h","gray per hour" -P62,5256754,"mGy/h","milligray per hour" -P63,5256755,"µGy/h","microgray per hour" -P64,5256756,"nGy/h","nanogray per hour" -P65,5256757,"Sv/s","sievert per second" -P66,5256758,"mSv/s","millisievert per second" -P67,5256759,"µSv/s","microsievert per second" -P68,5256760,"nSv/s","nanosievert per second" -P69,5256761,"rem/s","rem per second" -P70,5257008,"Sv/h","sievert per hour" -P71,5257009,"mSv/h","millisievert per hour" -P72,5257010,"µSv/h","microsievert per hour" -P73,5257011,"nSv/h","nanosievert per hour" -P74,5257012,"Sv/min","sievert per minute" -P75,5257013,"mSv/min","millisievert per minute" -P76,5257014,"µSv/min","microsievert per minute" -P77,5257015,"nSv/min","nanosievert per minute" -P78,5257016,"1/in²","reciprocal square inch" -P53,5256499,"unit pole","unit pole" -C85,4405301,"Å⁻¹","reciprocal angstrom" -D94,4471092,"s/(rad·m³)","second per cubic metre radian" -C90,4405552,"J⁻¹/m³","reciprocal joule per cubic metre" -C88,4405304,"eV⁻¹/m³","reciprocal electron volt per cubic metre" -A38,4272952,"m³/C","cubic metre per coulomb" -D48,4469816,"V/K","volt per kelvin" -D49,4469817,"mV/K","millivolt per kelvin" -A6,16694,"A/(m²·K²)","ampere per square metre kelvin squared" -33,13107,"kPa·m²/g","kilopascal square metre per gram" -P79,5257017,"Pa/(kg/m²)","pascal square metre per kilogram" -34,13108,"kPa/mm","kilopascal per millimetre" -H42,4731954,"Pa/m","pascal per metre" -H69,4732473,"pPa/km","picopascal per kilometre" -P80,5257264,"mPa/m","millipascal per metre" -P81,5257265,"kPa/m","kilopascal per metre" -P82,5257266,"hPa/m","hectopascal per metre" -P83,5257267,"Atm/m","standard atmosphere per metre" -P84,5257268,"at/m","technical atmosphere per metre" -P85,5257269,"Torr/m","torr per metre" -P86,5257270,"psi/in","psi per inch" -35,13109,"ml/(cm²·s)","millilitre per square centimetre second" -P87,5257271,"(m³/s)/m²","cubic metre per second square metre" -OPM,5197901,"o/min","oscillations per minute" -KNM,4935245,"KN/m2","kilonewton per square metre" -Q35,5321525,"MW/min","megawatts per minute" -10,12592,"group","group" -11,12593,"outfit","outfit" -13,12595,"ration","ration" -14,12596,"shot","shot" -15,12597,"stick, military","stick, military" -20,12848,"twenty foot container","twenty foot container" -21,12849,"forty foot container","forty foot container" -24,12852,"theoretical pound","theoretical pound" -27,12855,"theoretical ton","theoretical ton" -38,13112,"oz/(ft²/cin)","ounce per square foot per 0,01inch" -56,13622,"sitas","sitas" -57,13623,"mesh","mesh" -58,13624,"net kilogram","net kilogram" -59,13625,"ppm","part per million" -60,13872,"percent weight","percent weight" -61,13873,"ppb","part per billion (US)" -64,13876,"pound per square inch, gauge","pound per square inch, gauge" -66,13878,"Oe","oersted" -76,14134,"Gs","gauss" -78,14136,"kGs","kilogauss" -1I,12617,"fixed rate","fixed rate" -2G,12871,"V","volt AC" -2H,12872,"V","volt DC" -2P,12880,"kbyte","kilobyte" -3C,13123,"manmonth","manmonth" -4L,13388,"Mbyte","megabyte" -5B,13634,"batch","batch" -5E,13637,"MMSCF/day","MMSCF/day" -5J,13642,"hydraulic horse power","hydraulic horse power" -A43,4273203,"dwt","deadweight tonnage" -A47,4273207,"dtex (g/10km)","decitex" -A49,4273209,"den (g/9 km)","denier (g/9 km)" -A59,4273465,"8-part cloud cover","8-part cloud cover" -A75,4273973,"freight ton","freight ton" -A77,4273975,"Gaussian CGS (Centimetre-Gram-Second system) unit of displacement","Gaussian CGS (Centimetre-Gram-Second system) unit of displacement" -A78,4273976,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric current","Gaussian CGS (Centimetre-Gram-Second system) unit of electric current" -A79,4273977,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric charge","Gaussian CGS (Centimetre-Gram-Second system) unit of electric charge" -A80,4274224,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric field strength","Gaussian CGS (Centimetre-Gram-Second system) unit of electric field strength" -A81,4274225,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric polarization","Gaussian CGS (Centimetre-Gram-Second system) unit of electric polarization" -A82,4274226,"Gaussian CGS (Centimetre-Gram-Second system) unit of electric potential","Gaussian CGS (Centimetre-Gram-Second system) unit of electric potential" -A83,4274227,"Gaussian CGS (Centimetre-Gram-Second system) unit of magnetization","Gaussian CGS (Centimetre-Gram-Second system) unit of magnetization" -A9,16697,"rate","rate" -A99,4274489,"bit","bit" -AA,16705,"ball","ball" -AB,16706,"pk","bulk pack" -ACT,4277076,"activity","activity" -AD,16708,"byte","byte" -AH,16712,"additional minute","additional minute" -AI,16713,"average minute per call","average minute per call" -AL,16716,"access line","access line" -AQ,16721,"anti-hemophilic factor (AHF) unit","anti-hemophilic factor (AHF) unit" -AS,16723,"assortment","assortment" -ASM,4281165,"alcoholic strength by mass","alcoholic strength by mass" -ASU,4281173,"alcoholic strength by volume","alcoholic strength by volume" -AY,16729,"assembly","assembly" -B1,16945,"barrel (US)/d","barrel (US) per day" -B10,4337968,"bit/s","bit per second" -B17,4337975,"credit","credit" -B19,4337977,"digit","digit" -B3,16947,"batting pound","batting pound" -B30,4338480,"Gibit","gibibit" -B4,16948,"barrel, imperial","barrel, imperial" -B65,4339253,"Mx","maxwell" -B68,4339256,"Gbit","gigabit" -B7,16951,"cycle","cycle" -B80,4339760,"Gbit/s","gigabit per second" -B82,4339762,"inch per linear foot","inch per linear foot" -BB,16962,"base box","base box" -BFT,4343380,"fbm","board foot" -BIL,4344140,"billion (EUR)","billion (EUR)" -BP,16976,"hundred board foot","hundred board foot" -BPM,4345933,"BPM","beats per minute" -C0,17200,"call","call" -C21,4403761,"Kibit","kibibit" -C37,4404023,"kbit","kilobit" -C74,4405044,"kbit/s","kilobit per second" -C79,4405049,"kVAh","kilovolt ampere hour" -C9,17209,"coil group","coil group" -CCT,4408148,"carrying capacity in metric ton","carrying capacity in metric ton" -CEN,4408654,"hundred","hundred" -CG,17223,"card","card" -CLF,4410438,"hundred leave","hundred leave" -CNP,4410960,"hundred pack","hundred pack" -CNT,4410964,"cental (UK)","cental (UK)" -CTG,4412487,"content gram","content gram" -CTM,4412493,"metric carat","metric carat" -CTN,4412494,"content ton (metric)","content ton (metric)" -D03,4468787,"kW·h/h","kilowatt hour per hour" -D04,4468788,"lot [unit of weight]","lot [unit of weight]" -D11,4469041,"Mibit","mebibit" -D23,4469299,"pen gram (protein)","pen gram (protein)" -D34,4469556,"tex (g/km)","tex" -D36,4469558,"Mbit","megabit" -D63,4470323,"book","book" -D65,4470325,"round","round" -D68,4470328,"number of words","number of words" -D78,4470584,"MJ/s","megajoule per second" -DAD,4473156,"ten day","ten day" -DB,17474,"dry pound","dry pound" -DEC,4474179,"decade","decade" -DMO,4476239,"standard kilolitre","standard kilolitre" -DPC,4476995,"dozen piece","dozen piece" -DPR,4477010,"dozen pair","dozen pair" -DPT,4477012,"displacement tonnage","displacement tonnage" -DRA,4477505,"dram (US)","dram (US)" -DRI,4477513,"dram (UK)","dram (UK)" -DRL,4477516,"dozen roll","dozen roll" -DT,17492,"dry ton","dry ton" -DWT,4478804,"pennyweight","pennyweight" -DZN,4479566,"DOZ","dozen" -DZP,4479568,"dozen pack","dozen pack" -E07,4534327,"MW·h/h","megawatt hour per hour" -E08,4534328,"MW/Hz","megawatt per hertz" -E10,4534576,"deg da","degree day" -E11,4534577,"gigacalorie","gigacalorie" -E12,4534578,"mille","mille" -E16,4534582,"BtuIT/h","million Btu(IT) per hour" -E17,4534583,"ft³/s","cubic foot per second" -E19,4534585,"ping","ping" -E20,4534832,"Mbit/s","megabit per second" -E21,4534833,"shares","shares" -E22,4534834,"TEU","TEU" -E23,4534835,"tyre","tyre" -E25,4534837,"active unit","active unit" -E27,4534839,"dose","dose" -E28,4534840,"air dry ton","air dry ton" -E30,4535088,"strand","strand" -E31,4535089,"m²/l","square metre per litre" -E32,4535090,"l/h","litre per hour" -E33,4535091,"foot per thousand","foot per thousand" -E34,4535092,"Gbyte","gigabyte" -E35,4535093,"Tbyte","terabyte" -E36,4535094,"Pbyte","petabyte" -E37,4535095,"pixel","pixel" -E38,4535096,"megapixel","megapixel" -E39,4535097,"dpi","dots per inch" -E4,17716,"gross kilogram","gross kilogram" -E40,4535344,"ppht","part per hundred thousand" -E44,4535348,"kgf·m/cm²","kilogram-force metre per square centimetre" -E46,4535350,"kW·h/m³","kilowatt hour per cubic metre" -E47,4535351,"kW·h/K","kilowatt hour per kelvin" -E48,4535352,"service unit","service unit" -E49,4535353,"working day","working day" -E50,4535600,"accounting unit","accounting unit" -E51,4535601,"job","job" -E52,4535602,"run foot","run foot" -E53,4535603,"test","test" -E54,4535604,"trip","trip" -E55,4535605,"use","use" -E56,4535606,"well","well" -E57,4535607,"zone","zone" -E58,4535608,"Ebit/s","exabit per second" -E59,4535609,"Eibyte","exbibyte" -E60,4535856,"Pibyte","pebibyte" -E61,4535857,"Tibyte","tebibyte" -E62,4535858,"Gibyte","gibibyte" -E63,4535859,"Mibyte","mebibyte" -E64,4535860,"Kibyte","kibibyte" -E65,4535861,"Eibit/m","exbibit per metre" -E66,4535862,"Eibit/m²","exbibit per square metre" -E67,4535863,"Eibit/m³","exbibit per cubic metre" -E68,4535864,"Gbyte/s","gigabyte per second" -E69,4535865,"Gibit/m","gibibit per metre" -E70,4536112,"Gibit/m²","gibibit per square metre" -E71,4536113,"Gibit/m³","gibibit per cubic metre" -E72,4536114,"Kibit/m","kibibit per metre" -E73,4536115,"Kibit/m²","kibibit per square metre" -E74,4536116,"Kibit/m³","kibibit per cubic metre" -E75,4536117,"Mibit/m","mebibit per metre" -E76,4536118,"Mibit/m²","mebibit per square metre" -E77,4536119,"Mibit/m³","mebibit per cubic metre" -E78,4536120,"Pbit","petabit" -E79,4536121,"Pbit/s","petabit per second" -E80,4536368,"Pibit/m","pebibit per metre" -E81,4536369,"Pibit/m²","pebibit per square metre" -E82,4536370,"Pibit/m³","pebibit per cubic metre" -E83,4536371,"Tbit","terabit" -E84,4536372,"Tbit/s","terabit per second" -E85,4536373,"Tibit/m","tebibit per metre" -E86,4536374,"Tibit/m³","tebibit per cubic metre" -E87,4536375,"Tibit/m²","tebibit per square metre" -E88,4536376,"bit/m","bit per metre" -E89,4536377,"bit/m²","bit per square metre" -E90,4536624,"cm⁻¹","reciprocal centimetre" -E91,4536625,"d⁻¹","reciprocal day" -EA,17729,"each","each" -EB,17730,"electronic mail box","electronic mail box" -EQ,17745,"equivalent gallon","equivalent gallon" -F01,4599857,"bit/m³","bit per cubic metre" -FBM,4604493,"fibre metre","fibre metre" -FC,17987,"kft³","thousand cubic foot" -FF,17990,"hundred cubic metre","hundred cubic metre" -FIT,4606292,"FIT","failures in time" -FL,17996,"flake ton","flake ton" -GB,18242,"gal (US)/d","gallon (US) per day" -GDW,4670551,"gram, dry weight","gram, dry weight" -GFI,4671049,"gi F/S","gram of fissile isotope" -GGR,4671314,"great gross","great gross" -GIA,4671809,"gi (US)","gill (US)" -GIC,4671811,"gram, including container","gram, including container" -GII,4671817,"gi (UK)","gill (UK)" -GIP,4671824,"gram, including inner packaging","gram, including inner packaging" -GRO,4674127,"gr","gross" -GRT,4674132,"gross register ton","gross register ton" -GT,18260,"gross ton","gross ton" -H21,4731441,"blank","blank" -H25,4731445,"%/K","percent per kelvin" -H71,4732721,"%/mo","percent per month" -H72,4732722,"%/hbar","percent per hectobar" -H73,4732723,"%/daK","percent per decakelvin" -H77,4732727,"MW","module width" -H80,4732976,"U or RU","rack unit" -H82,4732978,"bp","big point" -H87,4732983,"piece","piece" -H89,4732985,"%/Ω","percent per ohm" -H90,4733232,"%/°","percent per degree" -H91,4733233,"%/10000","percent per ten thousand" -H92,4733234,"%/100000","percent per one hundred thousand" -H93,4733235,"%/100","percent per hundred" -H94,4733236,"%/1000","percent per thousand" -H95,4733237,"%/V","percent per volt" -H96,4733238,"%/bar","percent per bar" -H98,4733240,"%/in","percent per inch" -H99,4733241,"%/m","percent per metre" -HA,18497,"hank","hank" -HBX,4735576,"hundred boxes","hundred boxes" -HC,18499,"hundred count","hundred count" -HDW,4736087,"hundred kilogram, dry weight","hundred kilogram, dry weight" -HEA,4736321,"head","head" -HH,18504,"hundred cubic foot","hundred cubic foot" -HIU,4737365,"hundred international unit","hundred international unit" -HKM,4737869,"hundred kilogram, net mass","hundred kilogram, net mass" -HMQ,4738385,"Mm³","million cubic metre" -HPA,4739137,"hectolitre of pure alcohol","hectolitre of pure alcohol" -IE,18757,"person","person" -ISD,4805444,"international sugar degree","international sugar degree" -IUG,4805959,"international unit per gram","international unit per gram" -J10,4862256,"%/mm","percent per millimetre" -J12,4862258,"‰/psi","per mille per psi" -J13,4862259,"°API","degree API" -J14,4862260,"°Bé","degree Baume (origin scale)" -J15,4862261,"°Bé (US heavy)","degree Baume (US heavy)" -J16,4862262,"°Bé (US light)","degree Baume (US light)" -J17,4862263,"°Balling","degree Balling" -J18,4862264,"°Bx","degree Brix" -J27,4862519,"°Oechsle","degree Oechsle" -J31,4862769,"°Tw","degree Twaddell" -J38,4862776,"Bd","baud" -J54,4863284,"MBd","megabaud" -JNT,4869716,"pipeline joint","pipeline joint" -JPS,4870227,"hundred metre","hundred metre" -JWL,4872012,"number of jewels","number of jewels" -K1,19249,"kilowatt demand","kilowatt demand" -K2,19250,"kilovolt ampere reactive demand","kilovolt ampere reactive demand" -K3,19251,"kvar·h","kilovolt ampere reactive hour" -K50,4928816,"kBd","kilobaud" -KA,19265,"cake","cake" -KB,19266,"kilocharacter","kilocharacter" -KCC,4932419,"kg C₅ H₁₄ClNO","kilogram of choline chloride" -KDW,4932695,"kg/net eda","kilogram drained net weight" -KHY,4933721,"kg H₂O₂","kilogram of hydrogen peroxide" -KI,19273,"kilogram per millimetre width","kilogram per millimetre width" -KIC,4933955,"kilogram, including container","kilogram, including container" -KIP,4933968,"kilogram, including inner packaging","kilogram, including inner packaging" -KJ,19274,"kilosegment","kilosegment" -KLK,4934731,"lactic dry material percentage","lactic dry material percentage" -KMA,4934977,"kg met.am.","kilogram of methylamine" -KNI,4935241,"kg N","kilogram of nitrogen" -KNS,4935251,"kilogram named substance","kilogram named substance" -KO,19279,"milliequivalence caustic potash per gram of product","milliequivalence caustic potash per gram of product" -KPH,4935752,"kg KOH","kilogram of potassium hydroxide (caustic potash)" -KPO,4935759,"kg K₂O","kilogram of potassium oxide" -KPP,4935760,"kilogram of phosphorus pentoxide (phosphoric anhydride)","kilogram of phosphorus pentoxide (phosphoric anhydride)" -KSD,4936516,"kg 90 % sdt","kilogram of substance 90 % dry" -KSH,4936520,"kg NaOH","kilogram of sodium hydroxide (caustic soda)" -KT,19284,"kit","kit" -KUR,4937042,"kg U","kilogram of uranium" -KWY,4937561,"kW/year","kilowatt year" -KWO,4937551,"kg WO₃","kilogram of tungsten trioxide" -LAC,4997443,"lactose excess percentage","lactose excess percentage" -LBT,4997716,"troy pound (US)","troy pound (US)" -LEF,4998470,"leaf","leaf" -LF,19526,"linear foot","linear foot" -LH,19528,"labour hour","labour hour" -LK,19531,"link","link" -LM,19533,"linear metre","linear metre" -LN,19534,"length","length" -LO,19535,"lot [unit of procurement]","lot [unit of procurement]" -LP,19536,"liquid pound","liquid pound" -LPA,5001281,"litre of pure alcohol","litre of pure alcohol" -LR,19538,"layer","layer" -LS,19539,"lump sum","lump sum" -LUB,5002562,"metric ton, lubricating oil","metric ton, lubricating oil" -LY,19545,"linear yard","linear yard" -M19,5058873,"Bft","Beaufort" -M25,5059125,"%/°C","percent per degree Celsius" -M36,5059382,"mo (30 days)","30-day month" -M37,5059383,"y (360 days)","actual/360" -M4,19764,"monetary value","monetary value" -M9,19769,"MBTU/kft³","million Btu per 1000 cubic foot" -MAH,5062984,"Mvar·h","megavolt ampere reactive hour" -MBE,5063237,"thousand standard brick equivalent","thousand standard brick equivalent" -MBF,5063238,"thousand board foot","thousand board foot" -MD,19780,"air dry metric ton","air dry metric ton" -MIL,5065036,"thousand","thousand" -MIO,5065039,"million","million" -MIU,5065045,"million international unit","million international unit" -MLD,5065796,"milliard","milliard" -MND,5066308,"kilogram, dry weight","kilogram, dry weight" -N1,20017,"pen calorie","pen calorie" -N3,20019,"print point","print point" -NAR,5128530,"number of articles","number of articles" -NCL,5129036,"number of cells","number of cells" -NF,20038,"message","message" -NIL,5130572,"()","nil" -NIU,5130581,"number of international units","number of international units" -NL,20044,"load","load" -NMP,5131600,"number of packs","number of packs" -NPR,5132370,"number of pairs","number of pairs" -NPT,5132372,"number of parts","number of parts" -NT,20052,"net ton","net ton" -NTT,5133396,"net register ton","net register ton" -NX,20056,"‰","part per thousand" -OA,20289,"panel","panel" -ODE,5194821,"ozone depletion equivalent","ozone depletion equivalent" -ODG,5194823,"ODS Grams","ODS Grams" -ODK,5194827,"ODS Kilograms","ODS Kilograms" -ODM,5194829,"ODS Milligrams","ODS Milligrams" -OT,20308,"overtime hour","overtime hour" -OZ,20314,"ounce av","ounce av" -P1,20529,"%","percent" -P5,20533,"five pack","five pack" -P88,5257272,"rhe","rhe" -P89,5257273,"lbf·ft/in","pound-force foot per inch" -P90,5257520,"lbf·in/in","pound-force inch per inch" -P91,5257521,"perm (0 ºC)","perm (0 ºC)" -P92,5257522,"perm (23 ºC)","perm (23 ºC)" -P93,5257523,"byte/s","byte per second" -P94,5257524,"kbyte/s","kilobyte per second" -P95,5257525,"Mbyte/s","megabyte per second" -P96,5257526,"1/V","reciprocal volt" -P97,5257527,"1/rad","reciprocal radian" -P98,5257528,"PaΣνB","pascal to the power sum of stoichiometric numbers" -P99,5257529,"(mol/m³)∑νB","mole per cubiv metre to the power sum of stoichiometric numbers" -PD,20548,"pad","pad" -PFL,5260876,"proof litre","proof litre" -PGL,5261132,"proof gallon","proof gallon" -PI,20553,"pitch","pitch" -PLA,5262401,"°P","degree Plato" -PQ,20561,"ppi","page per inch" -PR,20562,"pair","pair" -PTN,5264462,"PTN","portion" -Q10,5321008,"J/T","joule per tesla" -Q11,5321009,"E","erlang" -Q12,5321010,"o","octet" -Q13,5321011,"o/s","octet per second" -Q14,5321012,"Sh","shannon" -Q15,5321013,"Hart","hartley" -Q16,5321014,"nat","natural unit of information" -Q17,5321015,"Sh/s","shannon per second" -Q18,5321016,"Hart/s","hartley per second" -Q19,5321017,"nat/s","natural unit of information per second" -Q20,5321264,"s/kg","second per kilogramm" -Q21,5321265,"W·m²","watt square metre" -Q22,5321266,"1/(Hz·rad·m³)","second per radian cubic metre" -Q23,5321267,"1/Wb","weber to the power minus one" -Q24,5321268,"1/in","reciprocal inch" -Q25,5321269,"dpt","dioptre" -Q26,5321270,"1/1","one per one" -Q27,5321271,"N·m/m²","newton metre per metre" -Q28,5321272,"kg/(m²·Pa·s)","kilogram per square metre pascal second" -Q36,5321526,"m2/m3","square metre per cubic metre" -Q3,20787,"meal","meal" -QA,20801,"page - facsimile","page - facsimile" -QAN,5325134,"quarter (of a year)","quarter (of a year)" -QB,20802,"page - hardcopy","page - hardcopy" -QR,20818,"qr","quire" -QTR,5330002,"Qr (UK)","quarter (UK)" -R1,21041,"pica","pica" -R9,21049,"thousand cubic metre","thousand cubic metre" -RH,21064,"running or operating hour","running or operating hour" -RM,21069,"ream","ream" -ROM,5394253,"room","room" -RP,21072,"pound per ream","pound per ream" -RT,21076,"revenue ton mile","revenue ton mile" -SAN,5456206,"half year (6 months)","half year (6 months)" -SCO,5456719,"score","score" -SCR,5456722,"scruple","scruple" -SET,5457236,"set","set" -SG,21319,"segment","segment" -SHT,5458004,"shipping ton","shipping ton" -SQ,21329,"square","square" -SQR,5460306,"square, roofing","square, roofing" -SR,21330,"strip","strip" -STC,5461059,"stick","stick" -STK,5461067,"stick, cigarette","stick, cigarette" -STL,5461068,"standard litre","standard litre" -STW,5461079,"straw","straw" -SW,21335,"skein","skein" -SX,21336,"shipment","shipment" -SYR,5462354,"syringe","syringe" -T0,21552,"telecommunication line in service","telecommunication line in service" -T3,21555,"thousand piece","thousand piece" -TAN,5521742,"TAN","total acid number" -TI,21577,"thousand square inch","thousand square inch" -TIC,5523779,"metric ton, including container","metric ton, including container" -TIP,5523792,"metric ton, including inner packaging","metric ton, including inner packaging" -TKM,5524301,"t·km","tonne kilometre" -TMS,5524819,"kilogram of imported meat, less offal","kilogram of imported meat, less offal" -TP,21584,"ten pack","ten pack" -TPI,5525577,"TPI","teeth per inch" -TPR,5525586,"ten pair","ten pair" -TQD,5525828,"km³/d","thousand cubic metre per day" -TRL,5526092,"trillion (EUR)","trillion (EUR)" -TST,5526356,"ten set","ten set" -TTS,5526611,"ten thousand sticks","ten thousand sticks" -U1,21809,"treatment","treatment" -U2,21810,"tablet","tablet" -UB,21826,"telecommunication line in service average","telecommunication line in service average" -UC,21827,"telecommunication port","telecommunication port" -VA,22081,"V·A / kg","volt - ampere per kilogram" -VP,22096,"percent volume","percent volume" -W2,22322,"wet kilo","wet kilo" -WA,22337,"W/kg","watt per kilogram" -WB,22338,"wet pound","wet pound" -WCD,5718852,"cord","cord" -WE,22341,"wet ton","wet ton" -WG,22343,"wine gallon","wine gallon" -WM,22349,"working month","working month" -WSD,5722948,"std","standard" -WW,22359,"millilitre of water","millilitre of water" -Z11,5910833,"hanging container","hanging container" -ZP,23120,"page","page" -ZZ,23130,"mutually defined","mutually defined" -MRW,5067351,"m·wk","Metre Week" -MKW,5065559,"m²· wk","Square Metre Week" -MQW,5067095,"m³·wk","Cubic Metre Week" -HWE,4740933,"piece·k","Piece Week" -MRD,5067332,"m·day","Metre Day" -MKD,5065540,"m²·d","Square Metre Day" -MQD,5067076,"m³·d","Cubic Metre Day" -HAD,4735300,"piece·d","Piece Day" -MRM,5067341,"m·mo","Metre Month" -MKM,5065549,"m²·mo","Square Metre Month" -MQM,5067085,"m³·mo","Cubic Metre Month" -HMO,4738383,"piece·mo","Piece Month" -DBW,4473431,"dBW","Decibel watt" -DBM,4473421,"dBm","Decibel-milliwatts" -FNU,4607573,"FNU","Formazin nephelometric unit" -NTU,5133397,"NTU","Nephelometric turbidity unit" diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelExportOpc.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelExportOpc.cs deleted file mode 100644 index 8da32895..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelExportOpc.cs +++ /dev/null @@ -1,1086 +0,0 @@ -using Opc.Ua; -using ua = Opc.Ua; -using uaExport = Opc.Ua.Export; - -using System; -using System.Collections.Generic; -using System.Linq; - -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Opc.Ua.Export; -using CESMII.OpcUa.NodeSetModel.Factory.Opc; -using System.Xml; -using System.Globalization; -using Newtonsoft.Json; - -namespace CESMII.OpcUa.NodeSetModel.Export.Opc -{ - - public class NodeModelExportOpc : NodeModelExportOpc - { - - } - public class NodeModelExportOpc where T : NodeModel, new() - { - protected T _model; - - public static (UANode ExportedNode, List AdditionalNodes, bool Created) GetUANode(NodeModel model, ExportContext context) - { - if (model is InterfaceModel uaInterface) - { - return new InterfaceModelExportOpc { _model = uaInterface }.GetUANode(context); - } - else if (model is ObjectTypeModel objectType) - { - return new ObjectTypeModelExportOpc { _model = objectType, }.GetUANode(context); - } - else if (model is VariableTypeModel variableType) - { - return new VariableTypeModelExportOpc { _model = variableType, }.GetUANode(context); - } - else if (model is DataTypeModel dataType) - { - return new DataTypeModelExportOpc { _model = dataType, }.GetUANode(context); - } - else if (model is DataVariableModel dataVariable) - { - return new DataVariableModelExportOpc { _model = dataVariable, }.GetUANode(context); - } - else if (model is PropertyModel property) - { - return new PropertyModelExportOpc { _model = property, }.GetUANode(context); - } - else if (model is ObjectModel uaObject) - { - return new ObjectModelExportOpc { _model = uaObject, }.GetUANode(context); - } - else if (model is MethodModel uaMethod) - { - return new MethodModelExportOpc { _model = uaMethod, }.GetUANode(context); - } - else if (model is ReferenceTypeModel referenceType) - { - return new ReferenceTypeModelExportOpc { _model = referenceType, }.GetUANode(context); - } - throw new Exception($"Unexpected node model {model.GetType()}"); - } - - public virtual (TUANode ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) where TUANode : UANode, new() - { - var nodeIdForExport = GetNodeIdForExport(_model.NodeId, context); - if (context._exportedSoFar.TryGetValue(nodeIdForExport, out var existingNode)) - { - return ((TUANode)existingNode, null, false); - } - var node = new TUANode - { - Description = _model.Description?.ToExport()?.ToArray(), - BrowseName = GetBrowseNameForExport(context.NamespaceUris), - SymbolicName = _model.SymbolicName, - DisplayName = _model.DisplayName?.ToExport()?.ToArray(), - NodeId = nodeIdForExport, - Documentation = _model.Documentation, - Category = _model.Categories?.ToArray(), - }; - context._exportedSoFar.Add(nodeIdForExport, node); - if (!string.IsNullOrEmpty(_model.ReleaseStatus)) - { - if (Enum.TryParse(_model.ReleaseStatus, out var releaseStatus)) - { - node.ReleaseStatus = releaseStatus; - } - else - { - throw new Exception($"Invalid release status '{_model.ReleaseStatus}' on {_model}"); - } - } - - var references = new List(); - foreach (var property in _model.Properties) - { - if (_model is DataTypeModel && - (property.BrowseName.EndsWith(BrowseNames.EnumValues) - || property.BrowseName.EndsWith(BrowseNames.EnumStrings) - || property.BrowseName.EndsWith(BrowseNames.OptionSetValues))) - { - // Property will get generated during data type export - continue; - } - context.NamespaceUris.GetIndexOrAppend(property.Namespace); - var referenceTypeId = context.GetModelNodeId(ReferenceTypeIds.HasProperty); - if (GetOtherReferenceWithDerivedReferenceType(property, referenceTypeId) == null) - { - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasProperty, context), - Value = GetNodeIdForExport(property.NodeId, context), - }); - } - } - foreach (var uaObject in this._model.Objects) - { - context.NamespaceUris.GetIndexOrAppend(uaObject.Namespace); - var referenceTypeId = context.GetModelNodeId(ReferenceTypeIds.HasComponent); - if (GetOtherReferenceWithDerivedReferenceType(uaObject, referenceTypeId) == null) - { - // Only add if not also covered in OtherReferencedNodes (will be added later) - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(referenceTypeId, context), - Value = GetNodeIdForExport(uaObject.NodeId, context), - }); - } - } - foreach (var nodeRef in this._model.OtherReferencedNodes) - { - context.NamespaceUris.GetIndexOrAppend(nodeRef.Node.Namespace); - context.NamespaceUris.GetIndexOrAppend(NodeModelUtils.GetNamespaceFromNodeId(nodeRef.ReferenceType?.NodeId)); - - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(nodeRef.ReferenceType?.NodeId, context), - Value = GetNodeIdForExport(nodeRef.Node.NodeId, context), - }); - } - foreach (var inverseNodeRef in this._model.OtherReferencingNodes) - { - context.NamespaceUris.GetIndexOrAppend(inverseNodeRef.Node.Namespace); - context.NamespaceUris.GetIndexOrAppend(NodeModelUtils.GetNamespaceFromNodeId(inverseNodeRef.ReferenceType?.NodeId)); - - var inverseRef = new Reference - { - ReferenceType = GetNodeIdForExport(inverseNodeRef.ReferenceType?.NodeId, context), - Value = GetNodeIdForExport(inverseNodeRef.Node.NodeId, context), - IsForward = false, - }; - if (!references.Any(r => r.IsForward == false && r.ReferenceType == inverseRef.ReferenceType && r.Value == inverseRef.Value)) - { - // TODO ensure we pick the most derived reference type - references.Add(inverseRef); - } - } - foreach (var uaInterface in this._model.Interfaces) - { - context.NamespaceUris.GetIndexOrAppend(uaInterface.Namespace); - var referenceTypeId = context.GetModelNodeId(ReferenceTypeIds.HasInterface); - if (GetOtherReferenceWithDerivedReferenceType(uaInterface, referenceTypeId) == null) - { - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(referenceTypeId, context), - Value = GetNodeIdForExport(uaInterface.NodeId, context), - }); - } - } - foreach (var method in this._model.Methods) - { - context.NamespaceUris.GetIndexOrAppend(method.Namespace); - - var referenceTypeId = context.GetModelNodeId(ReferenceTypeIds.HasComponent); - if (GetOtherReferenceWithDerivedReferenceType(method, referenceTypeId) == null) - { - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(referenceTypeId, context), - Value = GetNodeIdForExport(method.NodeId, context), - }); - } - } - foreach (var uaEvent in this._model.Events) - { - context.NamespaceUris.GetIndexOrAppend(uaEvent.Namespace); - var referenceTypeId = context.GetModelNodeId(ReferenceTypeIds.GeneratesEvent); - if (GetOtherReferenceWithDerivedReferenceType(uaEvent, referenceTypeId) == null) - { - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(referenceTypeId, context), - Value = GetNodeIdForExport(uaEvent.NodeId, context), - }); - } - } - foreach (var variable in this._model.DataVariables) - { - context.NamespaceUris.GetIndexOrAppend(variable.Namespace); - var referenceTypeId = context.GetModelNodeId(ReferenceTypeIds.HasComponent); - if (GetOtherReferenceWithDerivedReferenceType(variable, referenceTypeId) == null) - { - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(referenceTypeId, context), - Value = GetNodeIdForExport(variable.NodeId, context), - }); - } - } - if (references.Any()) - { - node.References = references.ToArray(); - } - return (node, null, true); - } - - protected string GetOtherReferenceWithDerivedReferenceType(NodeModel uaNode, string referenceTypeModelId) - { - return GetOtherReferenceWithDerivedReferenceType(_model, uaNode, referenceTypeModelId); - } - - static protected string GetOtherReferenceWithDerivedReferenceType(NodeModel parentModel, NodeModel uaNode, string referenceTypeModelId) - { - var otherReferences = parentModel.OtherReferencedNodes.Where(nr => nr.Node == uaNode).ToList(); - var otherMatchingReference = otherReferences.FirstOrDefault(r => (r.ReferenceType as ReferenceTypeModel).SuperType == null || (r.ReferenceType as ReferenceTypeModel)?.HasBaseType(referenceTypeModelId) == true); - if (otherMatchingReference != null && otherMatchingReference.ReferenceType.NodeId != referenceTypeModelId) - { - return otherMatchingReference.ReferenceType.NodeId; - } - return null; - } - - protected string GetNodeIdForExport(NodeId nodeId, ExportContext context, bool applyAlias = true) - { - if (nodeId == null) return null; - var nodeIdStr = nodeId.ToString(); - - context._nodeIdsUsed?.Add(nodeIdStr); - - if (applyAlias && context.Aliases?.TryGetValue(nodeIdStr, out var alias) == true) - { - return alias; - } - return ExpandedNodeId.ToNodeId(nodeId, context.NamespaceUris).ToString(); - } - protected string GetNodeIdForExport(string nodeId, ExportContext context, bool applyAlias = true) - { - if (nodeId == null) { return null; } - NodeId parsedNodeId = GetNodeIdFromString(nodeId, context); - return GetNodeIdForExport(parsedNodeId, context); - } - - private NodeId GetNodeIdFromString(string nodeId, ExportContext context) - { - if (nodeId == null) return null; - NodeId parsedNodeId; - try - { - parsedNodeId = ExpandedNodeId.Parse(nodeId, context.NamespaceUris); - } - catch (ServiceResultException) - { - // try again after adding namespace to the namespace table - var nameSpace = NodeModelUtils.GetNamespaceFromNodeId(nodeId); - context.NamespaceUris.GetIndexOrAppend(nameSpace); - parsedNodeId = ExpandedNodeId.Parse(nodeId, context.NamespaceUris); - } - if (string.IsNullOrEmpty(context.NamespaceUris.GetString(parsedNodeId.NamespaceIndex))) - { - throw ServiceResultException.Create(StatusCodes.BadNodeIdInvalid, "Namespace Uri for Node id ({0}) not specified or not found in the namespace table. Node Ids should be specified in nsu= format.", nodeId); - } - return parsedNodeId; - } - - protected string GetBrowseNameForExport(NamespaceTable namespaces) - { - return GetQualifiedNameForExport(_model.BrowseName, _model.Namespace, _model.DisplayName, namespaces); - } - - protected static string GetQualifiedNameForExport(string qualifiedName, string fallbackNamespace, List displayName, NamespaceTable namespaces) - { - string qualifiedNameForExport; - if (qualifiedName != null) - { - var parts = qualifiedName.Split(new[] { ';' }, 2); - if (parts.Length >= 2) - { - qualifiedNameForExport = new QualifiedName(parts[1], namespaces.GetIndexOrAppend(parts[0])).ToString(); - } - else if (parts.Length == 1) - { - qualifiedNameForExport = parts[0]; - } - else - { - qualifiedNameForExport = ""; - } - } - else - { - qualifiedNameForExport = new QualifiedName(displayName?.FirstOrDefault()?.Text, namespaces.GetIndexOrAppend(fallbackNamespace)).ToString(); - } - - return qualifiedNameForExport; - } - - public override string ToString() - { - return _model?.ToString(); - } - } - - public abstract class InstanceModelExportOpc : NodeModelExportOpc - where TInstanceModel : InstanceModel, new() - where TBaseTypeModel : NodeModel, new() - { - - protected abstract (bool IsChild, NodeId ReferenceTypeId) ReferenceFromParent(NodeModel parent); - - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - if (!result.Created) - { - return result; - } - var instance = result.ExportedNode as UAInstance; - if (instance == null) - { - throw new Exception("Internal error: wrong generic type requested"); - } - var references = instance.References?.ToList() ?? new List(); - - if (!string.IsNullOrEmpty(_model.Parent?.NodeId)) - { - instance.ParentNodeId = GetNodeIdForExport(_model.Parent.NodeId, context); - } - - string typeDefinitionNodeIdForExport; - if (_model.TypeDefinition != null) - { - context.NamespaceUris.GetIndexOrAppend(_model.TypeDefinition.Namespace); - typeDefinitionNodeIdForExport = GetNodeIdForExport(_model.TypeDefinition.NodeId, context); - } - else - { - NodeId typeDefinitionNodeId = null; - if (_model is PropertyModel) - { - typeDefinitionNodeId = VariableTypeIds.PropertyType; - } - else if (_model is DataVariableModel) - { - typeDefinitionNodeId = VariableTypeIds.BaseDataVariableType; - } - else if (_model is VariableModel) - { - typeDefinitionNodeId = VariableTypeIds.BaseVariableType; - } - else if (_model is ObjectModel) - { - typeDefinitionNodeId = ObjectTypeIds.BaseObjectType; - } - - typeDefinitionNodeIdForExport = GetNodeIdForExport(typeDefinitionNodeId, context); - } - if (typeDefinitionNodeIdForExport != null && !(_model.TypeDefinition is MethodModel)) - { - var reference = new Reference - { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasTypeDefinition, context), - Value = typeDefinitionNodeIdForExport, - }; - references.Add(reference); - } - - AddModellingRuleReference(_model.ModellingRule, references, context); - - if (references.Any()) - { - instance.References = references.Distinct(new ReferenceComparer()).ToArray(); - } - - return (instance as T, result.AdditionalNodes, result.Created); - } - - protected List AddModellingRuleReference(string modellingRule, List references, ExportContext context) - { - if (modellingRule != null) - { - var modellingRuleId = modellingRule switch - { - "Optional" => ObjectIds.ModellingRule_Optional, - "Mandatory" => ObjectIds.ModellingRule_Mandatory, - "MandatoryPlaceholder" => ObjectIds.ModellingRule_MandatoryPlaceholder, - "OptionalPlaceholder" => ObjectIds.ModellingRule_OptionalPlaceholder, - "ExposesItsArray" => ObjectIds.ModellingRule_ExposesItsArray, - _ => null, - }; - if (modellingRuleId != null) - { - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasModellingRule, context), - Value = GetNodeIdForExport(modellingRuleId, context), - }); - } - } - return references; - } - - protected void AddOtherReferences(List references, string parentNodeId, NodeId referenceTypeId, bool bIsChild, ExportContext context) - { - if (!string.IsNullOrEmpty(_model.Parent?.NodeId)) - { - bool bAdded = false; - foreach (var referencingNode in _model.Parent.OtherReferencedNodes.Where(cr => cr.Node == _model)) - { - var referenceType = GetNodeIdForExport(referencingNode.ReferenceType?.NodeId, context); - if (!references.Any(r => r.IsForward == false && r.Value == parentNodeId && r.ReferenceType != referenceType)) - { - references.Add(new Reference { IsForward = false, ReferenceType = referenceType, Value = parentNodeId }); - } - else - { - // TODO ensure we pick the most derived reference type - } - bAdded = true; - } - if (bIsChild || !bAdded)//_model.Parent.Objects.Contains(_model)) - { - var referenceType = GetNodeIdForExport(referenceTypeId, context); - if (!references.Any(r => r.IsForward == false && r.Value == parentNodeId && r.ReferenceType != referenceType)) - { - references.Add(new Reference { IsForward = false, ReferenceType = referenceType, Value = parentNodeId }); - } - else - { - // TODO ensure we pick the most derived reference type - } - } - } - } - - - - } - - public class ObjectModelExportOpc : InstanceModelExportOpc - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - if (!result.Created) - { - return (result.ExportedNode as T, result.AdditionalNodes, result.Created); - } - var uaObject = result.ExportedNode; - if (_model.EventNotifier != null) - { - uaObject.EventNotifier = _model.EventNotifier.Value; - } - var references = uaObject.References?.ToList() ?? new List(); - - if (uaObject.ParentNodeId != null) - { - AddOtherReferences(references, uaObject.ParentNodeId, ReferenceTypeIds.HasComponent, _model.Parent.Objects.Contains(_model), context); - } - if (references.Any()) - { - uaObject.References = references.Distinct(new ReferenceComparer()).ToArray(); - } - - return (uaObject as T, result.AdditionalNodes, result.Created); - } - - protected override (bool IsChild, NodeId ReferenceTypeId) ReferenceFromParent(NodeModel parent) - { - return (parent.Objects.Contains(_model), ReferenceTypeIds.HasComponent); - } - } - - public class BaseTypeModelExportOpc : NodeModelExportOpc where TBaseTypeModel : BaseTypeModel, new() - //public class BaseTypeModelExportOpc : NodeModelExportOpc where TBaseTypeModel : BaseTypeModel, new() - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - if (!result.Created) - { - return result; - } - var objectType = result.ExportedNode; - foreach (var subType in this._model.SubTypes) - { - context.NamespaceUris.GetIndexOrAppend(subType.Namespace); - } - - var superType = _model.SuperType; - if (superType == null && _model.NodeId == context.GetModelNodeId(ObjectTypeIds.BaseInterfaceType)) - { - superType = context.GetModelForNode(_model.NodeId); - } - if (superType != null) - { - context.NamespaceUris.GetIndexOrAppend(superType.Namespace); - var superTypeReference = new Reference - { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasSubtype, context), - IsForward = false, - Value = GetNodeIdForExport(superType.NodeId, context), - }; - if (objectType.References == null) - { - objectType.References = new Reference[] { superTypeReference }; - } - else - { - var referenceList = new List(objectType.References); - referenceList.Add(superTypeReference); - objectType.References = referenceList.ToArray(); - } - } - if (objectType is UAType uaType) - { - uaType.IsAbstract = _model.IsAbstract; - } - else - { - throw new Exception("Must be UAType or derived"); - } - return (objectType, result.AdditionalNodes, result.Created); - } - } - - public class ObjectTypeModelExportOpc : BaseTypeModelExportOpc where TTypeModel : BaseTypeModel, new() - //public class ObjectTypeModelExportOpc : BaseTypeModelExportOpc where TTypeModel : BaseTypeModel, new() - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - var objectType = result.ExportedNode; - return (objectType as T, result.AdditionalNodes, result.Created); - } - } - - public class ObjectTypeModelExportOpc : ObjectTypeModelExportOpc - { - } - - public class InterfaceModelExportOpc : ObjectTypeModelExportOpc - { - } - - public abstract class VariableModelExportOpc : InstanceModelExportOpc - where TVariableModel : VariableModel, new() - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - if (_model.DataType?.Namespace != null) - { - context.NamespaceUris.GetIndexOrAppend(_model.DataType.Namespace); - } - else - { - // TODO: should not happen - remove once coded - } - var result = base.GetUANode(context); - if (!result.Created) - { - return (result.ExportedNode as T, result.AdditionalNodes, result.Created); - } - var dataVariable = result.ExportedNode; - - var references = dataVariable.References?.ToList() ?? new List(); - - if (!_model.Properties.Concat(_model.DataVariables).Any(p => p.NodeId == _model.EngUnitNodeId) && (_model.EngineeringUnit != null || !string.IsNullOrEmpty(_model.EngUnitNodeId))) - { - // Add engineering unit property - if (result.AdditionalNodes == null) - { - result.AdditionalNodes = new List(); - } - - var engUnitProp = new UAVariable - { - NodeId = GetNodeIdForExport(!String.IsNullOrEmpty(_model.EngUnitNodeId) ? _model.EngUnitNodeId : NodeModelOpcExtensions.GetNewNodeId(_model.Namespace), context), - BrowseName = BrowseNames.EngineeringUnits, // TODO preserve non-standard browsenames (detected based on data type) - DisplayName = new uaExport.LocalizedText[] { new uaExport.LocalizedText { Value = BrowseNames.EngineeringUnits } }, - ParentNodeId = dataVariable.NodeId, - DataType = DataTypeIds.EUInformation.ToString(), - References = new Reference[] - { - new Reference { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasTypeDefinition, context), - Value = GetNodeIdForExport(VariableTypeIds.PropertyType, context) - }, - new Reference { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasProperty, context), - IsForward = false, - Value = GetNodeIdForExport(dataVariable.NodeId, context), - }, - }, - AccessLevel = _model.EngUnitAccessLevel ?? 1, - // UserAccessLevel: deprecated: never emit - }; - if (_model.EngUnitModellingRule != null) - { - engUnitProp.References = AddModellingRuleReference(_model.EngUnitModellingRule, engUnitProp.References.ToList(), context).ToArray(); - } - if (_model.EngineeringUnit != null) - { - // Ensure EU type gets added to aliases - _ = GetNodeIdForExport(DataTypeIds.EUInformation, context); - - EUInformation engUnits = NodeModelOpcExtensions.GetEUInformation(_model.EngineeringUnit); - var euXmlElement = NodeModelUtils.GetExtensionObjectAsXML(engUnits); - engUnitProp.Value = euXmlElement; - } - result.AdditionalNodes.Add(engUnitProp); - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasProperty, context), - Value = engUnitProp.NodeId, - }); - } - - AddRangeProperties( - dataVariable.NodeId, _model.EURangeNodeId, BrowseNames.EURange, _model.EURangeAccessLevel, _model.EURangeModellingRule, _model.MinValue, _model.MaxValue, - ref result.AdditionalNodes, references, - context); - - AddRangeProperties( - dataVariable.NodeId, _model.InstrumentRangeNodeId, BrowseNames.InstrumentRange, _model.InstrumentRangeAccessLevel, _model.InstrumentRangeModellingRule, _model.InstrumentMinValue, _model.InstrumentMaxValue, - ref result.AdditionalNodes, references, - context); - - if (_model.DataType != null) - { - dataVariable.DataType = GetNodeIdForExport(_model.DataType.NodeId, context); - } - dataVariable.ValueRank = _model.ValueRank ?? -1; - dataVariable.ArrayDimensions = _model.ArrayDimensions; - - if (!string.IsNullOrEmpty(_model.Parent?.NodeId)) - { - dataVariable.ParentNodeId = GetNodeIdForExport(_model.Parent.NodeId, context); - if (!references.Any(r => r.Value == dataVariable.ParentNodeId && r.IsForward == false)) - { - var referenceTypeNodeId = context.GetModelNodeId((_model.Parent.Properties.Contains(_model) ? ReferenceTypeIds.HasProperty : ReferenceTypeIds.HasComponent)); - referenceTypeNodeId = GetOtherReferenceWithDerivedReferenceType(_model.Parent, _model, referenceTypeNodeId) ?? referenceTypeNodeId; - var reference = new Reference - { - IsForward = false, - ReferenceType = GetNodeIdForExport(referenceTypeNodeId, context), - Value = dataVariable.ParentNodeId - }; - references.Add(reference); - } - else - { - // TODO ensure we pick the most derived reference type - } - } - if (_model.Value != null) - { - if (_model.DataType != null) - { - ServiceMessageContext messageContext = NodeModelUtils.GetContextWithDynamicEncodeableFactory(_model.DataType, context.NamespaceUris); - dataVariable.Value = NodeModelUtils.JsonDecodeVariantToXml(_model.Value, messageContext, _model.DataType, context.EncodeJsonScalarsAsValue); - } - else - { - // Unknown data type - } - } - - dataVariable.AccessLevel = _model.AccessLevel ?? 1; - // deprecated: dataVariable.UserAccessLevel = _model.UserAccessLevel ?? 1; - dataVariable.AccessRestrictions = (byte)(_model.AccessRestrictions ?? 0); - dataVariable.UserWriteMask = _model.UserWriteMask ?? 0; - dataVariable.WriteMask = _model.WriteMask ?? 0; - dataVariable.MinimumSamplingInterval = _model.MinimumSamplingInterval ?? 0; - - if (references?.Any() == true) - { - dataVariable.References = references.ToArray(); - } - return (dataVariable as T, result.AdditionalNodes, result.Created); - } - - private void AddRangeProperties( - string parentNodeId, string rangeNodeId, string rangeBrowseName, uint? rangeAccessLevel, string rangeModellingRule, double? minValue, double? maxValue, // inputs - ref List additionalNodes, List references, // outputs - ExportContext context) // lookups - { - if (!_model.Properties.Concat(_model.DataVariables).Any(p => p.NodeId == rangeNodeId) // if it's explicitly authored: don't auto-generate - && (!string.IsNullOrEmpty(rangeNodeId) // if rangeNodeid or min/max are specified: do generate, otherwise skip - || (minValue.HasValue && maxValue.HasValue && minValue != maxValue) - )) - { - // Add EURange property - if (additionalNodes == null) - { - additionalNodes = new List(); - } - - System.Xml.XmlElement xmlElem = null; - - if (minValue.HasValue && maxValue.HasValue) - { - // Ensure EU type gets added to aliases - _ = GetNodeIdForExport(DataTypeIds.Range, context); - var range = new ua.Range - { - Low = minValue.Value, - High = maxValue.Value, - }; - xmlElem = NodeModelUtils.GetExtensionObjectAsXML(range); - } - var euRangeProp = new UAVariable - { - NodeId = GetNodeIdForExport(!String.IsNullOrEmpty(rangeNodeId) ? rangeNodeId : NodeModelOpcExtensions.GetNewNodeId(_model.Namespace), context), - BrowseName = rangeBrowseName, - DisplayName = new uaExport.LocalizedText[] { new uaExport.LocalizedText { Value = rangeBrowseName } }, - ParentNodeId = parentNodeId, - DataType = GetNodeIdForExport(DataTypeIds.Range, context), - References = new[] { - new Reference { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasTypeDefinition, context), - Value = GetNodeIdForExport(VariableTypeIds.PropertyType, context), - }, - new Reference - { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasProperty, context), - IsForward = false, - Value = GetNodeIdForExport(parentNodeId, context), - }, - }, - Value = xmlElem, - AccessLevel = rangeAccessLevel ?? 1, - // deprecated: UserAccessLevel = _model.EURangeUserAccessLevel ?? 1, - }; - - if (rangeModellingRule != null) - { - euRangeProp.References = AddModellingRuleReference(rangeModellingRule, euRangeProp.References?.ToList() ?? new List(), context).ToArray(); - } - - additionalNodes.Add(euRangeProp); - references.Add(new Reference - { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasProperty, context), - Value = GetNodeIdForExport(euRangeProp.NodeId, context), - }); - } - } - } - - public class DataVariableModelExportOpc : VariableModelExportOpc - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - var dataVariable = result.ExportedNode; - //var references = dataVariable.References?.ToList() ?? new List(); - //references.Add(new Reference { ReferenceType = "HasTypeDefinition", Value = GetNodeIdForExport(VariableTypeIds.BaseDataVariableType, context), }); - //dataVariable.References = references.ToArray(); - return (dataVariable, result.AdditionalNodes, result.Created); - } - - protected override (bool IsChild, NodeId ReferenceTypeId) ReferenceFromParent(NodeModel parent) - { - return (parent.DataVariables.Contains(_model), ReferenceTypeIds.HasComponent); - } - } - - public class PropertyModelExportOpc : VariableModelExportOpc - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - if (!result.Created) - { - return result; - } - var property = result.ExportedNode; - var references = property.References?.ToList() ?? new List(); - var propertyTypeNodeId = GetNodeIdForExport(VariableTypeIds.PropertyType, context); - if (references?.Any(r => r.Value == propertyTypeNodeId) == false) - { - references.Add(new Reference { ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasTypeDefinition, context), Value = propertyTypeNodeId, }); - } - property.References = references.ToArray(); - return (property, result.AdditionalNodes, result.Created); - } - protected override (bool IsChild, NodeId ReferenceTypeId) ReferenceFromParent(NodeModel parent) - { - return (false, ReferenceTypeIds.HasProperty); - } - } - - public class MethodModelExportOpc : InstanceModelExportOpc - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - if (!result.Created) - { - return (result.ExportedNode as T, result.AdditionalNodes, result.Created); - } - var method = result.ExportedNode; - method.MethodDeclarationId = GetNodeIdForExport(_model.TypeDefinition?.NodeId, context); - // method.ArgumentDescription = null; // TODO - not commonly used - if (method.ParentNodeId != null) - { - var references = method.References?.ToList() ?? new List(); - AddOtherReferences(references, method.ParentNodeId, ReferenceTypeIds.HasComponent, _model.Parent.Methods.Contains(_model), context); - method.References = references.Distinct(new ReferenceComparer()).ToArray(); - } - return (method as T, result.AdditionalNodes, result.Created); - } - - protected override (bool IsChild, NodeId ReferenceTypeId) ReferenceFromParent(NodeModel parent) - { - return (parent.Methods.Contains(_model), ReferenceTypeIds.HasComponent); - } - } - - public class VariableTypeModelExportOpc : BaseTypeModelExportOpc - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - if (!result.Created) - { - return (result.ExportedNode as T, result.AdditionalNodes, result.Created); - } - var variableType = result.ExportedNode; - variableType.IsAbstract = _model.IsAbstract; - if (_model.DataType != null) - { - variableType.DataType = GetNodeIdForExport(_model.DataType.NodeId, context); - } - if (_model.ValueRank != null) - { - variableType.ValueRank = _model.ValueRank.Value; - } - variableType.ArrayDimensions = _model.ArrayDimensions; - if (_model.Value != null) - { - ServiceMessageContext messageContext = NodeModelUtils.GetContextWithDynamicEncodeableFactory(_model.DataType, context.NamespaceUris); - variableType.Value = NodeModelUtils.JsonDecodeVariantToXml(_model.Value, messageContext, _model.DataType, true); // TODO make this configurable by callers); - } - return (variableType as T, result.AdditionalNodes, result.Created); - } - } - public class DataTypeModelExportOpc : BaseTypeModelExportOpc - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - if (!result.Created) - { - return (result.ExportedNode as T, result.AdditionalNodes, result.Created); - } - var dataType = result.ExportedNode; - if (_model.StructureFields?.Any() == true) - { - var fields = new List(); - foreach (var field in _model.StructureFields.OrderBy(f => f.FieldOrder)) - { - var uaField = new DataTypeField - { - Name = field.Name, - SymbolicName = field.SymbolicName, - DataType = GetNodeIdForExport(field.DataType.NodeId, context), - Description = field.Description.ToExport().ToArray(), - ArrayDimensions = field.ArrayDimensions, - IsOptional = field.IsOptional, - AllowSubTypes = field.AllowSubTypes, - }; - if (field.ValueRank != null) - { - uaField.ValueRank = field.ValueRank.Value; - } - if (field.MaxStringLength != null) - { - uaField.MaxStringLength = field.MaxStringLength.Value; - } - fields.Add(uaField); - } - dataType.Definition = new uaExport.DataTypeDefinition - { - Name = GetBrowseNameForExport(context.NamespaceUris), - SymbolicName = _model.SymbolicName, - Field = fields.ToArray(), - }; - } - if (_model.EnumFields?.Any() == true) - { - var enumValues = new List(); - var fields = new List(); - - // Some nodesets use an improper browsename in their own namespace: tolerate this on export - var existingEnumStringOrValuesModel = _model.Properties.FirstOrDefault(p => - p.BrowseName.EndsWith(BrowseNames.EnumValues) - || p.BrowseName.EndsWith(BrowseNames.EnumStrings) - || p.BrowseName.EndsWith(BrowseNames.OptionSetValues) - ); - int i = 0; - bool requiresEnumValues = false; - bool hasDescription = false; - long previousValue = -1; - foreach (var field in _model.EnumFields.OrderBy(f => f.Value)) - { - var dtField = new DataTypeField - { - Name = field.Name, - DisplayName = field.DisplayName?.ToExport().ToArray(), - Description = field.Description?.ToExport().ToArray(), - Value = (int)field.Value, - SymbolicName = field.SymbolicName, - // TODO: - //DataType = field.DataType, - }; - fields.Add(dtField); - if (_model.IsOptionSet == true && previousValue + 1 < field.Value) - { - var reserved = new EnumValueType { DisplayName = new ua.LocalizedText("Reserved"), }; - for (long j = previousValue + 1; j < field.Value; j++) - { - enumValues.Add(reserved); - } - } - enumValues.Add(new EnumValueType - { - DisplayName = new ua.LocalizedText(field.DisplayName?.FirstOrDefault()?.Text ?? field.Name), - Description = new ua.LocalizedText(field.Description?.FirstOrDefault()?.Text), - Value = field.Value, - }); - if (field.Value != i) - { - // Non-consecutive,non-zero based values require EnumValues instead of EnumStrings. Also better for capturing displayname and description if provided. - requiresEnumValues = true; - } - if (field.DisplayName?.Any() == true || field.Description?.Any() == true) - { - hasDescription = true; - } - i++; - previousValue = field.Value; - } - if (_model.IsOptionSet == true) - { - requiresEnumValues = false; - } - else if (existingEnumStringOrValuesModel?.BrowseName?.EndsWith(BrowseNames.EnumValues) == true) - { - // Keep as authored even if not technically required - requiresEnumValues = true; - } - else if (existingEnumStringOrValuesModel == null) - { - // Only switch to enum values due to description if no authored node - requiresEnumValues |= hasDescription; - } - dataType.Definition = new uaExport.DataTypeDefinition - { - Name = GetBrowseNameForExport(context.NamespaceUris), - Field = fields.ToArray(), - }; - string browseName; - XmlElement enumValuesXml; - if (requiresEnumValues) - { - enumValuesXml = NodeModelUtils.EncodeAsXML((e) => - { - e.PushNamespace(Namespaces.OpcUaXsd); - e.WriteExtensionObjectArray("ListOfExtensionObject", new ExtensionObjectCollection(enumValues.Select(ev => new ExtensionObject(ev)))); - e.PopNamespace(); - }).FirstChild as XmlElement; - browseName = BrowseNames.EnumValues; - } - else - { - enumValuesXml = NodeModelUtils.EncodeAsXML((e) => - { - e.PushNamespace(Namespaces.OpcUaXsd); - e.WriteLocalizedTextArray("ListOfLocalizedText", enumValues.Select(ev => ev.DisplayName).ToArray()); - e.PopNamespace(); - }).FirstChild as XmlElement; - browseName = _model.IsOptionSet == true ? BrowseNames.OptionSetValues : BrowseNames.EnumStrings; - } - - string enumValuesNodeId; - string hasPropertyReferenceTypeId = GetNodeIdForExport(ReferenceTypeIds.HasProperty, context); - UAVariable enumValuesProp; - if (result.AdditionalNodes == null) - { - result.AdditionalNodes = new List(); - } - if (existingEnumStringOrValuesModel != null) - { - enumValuesNodeId = GetNodeIdForExport(existingEnumStringOrValuesModel.NodeId, context); - dataType.References = dataType.References?.Where(r => r.ReferenceType != hasPropertyReferenceTypeId && r.Value != enumValuesNodeId)?.ToArray(); - var enumPropResult = NodeModelExportOpc.GetUANode(existingEnumStringOrValuesModel, context); - if (enumPropResult.AdditionalNodes != null) - { - result.AdditionalNodes.AddRange(enumPropResult.AdditionalNodes); - } - enumValuesProp = enumPropResult.ExportedNode as UAVariable; - enumValuesProp.BrowseName = browseName; - enumValuesProp.DisplayName = new uaExport.LocalizedText[] { new uaExport.LocalizedText { Value = browseName } }; - enumValuesProp.Value = enumValuesXml; - enumValuesProp.DataType = requiresEnumValues ? DataTypeIds.EnumValueType.ToString() : DataTypeIds.LocalizedText.ToString(); - enumValuesProp.ValueRank = 1; - enumValuesProp.ArrayDimensions = enumValues.Count.ToString(CultureInfo.InvariantCulture); - } - else - { - enumValuesNodeId = GetNodeIdForExport(NodeModelOpcExtensions.GetNewNodeId(_model.Namespace), context); - enumValuesProp = new uaExport.UAVariable - { - NodeId = enumValuesNodeId, - BrowseName = browseName, - DisplayName = new uaExport.LocalizedText[] { new uaExport.LocalizedText { Value = browseName } }, - ParentNodeId = result.ExportedNode.NodeId, - DataType = requiresEnumValues ? DataTypeIds.EnumValueType.ToString() : DataTypeIds.LocalizedText.ToString(), - ValueRank = 1, - ArrayDimensions = enumValues.Count.ToString(CultureInfo.InvariantCulture), - References = new Reference[] - { - new Reference { - ReferenceType = GetNodeIdForExport(ReferenceTypeIds.HasTypeDefinition, context), - Value = GetNodeIdForExport(VariableTypeIds.PropertyType, context) - }, - }, - Value = enumValuesXml, - }; - } - var dtReferences = dataType.References?.ToList(); - dtReferences.Add(new Reference - { - ReferenceType = hasPropertyReferenceTypeId, - Value = enumValuesProp.NodeId, - }); - dataType.References = dtReferences.ToArray(); - result.AdditionalNodes.Add(enumValuesProp); - } - if (_model.IsOptionSet != null) - { - if (dataType.Definition == null) - { - dataType.Definition = new uaExport.DataTypeDefinition { }; - } - dataType.Definition.IsOptionSet = _model.IsOptionSet.Value; - } - return (dataType as T, result.AdditionalNodes, result.Created); - } - } - - public class ReferenceTypeModelExportOpc : BaseTypeModelExportOpc - { - public override (T ExportedNode, List AdditionalNodes, bool Created) GetUANode(ExportContext context) - { - var result = base.GetUANode(context); - result.ExportedNode.IsAbstract = _model.IsAbstract; - result.ExportedNode.InverseName = _model.InverseName?.ToExport().ToArray(); - result.ExportedNode.Symmetric = _model.Symmetric; - return (result.ExportedNode as T, result.AdditionalNodes, result.Created); - } - } - - public static class LocalizedTextExtension - { - public static uaExport.LocalizedText ToExport(this NodeModel.LocalizedText localizedText) => localizedText?.Text != null || localizedText?.Locale != null ? new uaExport.LocalizedText { Locale = localizedText.Locale, Value = localizedText.Text } : null; - public static IEnumerable ToExport(this IEnumerable localizedTexts) => localizedTexts?.Select(d => d.Text != null || d.Locale != null ? new uaExport.LocalizedText { Locale = d.Locale, Value = d.Text } : null).ToArray(); - } - -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelFactoryOpc.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelFactoryOpc.cs deleted file mode 100644 index 3783fe77..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/NodesetModelFactoryOpc.cs +++ /dev/null @@ -1,1299 +0,0 @@ -using Opc.Ua; -using ua = Opc.Ua; - -using System; -using System.Collections.Generic; -using System.Linq; - -using CESMII.OpcUa.NodeSetModel.Opc.Extensions; -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; -using Opc.Ua.Export; -using System.Xml; - -namespace CESMII.OpcUa.NodeSetModel.Factory.Opc -{ - - public class NodeModelFactoryOpc : NodeModelFactoryOpc - { - public static Task> LoadNodeSetAsync(IOpcUaContext opcContext, UANodeSet nodeSet, Object customState, Dictionary Aliases, bool doNotReimport = false, List importedNodes = null) - { - if (!nodeSet.Models.Any()) - { - var ex = new Exception($"Invalid nodeset: no models specified"); - opcContext.Logger.LogError(ex.Message); - throw ex; - } - - // Find all models that are used by another nodeset - var requiredModels = nodeSet.Models.Where(m => m.RequiredModel != null).SelectMany(m => m.RequiredModel).Distinct().ToList(); - var missingModels = requiredModels.Where(rm => opcContext.GetOrAddNodesetModel(rm) == null).ToList(); - if (missingModels.Any()) - { - throw new Exception($"Missing dependent node sets: {string.Join(", ", missingModels)}"); - } - - var loadedModels = new List(); - - NodeModelUtils.FixupNodesetVersionFromMetadata(nodeSet, opcContext.Logger); - foreach (var model in nodeSet.Models) - { - var nodesetModel = opcContext.GetOrAddNodesetModel(model); - if (nodesetModel == null) - { - throw new NodeSetResolverException($"Unable to create node set: {model.ModelUri}"); - } - nodesetModel.CustomState = customState; - if (model.RequiredModel != null) - { - foreach (var requiredModel in model.RequiredModel) - { - var requiredModelInfo = nodesetModel.RequiredModels.FirstOrDefault(rm => rm.ModelUri == requiredModel.ModelUri); - if (requiredModelInfo == null) - { - throw new Exception("Required model not found"); - } - if (requiredModelInfo != null && requiredModelInfo.AvailableModel == null) - { - var availableModel = opcContext.GetOrAddNodesetModel(requiredModel); - if (availableModel != null) - { - requiredModelInfo.AvailableModel = availableModel; - } - } - } - } - if (nodeSet.Aliases?.Length > 0 && Aliases != null) - { - foreach (var alias in nodeSet.Aliases) - { - Aliases[alias.Value] = alias.Alias; - } - } - loadedModels.Add(nodesetModel); - } - if (nodeSet.Items == null) - { - nodeSet.Items = new UANode[0]; - } - - var newImportedNodes = opcContext.ImportUANodeSet(nodeSet); - - // TODO Read nodeset poperties like author etc. and expose them in Profile editor - - foreach (var node in newImportedNodes) - { - var nodeModel = NodeModelFactoryOpc.Create(opcContext, node, customState, out var bAdded); - if (nodeModel != null && !bAdded) - { - var nodesetModel = nodeModel.NodeSet; - - if (!nodesetModel.AllNodesByNodeId.ContainsKey(nodeModel.NodeId)) - { - nodesetModel.UnknownNodes.Add(nodeModel); - } - } - } - - // Ensure references that are implicitly used by the importer get resolved into the OPC model - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(ReferenceTypes.HasSubtype), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(ReferenceTypes.HasModellingRule), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(Objects.ModellingRule_Mandatory), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(Objects.ModellingRule_Optional), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(Objects.ModellingRule_ExposesItsArray), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(Objects.ModellingRule_MandatoryPlaceholder), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(Objects.ModellingRule_OptionalPlaceholder), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(ReferenceTypes.HasTypeDefinition), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(ReferenceTypes.GeneratesEvent), null, out _); - ReferenceTypeModelFactoryOpc.Create(opcContext, opcContext.GetNode(ReferenceTypes.Organizes), null, out _); - - if (importedNodes != null) - { - importedNodes.AddRange(newImportedNodes); - } - return Task.FromResult(loadedModels); - } - } - public class NodeModelFactoryOpc where TNodeModel : NodeModel, new() - { - protected TNodeModel _model; - protected ILogger Logger; - - protected virtual void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - Logger.LogTrace($"Creating node model for {opcNode}"); - // TODO capture multiple locales from a nodeset: UA library seems to offer only one locale - _model.DisplayName = opcNode.DisplayName.ToModel(); - - var browseNameNamespace = opcContext.NamespaceUris.GetString(opcNode.BrowseName.NamespaceIndex); - _model.BrowseName = opcContext.GetModelBrowseName(opcNode.BrowseName); - _model.SymbolicName = opcNode.SymbolicName; - _model.Description = opcNode.Description.ToModel(); - if (opcNode.Categories != null) - { - if (_model.Categories == null) - { - _model.Categories = new List(); - } - _model.Categories.AddRange(opcNode.Categories); - } - _model.Documentation = opcNode.NodeSetDocumentation; - _model.ReleaseStatus = opcNode.ReleaseStatus.ToString(); - - if (recursionDepth <= 0) - { - _model.ReferencesNotResolved = true; - return; - } - - recursionDepth--; - _model.ReferencesNotResolved = false; - - var references = opcContext.GetHierarchyReferences(opcNode); - - foreach (var reference in references) - { - var referenceType = opcContext.GetNode(reference.ReferenceTypeId) as ReferenceTypeState; - if (referenceType == null) - { - throw new Exception($"Reference Type {reference.ReferenceTypeId} not found for reference from {opcNode} to {reference.TargetId} . Missing required model / node set?"); - } - var referenceTypes = GetBaseTypes(opcContext, referenceType); - - var referencedNode = opcContext.GetNode(reference.TargetId); - if (referencedNode == null) - { - throw new Exception($"Referenced node {reference.TargetId} not found for {opcNode}"); - } - - if (reference.IsInverse) - { - // TODO UANodeSet.Import should already handle inverse references: investigate why these are not processed - // Workaround for now: - AddChildToNodeModel( - () => NodeModelFactoryOpc.Create(opcContext, referencedNode, this._model.CustomState, out _, recursionDepth), - opcContext, referenceType, referenceTypes, opcNode, recursionDepth); - } - else - { - AddChildToNodeModel(() => this._model, opcContext, referenceType, referenceTypes, referencedNode, recursionDepth); - } - } - Logger.LogTrace($"Created node model {this._model} for {opcNode}"); - } - - private static void AddChildToNodeModel(Func parentFactory, IOpcUaContext opcContext, ReferenceTypeState referenceType, List referenceTypes, NodeState referencedNode, int recursionDepth) - { - var organizesNodeId = opcContext.GetModelNodeId(ReferenceTypeIds.Organizes); - if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.HasComponent)) - { - if (referencedNode is BaseObjectState objectState) - { - // NodeModel.Objects - var parent = parentFactory(); - var uaChildObject = Create(opcContext, objectState, parent?.CustomState, recursionDepth); - if (uaChildObject != null) - { - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - if (parent?.Namespace != uaChildObject.Namespace) - { - // Add the reverse reference to the referencing node (parent) - var referencingNodeAndReference = new NodeModel.NodeAndReference { Node = parent, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(uaChildObject, uaChildObject.OtherReferencingNodes, referencingNodeAndReference, opcContext.Logger, organizesNodeId, false); - } - AddChildIfNotExists(parent, parent?.Objects, uaChildObject, opcContext.Logger, organizesNodeId); - if (referenceTypes[0].NodeId != ReferenceTypeIds.HasComponent) - { - // Preserve the more specific reference type as well - var nodeAndReference = new NodeModel.NodeAndReference { Node = uaChildObject, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId, false); - } - } - } - else if (referencedNode is BaseObjectTypeState objectTypeState) - { - opcContext.Logger.LogWarning($"Ignoring component {referencedNode} with unexpected node type {referencedNode.GetType()}"); - } - else if (referencedNode is BaseDataVariableState variableState) - { - // NodeModel.DataVariables - if (ProcessEUInfoAndRanges(opcContext, referencedNode, parentFactory)) - { - // EU Information was captured in the parent model - return; - } - var parent = parentFactory(); - var variable = Create(opcContext, variableState, parent?.CustomState, recursionDepth); - AddChildIfNotExists(parent, parent?.DataVariables, variable, opcContext.Logger, organizesNodeId); - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - if (referenceTypes[0].NodeId != ReferenceTypeIds.HasComponent) - { - // Preserve the more specific reference type as well - var nodeAndReference = new NodeModel.NodeAndReference { Node = variable, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId, false); - } - } - else if (referencedNode is MethodState methodState) - { - // NodeModel.Methods - var parent = parentFactory(); - var method = Create(opcContext, methodState, parent?.CustomState, recursionDepth); - AddChildIfNotExists(parent, parent?.Methods, method, opcContext.Logger, organizesNodeId); - } - else if(referencedNode is PropertyState propertyState) - { - // Not allowed per spec, but tolerate (treat as Property) - var parent = parentFactory(); - var property = Create(opcContext, propertyState, parent?.CustomState, recursionDepth); - AddChildIfNotExists(parent, parent?.Properties, property, opcContext.Logger, organizesNodeId); - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - if (referenceTypes[0].NodeId != ReferenceTypeIds.HasComponent) - { - // Preserve the more specific reference type as well - var nodeAndReference = new NodeModel.NodeAndReference { Node = property, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId, false); - } - } - else - { - var parent = parentFactory(); - if (referencedNode != null) - { - throw new Exception($"Property {referencedNode} has unexpected type {referencedNode.GetType()} in {parent}"); - } - throw new Exception($"Property {referencedNode} not found in {parent}"); - } - } - else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.HasProperty)) - { - // NodeModel.Properties - if (ProcessEUInfoAndRanges(opcContext, referencedNode, parentFactory)) - { - // EU Information was captured in the parent model - return; - } - // OptionSetValues are not commonly used and if they are they don't differ from the enum definitiones except for reserved bits: just preserve as regular properties/values for now so we can round trip without designer support - //else if (referencedNode.BrowseName?.Name == BrowseNames.OptionSetValues) - //{ - // var parent = parentFactory(); - // if (parent is DataTypeModel dataType && dataType != null) - // { - // var optionSetValues = ((referencedNode as BaseVariableState)?.Value as LocalizedText[]); - // if (optionSetValues != null) - // { - // dataType.SetOptionSetValues(optionSetValues.ToModel()); - // return; - // } - // else - // { - // opcContext.Logger.LogInformation($"No or invalid OptionSetValues in {parent} for {referencedNode}"); - // } - // } - // else - // { - // opcContext.Logger.LogInformation($"Unexpected parent {parent} of type {parent.GetType()} for OptionSetValues property {referencedNode}"); - // } - //} - if (referencedNode is PropertyState propertyState) - { - var parent = parentFactory(); - var property = Create(opcContext, propertyState, parent?.CustomState, recursionDepth); - AddChildIfNotExists(parent, parent?.Properties, property, opcContext.Logger, organizesNodeId); - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - if (referenceTypes[0].NodeId != ReferenceTypeIds.HasProperty) - { - // Preserve the more specific reference type as well - var nodeAndReference = new NodeModel.NodeAndReference { Node = property, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId, false); - } - } - else if (referencedNode is BaseDataVariableState variableState) - { - // Surprisingly, properties can also be of type DataVariable - var parent = parentFactory(); - var variable = Create(opcContext, variableState, parent?.CustomState, recursionDepth); - AddChildIfNotExists(parent, parent?.Properties, variable, opcContext.Logger, organizesNodeId); - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - if (referenceTypes[0].NodeId != ReferenceTypeIds.HasProperty) - { - // Preserve the more specific reference type as well - var nodeAndReference = new NodeModel.NodeAndReference { Node = variable, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId, false); - } - } - else - { - var parent = parentFactory(); - if (referencedNode != null) - { - throw new Exception($"Property {referencedNode} has unexpected type {referencedNode.GetType()} in {parent}"); - } - throw new Exception($"Property {referencedNode} not found in {parent}"); - - } - } - else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.HasInterface)) - { - // NodeModel.Interfaces - if (referencedNode is BaseObjectTypeState interfaceTypeState) - { - var parent = parentFactory(); - var uaInterface = Create(opcContext, interfaceTypeState, parent?.CustomState, recursionDepth); - if (uaInterface != null) - { - AddChildIfNotExists(parent, parent?.Interfaces, uaInterface, opcContext.Logger, organizesNodeId); - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - if (referenceTypes[0].NodeId != ReferenceTypeIds.HasInterface) - { - // Preserve the more specific reference type as well - var nodeAndReference = new NodeModel.NodeAndReference { Node = uaInterface, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId); - } - } - } - else - { - var parent = parentFactory(); - if (referencedNode != null) - { - throw new Exception($"Interface {referencedNode} has unexpected type {referencedNode.GetType()} in {parent}"); - } - throw new Exception($"Interface {referencedNode} not found in {parent}"); - } - } - //else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.Organizes)) - //{ - // if (referencedNode is BaseObjectState) - // { - // var parent = parentFactory(); - // var organizedNode = Create(opcContext, referencedNode, parent.CustomState); - // AddChildIfNotExists(parent, parent?.Objects, organizedNode, opcContext.Logger); - // } - // else - // { - - // } - //} - //else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.FromState)) - //{ } - //else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.ToState)) - //{ } - //else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.HasEffect)) - //{ } - //else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.HasCause)) - //{ } - else if (referenceTypes.Any(n => n.NodeId == ReferenceTypeIds.GeneratesEvent)) - { - // NodeModel.Events - if (referencedNode is BaseObjectTypeState eventTypeState) - { - var parent = parentFactory(); - var uaEvent = Create(opcContext, eventTypeState, parent?.CustomState, recursionDepth); - if (uaEvent != null) - { - AddChildIfNotExists(parent, parent?.Events, uaEvent, opcContext.Logger, organizesNodeId); - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - if (referenceTypes[0].NodeId != ReferenceTypeIds.GeneratesEvent) - { - // Preserve the more specific reference type as well - var nodeAndReference = new NodeModel.NodeAndReference { Node = uaEvent, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId); - } - } - } - else - { - var parent = parentFactory(); - throw new Exception($"Unexpected event type {referencedNode} in {parent}"); - } - } - else - { - // NodeModel.OtherReferencedNodes - var parent = parentFactory(); - var referencedModel = Create(opcContext, referencedNode, parent?.CustomState, out _, recursionDepth); - if (referencedModel != null) - { - var referenceTypeModel = ReferenceTypeModelFactoryOpc.Create(opcContext, referenceType, null, out _, recursionDepth) as ReferenceTypeModel; - var nodeAndReference = new NodeModel.NodeAndReference - { - Node = referencedModel, - ReferenceType = referenceTypeModel - }; - AddChildIfNotExists(parent, parent?.OtherReferencedNodes, nodeAndReference, opcContext.Logger, organizesNodeId, true); - - // Add the reverse reference to the referencing node (parent) - var referencingNodeAndReference = new NodeModel.NodeAndReference { Node = parent, ReferenceType = referenceTypeModel }; - AddChildIfNotExists(referencedModel, referencedModel.OtherReferencingNodes, referencingNodeAndReference, opcContext.Logger, organizesNodeId, false); - } - else - { - new Exception($"Failed to resolve reference {referenceTypes.FirstOrDefault()} from {parent} to {referencedNode}."); - } - // Potential candidates for first class representation in the model: - // {ns=1;i=6030} - ConnectsTo / Hierarchical - // {ns=2;i=18179} - Requires / Hierarchical - // {ns=2;i=18178} - Moves / Hierarchical - // {ns=2;i=18183} - HasSlave / Hierachical - // {ns=2;i=18180} - IsDrivenBy / Hierarchical - // {ns=2;i=18182} - HasSafetyStates - Hierarchical - // {ns=2;i=4002} - Controls / Hierarchical - } - - } - static void AddChildIfNotExists(NodeModel parent, IList collection, TColl uaChildObject, ILogger logger, string organizesNodeId, bool setParent = true) - { - if (uaChildObject == null) - { - return; - } - if (setParent - && (uaChildObject is InstanceModelBase uaInstance - || (uaChildObject is NodeModel.NodeAndReference nr - && (nr.ReferenceType as ReferenceTypeModel)?.HasBaseType(organizesNodeId) == true - && (uaInstance = (nr.Node as InstanceModelBase)) != null) - )) - { - uaInstance.Parent = parent; - if (uaInstance.Parent != parent) - { - logger.LogInformation($"{uaInstance} has more than one parent. Ignored parent: {parent}, using {uaInstance.Parent}"); - } - } - if (collection?.Contains(uaChildObject) == false) - { - collection.Add(uaChildObject); - } - } - - static bool ProcessEUInfoAndRangesWithoutParent(IOpcUaContext opcContext, NodeState potentialEUNode, object customState) - { - if (potentialEUNode.BrowseName?.Name == BrowseNames.EngineeringUnits || (potentialEUNode as BaseVariableState)?.DataType == DataTypeIds.EUInformation - || potentialEUNode.BrowseName?.Name == BrowseNames.EURange || potentialEUNode.BrowseName?.Name == BrowseNames.InstrumentRange) - { - foreach (var referenceToNode in opcContext.GetHierarchyReferences(potentialEUNode).Where(r => r.IsInverse)) - { - var referencingNodeState = opcContext.GetNode(referenceToNode.TargetId); - var referencingNode = Create(opcContext, referencingNodeState, customState, out _); - if (ProcessEUInfoAndRanges(opcContext, potentialEUNode, () => referencingNode)) - { - // captured in the referencing node - return true; - } - } - } - return false; - } - static bool ProcessEUInfoAndRanges(IOpcUaContext opcContext, NodeState referencedNode, Func parentFactory) - { - if (referencedNode.BrowseName?.Name == BrowseNames.EngineeringUnits || (referencedNode as BaseVariableState).DataType == DataTypeIds.EUInformation) - { - var parent = parentFactory(); - if (parent is VariableModel parentVariable && parentVariable != null) - { - parentVariable.EngUnitNodeId = opcContext.GetModelNodeId(referencedNode.NodeId); - - var modellingRuleId = (referencedNode as BaseInstanceState)?.ModellingRuleId; - if (modellingRuleId != null) - { - var modellingRule = opcContext.GetNode(modellingRuleId); - if (modellingRule == null) - { - throw new Exception($"Unable to resolve modelling rule {modellingRuleId}: dependency on UA nodeset not declared?"); - } - parentVariable.EngUnitModellingRule = modellingRule.DisplayName.Text; - } - if (referencedNode is BaseVariableState euInfoVariable) - { - parentVariable.EngUnitAccessLevel = euInfoVariable.AccessLevelEx != 1 ? euInfoVariable.AccessLevelEx : null; - // deprecated: parentVariable.EngUnitUserAccessLevel = euInfoVariable.UserAccessLevel != 1 ? euInfoVariable.UserAccessLevel : null; - - var euInfoExtension = euInfoVariable.Value as ExtensionObject; - var euInfo = euInfoExtension?.Body as EUInformation; - if (euInfo != null) - { - parentVariable.SetEngineeringUnits(euInfo); - } - else - { - if (euInfoVariable.Value != null) - { - if (euInfoExtension != null) - { - if (euInfoExtension.TypeId != ObjectIds.EUInformation_Encoding_DefaultXml) - { - throw new Exception($"Unable to parse Engineering units for {parentVariable}: Invalid encoding type id {euInfoExtension.TypeId}. Expected {ObjectIds.EUInformation_Encoding_DefaultXml}."); - } - if (euInfoExtension.Body is XmlElement xmlValue) - { - throw new Exception($"Unable to parse Engineering units for {parentVariable}: TypeId: {euInfoExtension.TypeId}.XML: {xmlValue.OuterXml}."); - } - throw new Exception($"Unable to parse Engineering units for {parentVariable}: TypeId: {euInfoExtension.TypeId}. Value: {(referencedNode as BaseVariableState).Value}"); - } - throw new Exception($"Unable to parse Engineering units for {parentVariable}: {(referencedNode as BaseVariableState).Value}"); - } - // Nodesets commonly indicate that EUs are required on instances by specifying an empty EU in the class - } - } - return true; - } - } - else if (referencedNode.BrowseName?.Name == BrowseNames.EURange) - { - var parent = parentFactory(); - if (parent is VariableModel parentVariable && parentVariable != null) - { - var info = GetRangeInfo(parentVariable, referencedNode, opcContext); - parentVariable.EURangeNodeId = info.RangeNodeId; - parentVariable.EURangeModellingRule = info.ModellingRuleId; - parentVariable.EURangeAccessLevel = info.rangeAccessLevel; - if (info.range != null) - { - parentVariable.SetRange(info.range); - } - return true; - } - } - else if (referencedNode.BrowseName?.Name == BrowseNames.InstrumentRange) - { - var parent = parentFactory(); - if (parent is VariableModel parentVariable && parentVariable != null) - { - var info = GetRangeInfo(parentVariable, referencedNode, opcContext); - parentVariable.InstrumentRangeNodeId = info.RangeNodeId; - parentVariable.InstrumentRangeModellingRule = info.ModellingRuleId; - parentVariable.InstrumentRangeAccessLevel = info.rangeAccessLevel; - if (info.range != null) - { - parentVariable.SetInstrumentRange(info.range); - } - return true; - } - } - return false; - } - - static (ua.Range range, string RangeNodeId, string ModellingRuleId, uint? rangeAccessLevel) - GetRangeInfo(NodeModel parentVariable, NodeState referencedNode, IOpcUaContext opcContext) - { - string rangeNodeId = opcContext.GetModelNodeId(referencedNode.NodeId); - string rangeModellingRule = null; - uint? rangeAccessLevel = null; - ua.Range range = null; - var modellingRuleId = (referencedNode as BaseInstanceState)?.ModellingRuleId; - if (modellingRuleId != null) - { - var modellingRuleNode = opcContext.GetNode(modellingRuleId); - if (modellingRuleNode == null) - { - throw new Exception($"Unable to resolve modelling rule {modellingRuleId}: dependency on UA nodeset not declared?"); - } - rangeModellingRule = modellingRuleNode.DisplayName.Text; - } - if (referencedNode is BaseVariableState euRangeVariable) - { - rangeAccessLevel = euRangeVariable.AccessLevelEx != 1 ? euRangeVariable.AccessLevelEx : null; - // deprecated: parentVariable.EURangeUserAccessLevel = euRangeVariable.UserAccessLevel != 1 ? euRangeVariable.UserAccessLevel : null; - - var euRangeExtension = euRangeVariable.Value as ExtensionObject; - range = euRangeExtension?.Body as ua.Range; - if (range == null) - { - if (euRangeVariable.Value != null) - { - if (euRangeExtension != null) - { - if (euRangeExtension.TypeId != ObjectIds.Range_Encoding_DefaultXml) - { - throw new Exception($"Unable to parse {referencedNode.BrowseName?.Name} for {parentVariable}: Invalid encoding type id {euRangeExtension.TypeId}. Expected {ObjectIds.Range_Encoding_DefaultXml}."); - } - if (euRangeExtension.Body is XmlElement xmlValue) - { - throw new Exception($"Unable to parse {referencedNode.BrowseName?.Name} for {parentVariable}: TypeId: {euRangeExtension.TypeId}.XML: {xmlValue.OuterXml}."); - } - throw new Exception($"Unable to parse {referencedNode.BrowseName?.Name} for {parentVariable}: TypeId: {euRangeExtension.TypeId}. Value: {(referencedNode as BaseVariableState).Value}"); - } - throw new Exception($"Unable to parse {referencedNode.BrowseName?.Name} for {parentVariable}: {(referencedNode as BaseVariableState).Value}"); - } - // Nodesets commonly indicate that EURange are required on instances by specifying an enpty EURange in the class - } - } - return (range, rangeNodeId, rangeModellingRule, rangeAccessLevel); - } - - - public static NodeModel Create(IOpcUaContext opcContext, NodeState node, object customState, out bool added, int recursionDepth = int.MaxValue) - { - NodeModel nodeModel; - added = true; - if (node is DataTypeState dataType) - { - nodeModel = Create(opcContext, dataType, customState, recursionDepth); - } - else if (node is BaseVariableTypeState variableType) - { - nodeModel = Create(opcContext, variableType, customState, recursionDepth); - } - else if (node is BaseObjectTypeState objectType) - { - if (GetBaseTypes(opcContext, objectType).Any(n => n.NodeId == ObjectTypeIds.BaseInterfaceType)) - { - nodeModel = Create(opcContext, objectType, customState, recursionDepth); - } - else - { - nodeModel = Create(opcContext, objectType, customState, recursionDepth); - } - } - else if (node is BaseObjectState uaObject) - { - nodeModel = Create(opcContext, uaObject, customState, recursionDepth); - } - else if (node is PropertyState property) - { - nodeModel = Create(opcContext, property, customState, recursionDepth); - } - else if (node is BaseDataVariableState dataVariable) - { - nodeModel = Create(opcContext, dataVariable, customState, recursionDepth); - } - else if (node is MethodState methodState) - { - nodeModel = Create(opcContext, methodState, customState, recursionDepth); - } - else if (node is ReferenceTypeState referenceState) - { - nodeModel = Create(opcContext, referenceState, customState, recursionDepth); - } - else - { - if (!(node is ViewState)) - { - nodeModel = Create, TNodeModel>(opcContext, node, customState, recursionDepth); - } - else - { - // TODO support Views - nodeModel = null; - } - added = false; - } - return nodeModel; - - } - - public static List GetBaseTypes(IOpcUaContext opcContext, BaseTypeState objectType) - { - var baseTypes = new List(); - if (objectType != null) - { - baseTypes.Add(objectType); - } - var currentObjectType = objectType; - while (currentObjectType?.SuperTypeId != null) - { - var objectSuperType = opcContext.GetNode(currentObjectType.SuperTypeId); - if (objectSuperType is BaseTypeState) - { - baseTypes.Add(objectSuperType as BaseTypeState); - } - else - { - baseTypes.Add(new BaseObjectTypeState { NodeId = objectType.SuperTypeId, Description = "Unknown type: more base types may exist" }); - } - currentObjectType = objectSuperType as BaseTypeState; - } - return baseTypes; - } - - - protected static TNodeModel2 Create(IOpcUaContext opcContext, NodeState opcNode, object customState, int recursionDepth) where TNodeModelOpc : NodeModelFactoryOpc, new() where TNodeModel2 : NodeModel, new() - { - var nodeId = opcContext.GetModelNodeId(opcNode.NodeId); - - // EngineeringUnits are captured in the datavariable to which they belong in order to simplify the model for consuming applications - // Need to make sure that the nodes with engineering units get properly captured even if they are processed before the containing node - if (ProcessEUInfoAndRangesWithoutParent(opcContext, opcNode, customState)) - { - // Node was captured into a parent: don't create separate model for it - return null; - } - string namespaceUri = opcContext.NamespaceUris.GetString(opcNode.NodeId.NamespaceIndex); - var nodeModel = Create(opcContext, nodeId, new ModelTableEntry { ModelUri = namespaceUri }, customState, out var created); - var nodeModelOpc = new TNodeModelOpc { _model = nodeModel, Logger = opcContext.Logger }; - if (created || nodeModel.ReferencesNotResolved) - { - nodeModelOpc.Initialize(opcContext, opcNode, recursionDepth); - } - else - { - opcContext.Logger.LogTrace($"Using previously created node model {nodeModel} for {opcNode}"); - } - return nodeModel; - } - - public static TNodeModel2 Create(IOpcUaContext opcContext, string nodeId, ModelTableEntry opcModelInfo, object customState, out bool created) where TNodeModel2 : NodeModel, new() - { - created = false; - opcContext.NamespaceUris.GetIndexOrAppend(opcModelInfo.ModelUri); // Ensure the namespace is in the namespace table - var nodeModelBase = opcContext.GetModelForNode(nodeId); - var nodeModel = nodeModelBase as TNodeModel2; - if (nodeModel == null) - { - if (nodeModelBase != null) - { - throw new Exception($"Internal error - Type mismatch for node {nodeId}: NodeModel of type {typeof(TNodeModel2)} was previously created with type {nodeModelBase.GetType()}."); - } - var nodesetModel = opcContext.GetOrAddNodesetModel(opcModelInfo); - - nodeModel = new TNodeModel2(); - nodeModel.NodeSet = nodesetModel; - if (nodesetModel.CustomState == null) - { - nodesetModel.CustomState = customState; - } - nodeModel.NodeId = nodeId; - nodeModel.CustomState = customState; - created = true; - - if (!nodesetModel.AllNodesByNodeId.ContainsKey(nodeModel.NodeId)) - { - nodesetModel.AllNodesByNodeId.Add(nodeModel.NodeId, nodeModel); - if (nodeModel is InterfaceModel uaInterface) - { - nodesetModel.Interfaces.Add(uaInterface); - } - else if (nodeModel is ObjectTypeModel objectType) - { - nodesetModel.ObjectTypes.Add(objectType); - } - else if (nodeModel is DataTypeModel dataType) - { - nodesetModel.DataTypes.Add(dataType); - } - else if (nodeModel is DataVariableModel dataVariable) - { - nodesetModel.DataVariables.Add(dataVariable); - } - else if (nodeModel is VariableTypeModel variableType) - { - nodesetModel.VariableTypes.Add(variableType); - } - else if (nodeModel is ObjectModel uaObject) - { - nodesetModel.Objects.Add(uaObject); - } - else if (nodeModel is PropertyModel property) - { - nodesetModel.Properties.Add(property); - } - else if (nodeModel is MethodModel method) - { - nodesetModel.Methods.Add(method); - } - else if (nodeModel is ReferenceTypeModel referenceType) - { - nodesetModel.ReferenceTypes.Add(referenceType); - } - else - { - throw new Exception($"Unexpected node model type {nodeModel.GetType().FullName} for node {nodeModel}"); - } - } - else - { - // Node already processed - opcContext.Logger.LogWarning($"Node {nodeModel} was already in the nodeset model."); - } - } - if (customState != null && nodeModel != null && nodeModel.CustomState == null) - { - nodeModel.CustomState = customState; - } - return nodeModel; - } - - } - - public class InstanceModelFactoryOpc : NodeModelFactoryOpc - where TInstanceModel : InstanceModel, new() - where TBaseTypeModel : NodeModel, new() - where TBaseTypeModelFactoryOpc : NodeModelFactoryOpc, new() - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - var uaInstance = opcNode as BaseInstanceState; - var variableTypeDefinition = opcContext.GetNode(uaInstance.TypeDefinitionId); - if (variableTypeDefinition != null) //is BaseTypeState) - { - var typeDefModel = NodeModelFactoryOpc.Create(opcContext, variableTypeDefinition, _model.CustomState, out _, recursionDepth -1); // Create(opcContext, variableTypeDefinition, null); - _model.TypeDefinition = typeDefModel as TBaseTypeModel; - if (_model.TypeDefinition == null) - { - throw new Exception($"Unexpected type definition {variableTypeDefinition} on {uaInstance}"); - } - } - - if (uaInstance.ModellingRuleId != null) - { - var modellingRuleId = uaInstance.ModellingRuleId; - var modellingRule = opcContext.GetNode(modellingRuleId); - if (modellingRule == null) - { - throw new Exception($"Unable to resolve modelling rule {modellingRuleId}: dependency on UA nodeset not declared?"); - } - _model.ModellingRule = modellingRule.DisplayName.Text; - } - if (uaInstance.Parent != null) - { - var instanceParent = NodeModelFactoryOpc.Create(opcContext, uaInstance.Parent, null, out _, recursionDepth - 1); - _model.Parent = instanceParent; - if (_model.Parent != instanceParent) - { - opcContext.Logger.LogWarning($"{_model} has more than one parent. Ignored parent: {instanceParent}, using {_model.Parent}."); - } - } - } - - } - - public class ObjectModelFactoryOpc : InstanceModelFactoryOpc - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - if (opcNode is BaseObjectState objState) - { - _model.EventNotifier = objState.EventNotifier; - } - } - } - - public class BaseTypeModelFactoryOpc : NodeModelFactoryOpc where TBaseTypeModel : BaseTypeModel, new() - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - var uaType = opcNode as BaseTypeState; - - if (uaType.SuperTypeId != null) - { - var superTypeNodeId = opcContext.GetModelNodeId(uaType.SuperTypeId); - BaseTypeModel superTypeModel = opcContext.GetModelForNode(superTypeNodeId); - if (superTypeModel == null) - { - // Handle cases where the supertype is of a different model class, for example the InterfaceModel for BaseInterfaceType has a supertype ObjectTypeModel, while all other InterfaceModels have a supertype of Interfacemodel - superTypeModel = opcContext.GetModelForNode(superTypeNodeId); - } - if (superTypeModel == null) - { - var superTypeState = opcContext.GetNode(uaType.SuperTypeId) as BaseTypeState; - if (superTypeState != null) - { - // Always resolve basetypes, regardless of recursionDepth - superTypeModel = NodeModelFactoryOpc.Create(opcContext, superTypeState, this._model.CustomState, out _, 2) as BaseTypeModel; - if (superTypeModel == null) - { - throw new Exception($"Invalid node {superTypeState} is not a Base Type"); - } - } - } - _model.SuperType = superTypeModel; - _model.RemoveInheritedAttributes(_model.SuperType); - foreach (var uaInterface in _model.Interfaces) - { - _model.RemoveInheritedAttributes(uaInterface); - } - } - else - { - _model.SuperType = null; - } - _model.IsAbstract = uaType.IsAbstract; - } - - } - - public class ObjectTypeModelFactoryOpc : BaseTypeModelFactoryOpc where TTypeModel : BaseTypeModel, new() - { - } - - public class ObjectTypeModelFactoryOpc : ObjectTypeModelFactoryOpc - { - } - - public class InterfaceModelFactoryOpc : ObjectTypeModelFactoryOpc - { - } - - public class VariableModelFactoryOpc : InstanceModelFactoryOpc - where TVariableModel : VariableModel, new() - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - var variableNode = opcNode as BaseVariableState; - - InitializeDataTypeInfo(_model, opcContext, variableNode, recursionDepth); - if (variableNode.AccessLevelEx != 1) _model.AccessLevel = variableNode.AccessLevelEx; - // deprecated if (variableNode.UserAccessLevel != 1) _model.UserAccessLevel = variableNode.UserAccessLevel; - if (variableNode.AccessRestrictions.HasValue && (variableNode.AccessRestrictions != 0)) _model.AccessRestrictions = (ushort)variableNode.AccessRestrictions; - if (variableNode.WriteMask != 0) _model.WriteMask = (uint)variableNode.WriteMask; - if (variableNode.UserWriteMask != 0) _model.UserWriteMask = (uint)variableNode.UserWriteMask; - if (variableNode.MinimumSamplingInterval != 0) - { - _model.MinimumSamplingInterval = variableNode.MinimumSamplingInterval; - } - - var invalidBrowseNameOnTypeInformation = _model.Properties.Where(p => - (p.BrowseName.EndsWith(BrowseNames.EnumValues) && p.BrowseName != opcContext.GetModelBrowseName(BrowseNames.EnumValues)) - || (p.BrowseName.EndsWith(BrowseNames.EnumStrings) && p.BrowseName != opcContext.GetModelBrowseName(BrowseNames.EnumStrings)) - || (p.BrowseName.EndsWith(BrowseNames.OptionSetValues) && p.BrowseName != opcContext.GetModelBrowseName(BrowseNames.OptionSetValues)) - ); - if (invalidBrowseNameOnTypeInformation.Any()) - { - opcContext.Logger.LogWarning($"Found type definition node with browsename in non-default namespace: {string.Join("", invalidBrowseNameOnTypeInformation.Select(ti => ti.BrowseName))}"); - } - - - if (string.IsNullOrEmpty(this._model.NodeSet.XmlSchemaUri) && variableNode.TypeDefinitionId == VariableTypeIds.DataTypeDictionaryType) - { - var namespaceUriModelBrowseName = opcContext.GetModelBrowseName(BrowseNames.NamespaceUri); - var xmlNamespaceVariable = _model.Properties.FirstOrDefault(dv => dv.BrowseName == namespaceUriModelBrowseName); - if (_model.Parent.NodeId == opcContext.GetModelNodeId(ObjectIds.XmlSchema_TypeSystem)) - { - if (xmlNamespaceVariable != null && !string.IsNullOrEmpty(xmlNamespaceVariable.Value)) - { - var variant = opcContext.JsonDecodeVariant(xmlNamespaceVariable.Value); - var namespaceUri = variant.Value as string; - if (!string.IsNullOrEmpty(namespaceUri)) - { - this._model.NodeSet.XmlSchemaUri = namespaceUri; - } - } - } - } - } - - internal static void InitializeDataTypeInfo(VariableModel _model, IOpcUaContext opcContext, BaseVariableState variableNode, int recursionDepth) - { - VariableTypeModelFactoryOpc.InitializeDataTypeInfo(_model, opcContext, $"{variableNode.GetType()} {variableNode}", variableNode.DataType, variableNode.ValueRank, variableNode.ArrayDimensions, variableNode.WrappedValue, recursionDepth); - } - } - - public class DataVariableModelFactoryOpc : VariableModelFactoryOpc - { - } - - public class PropertyModelFactoryOpc : VariableModelFactoryOpc - { - } - - public class MethodModelFactoryOpc : InstanceModelFactoryOpc // TODO determine if intermediate base classes of MethodState are worth exposing in the model - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - if (opcNode is MethodState methodState) - { - var references = opcContext.GetHierarchyReferences(methodState); - foreach (var reference in references.Where(r => r.ReferenceTypeId == ReferenceTypeIds.HasProperty)) - { - var referencedNode = opcContext.GetNode(reference.TargetId); - if (referencedNode?.BrowseName == "InputArguments" || referencedNode?.BrowseName == "OutputArguments") - { - if (referencedNode is PropertyState argumentProp && argumentProp.Value is ExtensionObject[] arguments) - { - var argumentInfo = new PropertyState(methodState) - { - NodeId = argumentProp.NodeId, - TypeDefinitionId = argumentProp.TypeDefinitionId, - ModellingRuleId = argumentProp.ModellingRuleId, - DataType = argumentProp.DataType, - }; - argumentInfo.Value = new Argument[arguments.Length]; - for (int arg = 0; arg < arguments.Length; arg++) - { - argumentInfo.Value[arg] = arguments[arg].Body as Argument; - } - if (referencedNode?.BrowseName == "InputArguments") - { - methodState.InputArguments = argumentInfo; - } - else - { - methodState.OutputArguments = argumentInfo; - } - } - } - } - - //_model.MethodDeclarationId = opcContext.GetNodeIdWithUri(methodState.MethodDeclarationId, out var _); - var inputArgsModelBrowseName = opcContext.GetModelBrowseName(BrowseNames.InputArguments); - var inputArgs = _model.Properties.FirstOrDefault(p => p.BrowseName == inputArgsModelBrowseName); - if (inputArgs != null) - { - _model.InputArguments = new List(); - ProcessMethodArguments(_model, BrowseNames.InputArguments, inputArgs, _model.InputArguments, opcContext, recursionDepth); - } - var outputArgsModelBrowseName = opcContext.GetModelBrowseName(BrowseNames.OutputArguments); - var outputArgs = _model.Properties.FirstOrDefault(p => p.BrowseName == outputArgsModelBrowseName); - if (outputArgs != null) - { - _model.OutputArguments = new List(); - ProcessMethodArguments(_model, BrowseNames.OutputArguments, outputArgs, _model.OutputArguments, opcContext, recursionDepth); - } - } - else - { - throw new Exception($"Unexpected node type for method {opcNode}"); - } - } - - private void ProcessMethodArguments(MethodModel methodModel, string browseName, VariableModel argumentVariable, List modelArguments, IOpcUaContext opcContext, int recursionDepth) - { - var arguments = opcContext.JsonDecodeVariant(argumentVariable.Value, argumentVariable.DataType); // TODO get from opcContext! - if (arguments.Value != null) - { - foreach (var argObj in arguments.Value as Array) - { - var arg = (argObj as ExtensionObject)?.Body as Argument; - - var dataTypeStateObj = opcContext.GetNode(arg.DataType); - if (dataTypeStateObj is DataTypeState dataTypeState) - { - var dataType = Create(opcContext, dataTypeState, null, recursionDepth); - - var argumentDescription = _model.OtherReferencedNodes - .FirstOrDefault(nr => nr.Node.GetUnqualifiedBrowseName() == arg.Name - && ((nr.ReferenceType as ReferenceTypeModel).HasBaseType($"{Namespaces.OpcUa};{ReferenceTypeIds.HasArgumentDescription}") - || (nr.ReferenceType as ReferenceTypeModel).HasBaseType($"{Namespaces.OpcUa};{ReferenceTypeIds.HasOptionalInputArgumentDescription}")) - ); - var argumentModel = argumentDescription?.Node as VariableModel; - if (argumentModel == null) - { - // No description: create an argument variable - argumentModel = new VariableModel - { - DisplayName = new List { new NodeModel.LocalizedText { Text = arg.Name } }, - BrowseName = arg.Name, - Description = arg.Description?.ToModel(), - NodeSet = argumentVariable.NodeSet, - NodeId = argumentVariable.NodeId, - CustomState = argumentVariable.CustomState, - }; - VariableTypeModelFactoryOpc.InitializeDataTypeInfo(argumentModel, opcContext, $"Method {_model} Argument {arg.Name}", arg.DataType, arg.ValueRank, new ReadOnlyList(arg.ArrayDimensions, false), new Variant(arg.Value), recursionDepth); - } - else - { - // TODO validate variable against argument property - if ((argumentDescription.ReferenceType as ReferenceTypeModel).HasBaseType($"{Namespaces.OpcUa};{ReferenceTypeIds.HasOptionalInputArgumentDescription}")) - { - argumentModel.ModellingRule = "Optional"; - } - else - { - argumentModel.ModellingRule = "Mandatory"; - } - } - modelArguments.Add(argumentModel); - } - else - { - throw new Exception($"Invalid data type {arg.DataType} for argument {arg.Name} in method {_model.NodeId}."); - } - } - } - - //if (argumentVariable.OtherReferencedNodes?.Any() != true && argumentVariable.OtherReferencingNodes?.Any() != true) - //{ - // var argumentProperty = NodeModelOpcExtensions.GetArgumentProperty(methodModel, browseName, modelArguments, opcContext); - //} - //else - //{ - - //} - } - } - - public class VariableTypeModelFactoryOpc : BaseTypeModelFactoryOpc - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - var variableTypeState = opcNode as BaseVariableTypeState; - InitializeDataTypeInfo(_model, opcContext, variableTypeState, recursionDepth); - //variableTypeState.ValueRank - //variableTypeState.Value - //variableTypeState.ArrayDimensions - //_model. - } - - internal static void InitializeDataTypeInfo(VariableTypeModel model, IOpcUaContext opcContext, BaseVariableTypeState variableTypeNode, int recursionDepth) - { - VariableTypeModelFactoryOpc.InitializeDataTypeInfo(model, opcContext, $"{variableTypeNode.GetType()} {variableTypeNode}", variableTypeNode.DataType, variableTypeNode.ValueRank, variableTypeNode.ArrayDimensions, variableTypeNode.WrappedValue, recursionDepth); - } - - internal static void InitializeDataTypeInfo(IVariableDataTypeInfo model, IOpcUaContext opcContext, string variableNodeDiagInfo, NodeId dataTypeNodeId, int valueRank, ReadOnlyList arrayDimensions, Variant wrappedValue, int recursionDepth) - { - var dataType = opcContext.GetNode(dataTypeNodeId); - if (dataType is DataTypeState) - { - model.DataType = Create(opcContext, dataType as DataTypeState, null, recursionDepth); - } - else - { - if (dataType == null) - { - throw new Exception($"{variableNodeDiagInfo}: did not find data type {dataTypeNodeId} (Namespace {opcContext.NamespaceUris.GetString(dataTypeNodeId.NamespaceIndex)})."); - } - else - { - throw new Exception($"{variableNodeDiagInfo}: Unexpected node state {dataTypeNodeId}/{dataType?.GetType().FullName}."); - } - } - if (valueRank != -1) - { - model.ValueRank = valueRank; - if (arrayDimensions != null && arrayDimensions.Any()) - { - model.ArrayDimensions = String.Join(",", arrayDimensions); - } - } - if (wrappedValue.Value != null) - { - var encodedValue = opcContext.JsonEncodeVariant(wrappedValue, model.DataType); - model.Value = encodedValue.Json; - } - } - - } - public class DataTypeModelFactoryOpc : BaseTypeModelFactoryOpc - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - - var dataTypeState = opcNode as DataTypeState; - if (dataTypeState.DataTypeDefinition?.Body != null) - { - var sd = dataTypeState.DataTypeDefinition.Body as StructureDefinition; - if (sd != null) - { - _model.StructureFields = new List(); - int order = 0; - // The OPC SDK does not put the SymbolicName into the node state: read from UANodeSet - var uaNodeSet = opcContext.GetUANodeSet(_model.Namespace); - UADataType uaStruct = null; - if (uaNodeSet != null) - { - var opcNodeIdStr = opcNode.NodeId.ToString(); - uaStruct = uaNodeSet.Items.FirstOrDefault(n => n.NodeId == opcNodeIdStr) as UADataType; - } - - foreach (var field in sd.Fields) - { - var dataType = opcContext.GetNode(field.DataType); - if (dataType is DataTypeState) - { - var dataTypeModel = Create(opcContext, dataType as DataTypeState, null, recursionDepth); - if (dataTypeModel == null) - { - throw new Exception($"Unable to resolve data type {dataType.DisplayName}"); - } - string symbolicName = null; - if (uaStruct != null) - { - symbolicName = uaStruct?.Definition?.Field?.FirstOrDefault(f => f.Name == field.Name)?.SymbolicName; - } - var structureField = new DataTypeModel.StructureField - { - Name = field.Name, - SymbolicName = symbolicName, - DataType = dataTypeModel, - ValueRank = field.ValueRank != -1 ? field.ValueRank : null, - ArrayDimensions = field.ArrayDimensions != null && field.ArrayDimensions.Any() ? String.Join(",", field.ArrayDimensions) : null, - MaxStringLength = field.MaxStringLength != 0 ? field.MaxStringLength : null, - Description = field.Description.ToModel(), - IsOptional = field.IsOptional && sd.StructureType == StructureType.StructureWithOptionalFields, - AllowSubTypes = field.IsOptional && (sd.StructureType == StructureType.StructureWithSubtypedValues || sd.StructureType == StructureType.UnionWithSubtypedValues), - FieldOrder = order++, - }; - _model.StructureFields.Add(structureField); - } - else - { - if (dataType == null) - { - throw new Exception($"Unable to find node state for data type {field.DataType} in {opcNode}"); - } - throw new Exception($"Unexpected node state {dataType?.GetType()?.FullName} for data type {field.DataType} in {opcNode}"); - } - } - } - else - { - var enumFields = dataTypeState.DataTypeDefinition.Body as EnumDefinition; - if (enumFields != null) - { - _model.IsOptionSet = enumFields.IsOptionSet || _model.HasBaseType(opcContext.GetModelNodeId(DataTypeIds.OptionSet)); - _model.EnumFields = new List(); - - // The OPC SDK does not put the SymbolicName into the node state: read from UANodeSet - var uaNodeSet = opcContext.GetUANodeSet(_model.Namespace); - UADataType uaEnum = null; - if (uaNodeSet != null) - { - uaEnum = uaNodeSet.Items.FirstOrDefault(n => n.NodeId == opcNode.NodeId) as UADataType; - } - foreach (var field in enumFields.Fields) - { - string symbolicName = null; - if (uaEnum != null) - { - symbolicName = uaEnum?.Definition?.Field?.FirstOrDefault(f => f.Name == field.Name)?.SymbolicName; - } - var enumField = new DataTypeModel.UaEnumField - { - Name = field.Name, - DisplayName = field.DisplayName.ToModel(), - Value = field.Value, - Description = field.Description.ToModel(), - SymbolicName = symbolicName, - }; - _model.EnumFields.Add(enumField); - } - } - else - { - throw new Exception($"Unknown data type definition in {dataTypeState}"); - } - } - } - } - } - - public class ReferenceTypeModelFactoryOpc : BaseTypeModelFactoryOpc - { - protected override void Initialize(IOpcUaContext opcContext, NodeState opcNode, int recursionDepth) - { - base.Initialize(opcContext, opcNode, recursionDepth); - var referenceTypeState = opcNode as ReferenceTypeState; - - _model.InverseName = referenceTypeState.InverseName?.ToModel(); - _model.Symmetric = referenceTypeState.Symmetric; - } - } -} - -namespace CESMII.OpcUa.NodeSetModel -{ - - public static class LocalizedTextExtension - { - public static NodeModel.LocalizedText ToModelSingle(this ua.LocalizedText text) => text != null ? new NodeModel.LocalizedText { Text = text.Text, Locale = text.Locale } : null; - public static List ToModel(this ua.LocalizedText text) => text != null ? new List { text.ToModelSingle() } : new List(); - public static List ToModel(this IEnumerable texts) => texts?.Select(text => text.ToModelSingle()).Where(lt => lt != null).ToList(); - } -} diff --git a/CESMII.OpcUa.NodeSetModel.Factory.Opc/ReferenceComparer.cs b/CESMII.OpcUa.NodeSetModel.Factory.Opc/ReferenceComparer.cs deleted file mode 100644 index 31bd119e..00000000 --- a/CESMII.OpcUa.NodeSetModel.Factory.Opc/ReferenceComparer.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Opc.Ua.Export; -using System.Collections.Generic; - -namespace CESMII.OpcUa.NodeSetModel.Export.Opc -{ - internal class ReferenceComparer : IEqualityComparer - { - public bool Equals(Reference r1, Reference r2) - { - return r1.IsForward == r2.IsForward - && r1.Value == r2.Value - && r1.ReferenceType == r2.ReferenceType; - } - - public int GetHashCode(Reference r) - { - unchecked - { - int hash = 17; - hash = hash * 23 + r.IsForward.GetHashCode(); - hash = hash * 23 + r.Value.GetHashCode(); - hash = hash * 23 + r.ReferenceType.GetHashCode(); - return hash; - } - } - } -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel/CESMII.OpcUa.NodeSetModel.csproj b/CESMII.OpcUa.NodeSetModel/CESMII.OpcUa.NodeSetModel.csproj deleted file mode 100644 index 0430ae0b..00000000 --- a/CESMII.OpcUa.NodeSetModel/CESMII.OpcUa.NodeSetModel.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - netstandard2.0;netstandard2.1 - Debug;Release;Staging - true - cesmii.png - 0.1 - Markus Horstmann - CESMII - - en - OPC UA Node Set Model: provides a fully populated graph of a node set and its dependencies. - Copyright © 2022 CESMII - BSD-3-Clause - Latest - - - - - - - diff --git a/CESMII.OpcUa.NodeSetModel/NodeSetModel.cs b/CESMII.OpcUa.NodeSetModel/NodeSetModel.cs deleted file mode 100644 index 29c20d64..00000000 --- a/CESMII.OpcUa.NodeSetModel/NodeSetModel.cs +++ /dev/null @@ -1,735 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Runtime.Serialization; - -namespace CESMII.OpcUa.NodeSetModel -{ - public class NodeSetModel - { - public string ModelUri { get; set; } - public string Version { get; set; } - public DateTime? PublicationDate { get; set; } - public string XmlSchemaUri { get; set; } - - // RequiredModels - public virtual List RequiredModels { get; set; } = new List(); - // NamespaceUris - // ServerUris - // DefaultAccessRules - - public override string ToString() => $"{ModelUri} {Version} ({PublicationDate})"; - - /// - /// Unique identifier for this nodeset, optionally assigned by the managing application. Not used in the nodeset model classes - /// - public string Identifier { get; set; } - - // For use by the application - public object CustomState { get; set; } - - /// - /// The UA object types defined by this node set - /// - public virtual List ObjectTypes { get; set; } = new List(); - - /// - /// The UA variable types defined by this node set - /// - public virtual List VariableTypes { get; set; } = new List(); - - /// - /// The UA data types defined by this node set - /// - public virtual List DataTypes { get; set; } = new List(); - - /// - /// The UA interfaces defined by this node set - /// - public virtual List Interfaces { get; set; } = new List(); - public virtual List Objects { get; set; } = new List(); - public virtual List Methods { get; set; } = new(); - - public virtual List Properties { get; set; } = new List(); - public virtual List DataVariables { get; set; } = new List(); - - public virtual List UnknownNodes { get; set; } = new List(); - - public virtual List ReferenceTypes { get; set; } = new List(); - - public Dictionary AllNodesByNodeId { get; } = new Dictionary(); - public string HeaderComments { get; set; } - public int? NamespaceIndex { get; set; } - } - public class RequiredModelInfo - { - public string ModelUri { get; set; } - public string Version { get; set; } - public DateTime? PublicationDate { get; set; } - virtual public NodeSetModel AvailableModel { get; set; } - } - - public class NodeModel - { - public virtual List DisplayName { get; set; } - public string BrowseName { get; set; } - public string SymbolicName { get; set; } - public string GetBrowseName() - { - return BrowseName ?? $"{Namespace}:{DisplayName?.FirstOrDefault()?.Text}"; - } - - public virtual List Description { get; set; } - public string Documentation { get; set; } - /// - /// Released, Draft, Deprecated - /// - public string ReleaseStatus { get; set; } - - [IgnoreDataMember] - public string Namespace { get => NodeSet?.ModelUri; } - public string NodeId - { - get - { - if (_namespace != null) - { - if (_namespace == "") - { - return $"nsu={Namespace};{NodeIdIdentifier}"; - } - return $"nsu={_namespace};{NodeIdIdentifier}"; - } - if (NodeSet.NamespaceIndex == 0) - { - return NodeIdIdentifier; - } - return $"ns={NodeSet.NamespaceIndex};{NodeIdIdentifier}"; - } - set - { - var nodeIdParts = value.Split(new[] { ';' }, 2); - if (nodeIdParts.Length > 1) - { - if (nodeIdParts[0].StartsWith("nsu=")) - { - if (this.GetType().Name.EndsWith("ModelProxy")) - { - // For use with EF proxies, we avoid accessing the NodeModel.NodeSet property. Instead save the namespace in a private _namespace variable - _namespace = nodeIdParts[0].Substring("nsu=".Length); - } - else - { - // Indicate that we want to use absolute nodeids - _namespace = ""; - } - } - else if (nodeIdParts[0].StartsWith("ns=")) - { - if (NodeSet?.NamespaceIndex != null) - { - throw new Exception($"Invalid NodeId: node ids must be absolute."); - } - if (nodeIdParts[0].Substring("ns=".Length) != NodeSet?.NamespaceIndex?.ToString(CultureInfo.InvariantCulture)) - { - throw new Exception($"Mismatching namespace index in {value}. Expected {NodeSet.NamespaceIndex}"); - } - _namespace = null; - } - NodeIdIdentifier = nodeIdParts[1]; - } - else - { - NodeIdIdentifier = value; - } - } - } - /// - /// null: use local node ids - /// empty string: use NodeSet.Namespace and absolute nodeids - /// uri: return as absolute nodeid without accessing the NodeSet property - /// - private string _namespace; - - public string NodeIdIdentifier { get; set; } - public object CustomState { get; set; } - public virtual List Categories { get; set; } - - public IEnumerable AllReferencedNodes - { - get - { - var core = NodeSet.RequiredModels?.FirstOrDefault(n => n.ModelUri == "http://opcfoundation.org/UA/")?.AvailableModel; -#pragma warning disable CS0618 // Type or member is obsolete - populating for backwards compat for now - return - this.Properties.Select(p => new NodeAndReference { ReferenceType = core?.ReferenceTypes.FirstOrDefault(r => r.BrowseName.EndsWith("HasProperty")), Node = p }) - .Concat(this.DataVariables.Select(p => new NodeAndReference { ReferenceType = core?.ReferenceTypes.FirstOrDefault(r => r.BrowseName.EndsWith("HasComponent")), Node = p })) - .Concat(this.Objects.Select(p => new NodeAndReference { ReferenceType = core?.ReferenceTypes.FirstOrDefault(r => r.BrowseName.EndsWith("HasComponent")), Node = p })) - .Concat(this.Methods.Select(p => new NodeAndReference { ReferenceType = core?.ReferenceTypes.FirstOrDefault(r => r.BrowseName.EndsWith("HasComponent")), Node = p })) - .Concat(this.Interfaces.Select(p => new NodeAndReference { ReferenceType = core?.ReferenceTypes.FirstOrDefault(r => r.BrowseName.EndsWith("HasInterface")), Node = p })) - .Concat(this.Events.Select(p => new NodeAndReference { ReferenceType = core?.ReferenceTypes.FirstOrDefault(r => r.BrowseName.EndsWith("GeneratesEvent")), Node = p })) - .Concat(this.OtherReferencedNodes) - ; -#pragma warning restore CS0618 // Type or member is obsolete - } - } - - public virtual NodeSetModel NodeSet { get; set; } - - public class LocalizedText - { - public LocalizedText() - { - Text = ""; - } -#nullable enable - public string Text { get => _text; set => _text = value ?? ""; } - private string _text; -#nullable restore - public string Locale { get; set; } - - public static implicit operator LocalizedText(string text) => text == null ? null : new LocalizedText { Text = text }; - public static List ListFromText(string text) => text != null ? new List { new LocalizedText { Text = text } } : new List(); - public override string ToString() => Text; - } - - /// - /// OPC UA: HasProperty references - /// - public virtual List Properties { get; set; } = new List(); // Surprisingly, properties can also be of type DataVariable - need to allow both by using the common base class - - /// - /// OPC UA: HasComponent references (or of derived reference type) to a DataVariable - /// - public virtual List DataVariables { get; set; } = new List(); - - /// - /// OPC UA: HasComponent references (or of derived reference types) to an Object - /// - public virtual List Objects { get; set; } = new List(); - - /// - /// OPC UA: HasInterface references (or of derivce reference types) - /// - public virtual List Interfaces { get; set; } = new List(); - - /// - /// TBD - defer for now - /// OPC UA: HasComponent references (or of derived reference types) to a MethodType - /// - public virtual List Methods { get; set; } = new List(); - /// - /// OPC UA: GeneratesEvent references (or of derived reference types) - /// - public virtual List Events { get; set; } = new List(); - - public class NodeAndReference : IEquatable - { - public virtual NodeModel Node { get; set; } - public virtual NodeModel ReferenceType { get; set; } - - public override bool Equals(object obj) - { - return Equals(obj as NodeAndReference); - } - - public bool Equals(NodeAndReference other) - { - return other is not null && - EqualityComparer.Default.Equals(Node, other.Node) && - EqualityComparer.Default.Equals(ReferenceType, other.ReferenceType); - } - - public override int GetHashCode() - { -#if !NETSTANDARD2_0 - return HashCode.Combine(Node, ReferenceType); -#else - return HashCode.Combine(Node, ReferenceType, ""); -#endif - } - - public static bool operator ==(NodeAndReference left, NodeAndReference right) - { - return EqualityComparer.Default.Equals(left, right); - } - - public static bool operator !=(NodeAndReference left, NodeAndReference right) - { - return !(left == right); - } - public override string ToString() - { - return $"{ReferenceType?.ToString()} {Node}"; - } - } - - public virtual List OtherReferencedNodes { get; set; } = new List(); - public virtual List OtherReferencingNodes { get; set; } = new List(); - - /// - /// Indicates that Properties, DataVariables, OtherReferencedNodes etc. have not been populated. Use to support incremental rendering of the node model graph. - /// - public bool ReferencesNotResolved { get; set; } - - internal virtual bool UpdateIndices(NodeSetModel model, HashSet updatedNodes) - { - if (updatedNodes.Contains(this.NodeId)) - { - // break some recursions - return false; - } - updatedNodes.Add(this.NodeId); - if (model.ModelUri == this.Namespace) - { - model.AllNodesByNodeId.TryAdd(this.NodeId, this); - } - foreach (var node in Objects) - { - if (model.ModelUri == node.Namespace && !model.Objects.Contains(node)) - { - model.Objects.Add(node); - } - node.UpdateIndices(model, updatedNodes); - } - foreach (var node in this.DataVariables) - { - if (model.ModelUri == node.Namespace && !model.DataVariables.Contains(node)) - { - model.DataVariables.Add(node); - } - node.UpdateIndices(model, updatedNodes); - } - foreach (var node in this.Interfaces) - { - if (model.ModelUri == node.Namespace && !model.Interfaces.Contains(node)) - { - model.Interfaces.Add(node); - } - node.UpdateIndices(model, updatedNodes); - } - foreach (var node in this.Methods) - { - if (model.ModelUri == node.Namespace && !model.Methods.Contains(node)) - { - model.Methods.Add(node); - } - node.UpdateIndices(model, updatedNodes); - } - foreach (var node in this.Properties) - { - if (model.ModelUri == node.Namespace && node is PropertyModel prop && !model.Properties.Contains(prop)) - { - model.Properties.Add(prop); - } - node.UpdateIndices(model, updatedNodes); - } - foreach (var node in this.Events) - { - node.UpdateIndices(model, updatedNodes); - } - return true; - } - - public override string ToString() - { - return $"{DisplayName?.FirstOrDefault()} ({Namespace}: {NodeId})"; - } - } - - public abstract class InstanceModelBase : NodeModel - { - /// - /// Values: Optional, Mandatory, MandatoryPlaceholder, OptionalPlaceholder, ExposesItsArray - /// - public string ModellingRule { get; set; } - public virtual NodeModel Parent - { - get => _parent; - set - { - if (_parent != null && _parent != value) - { - // Changing parent or multiple parents on {this}: new parent {value}, previous parent {_parent} - return; - } - _parent = value; - } - } - private NodeModel _parent; - } - public abstract class InstanceModel : InstanceModelBase where TTypeDefinition : NodeModel, new() - { - public virtual TTypeDefinition TypeDefinition { get; set; } - } - - public class ObjectModel : InstanceModel - { - /// - /// 0x0: The Object or View produces no event and has no event history. - /// 0x1: The Object or View produces event notifications. - /// 0x4: The Object has an event history which may be read. - /// 0x8: The Object has an event history which may be updated. - /// - public byte? EventNotifier { get; set; } - /// - /// Not used by the model itself. Captures the many-to-many relationship between NodeModel.Objects and ObjectModel for EF - /// - public virtual List NodesWithObjects { get; set; } = new List(); - } - - public abstract class BaseTypeModel : NodeModel - { - public bool IsAbstract { get; set; } - - public virtual BaseTypeModel SuperType { get; set; } - - [IgnoreDataMember] // This can contain cycle (and is easily recreated from the SubTypeId) - public virtual List SubTypes { get; set; } = new List(); - - public bool HasBaseType(string nodeId) - { - var baseType = this; - do - { - if (baseType?.NodeId == nodeId) - { - return true; - } - baseType = baseType.SuperType; - } - while (baseType != null); - return false; - } - - public void RemoveInheritedAttributes(BaseTypeModel superTypeModel) - { - while (superTypeModel != null) - { - RemoveByBrowseName(Properties, superTypeModel.Properties); - RemoveByBrowseName(DataVariables, superTypeModel.DataVariables); - RemoveByBrowseName(Objects, superTypeModel.Objects); - RemoveByBrowseName(Interfaces, superTypeModel.Interfaces); - foreach (var uaInterface in superTypeModel.Interfaces) - { - RemoveInheritedAttributes(uaInterface); - } - RemoveByBrowseName(Methods, superTypeModel.Methods); - RemoveByBrowseName(Events, superTypeModel.Events); - - superTypeModel = superTypeModel?.SuperType; - } - } - - private void RemoveByBrowseName(List properties, List propertiesToRemove) where T : NodeModel - { - foreach (var property in propertiesToRemove) - { - properties.RemoveAll(p => - p.GetBrowseName() == property.GetBrowseName() - && p.NodeId == property.NodeId - ); - } - } - - internal override bool UpdateIndices(NodeSetModel model, HashSet updatedNodes) - { - var bUpdated = base.UpdateIndices(model, updatedNodes); - if (bUpdated && SuperType != null && !SuperType.SubTypes.Any(sub => sub.NodeId == this.NodeId)) - { - SuperType.SubTypes.Add(this); - } - return bUpdated; - } - - } - - public class ObjectTypeModel : BaseTypeModel - { - /// Not used by the model itself. Captures the many-to-many relationship between NodeModel.Events and ObjectTypeModel for EF - public virtual List NodesWithEvents { get; set; } = new List(); - } - - public class InterfaceModel : ObjectTypeModel - { - /// - /// Not used by the model itself. Captures the many-to-many relationship between NodeModel.Interfaces and InterfaceModel for EF - /// - public virtual List NodesWithInterface { get; set; } = new List(); - } - - public class VariableModel : InstanceModel, IVariableDataTypeInfo - { - public virtual DataTypeModel DataType { get; set; } - /// - /// n > 1: the Value is an array with the specified number of dimensions. - /// OneDimension(1) : The value is an array with one dimension. - /// OneOrMoreDimensions(0): The value is an array with one or more dimensions. - /// Scalar(−1): The value is not an array. - /// Any(−2): The value can be a scalar or an array with any number of dimensions. - /// ScalarOrOneDimension(−3): The value can be a scalar or a one dimensional array. - /// - public int? ValueRank { get; set; } - /// - /// Comma separated list - /// - public string ArrayDimensions { get; set; } - /// - /// Default value of the variable represented as a JSON-encoded Variant, i.e. {\"Value\":{\"Type\":10,\"Body\":0 } - /// - public string Value { get; set; } - - /// - /// Not used by the model itself. Captures the many-to-many relationship between NodeModel.Properties and PropertiesModel for EF - /// - public virtual List NodesWithProperties { get; set; } = new List(); - - // Engineering units: - public class EngineeringUnitInfo - { - /// - /// If only DisplayName is specified, it is assumed to be the DisplayName or the Description of a UNECE unit as specified in https://reference.opcfoundation.org/v104/Core/docs/Part8/5.6.3/, and the referenced http://www.opcfoundation.org/UA/EngineeringUnits/UNECE/UNECE_to_OPCUA.csv - /// - public LocalizedText DisplayName { get; set; } - public LocalizedText Description { get; set; } - public string NamespaceUri { get; set; } - public int? UnitId { get; set; } - } - // Engineering Units - virtual public EngineeringUnitInfo EngineeringUnit { get; set; } - /// - /// NodeId to use for the engineering unit property. A random one can be generated by an exporter if not specified. - /// - public string EngUnitNodeId { get; set; } - public string EngUnitModellingRule { get; set; } - public uint? EngUnitAccessLevel { get; set; } - // EU Range - public double? MinValue { get; set; } - public double? MaxValue { get; set; } - /// - /// NodeId to use for the EURange property. A random one can be generated by an exporter if not specified. - /// - public string EURangeNodeId { get; set; } - public string EURangeModellingRule { get; set; } - public uint? EURangeAccessLevel { get; set; } - // Instrument Range - public double? InstrumentMinValue { get; set; } - public double? InstrumentMaxValue { get; set; } - public string InstrumentRangeNodeId { get; set; } - public string InstrumentRangeModellingRule { get; set; } - public uint? InstrumentRangeAccessLevel { get; set; } - - public long? EnumValue { get; set; } - - public uint? AccessLevel { get; set; } - public ushort? AccessRestrictions { get; set; } - public uint? WriteMask { get; set; } - public uint? UserWriteMask { get; set; } - public double? MinimumSamplingInterval { get; set; } - } - - public class DataVariableModel : VariableModel - { - /// - /// Not used by the model itself. Captures the many-to-many relationship between NodeModel.DataVariables and DataVariableModel for EF - /// - public virtual List NodesWithDataVariables { get; set; } = new List(); - } - - public class PropertyModel : VariableModel - { - } - - public class MethodModel : InstanceModel - { - /// - /// InputArguments are a merged representation of the InputArguments property and any HasArgumentDescription references - /// The NodeId will be NULL if there was no ArgumentDescription - /// - public List InputArguments { get; set; } - public List OutputArguments { get; set; } - - /// - /// Not used by the model itself. Captures the many-to-many relationship between NodeModel.Methods and MethodModel for EF - /// - public virtual List NodesWithMethods { get; set; } = new List(); - } - - public class ReferenceTypeModel : BaseTypeModel - { - /// - /// The inverse name for the reference. - /// - public List InverseName { get; set; } - /// - /// Whether the reference is symmetric. - /// - public bool Symmetric { get; set; } - } - - - public interface IVariableDataTypeInfo - { - DataTypeModel DataType { get; set; } - /// - /// n > 1: the Value is an array with the specified number of dimensions. - /// OneDimension(1) : The value is an array with one dimension. - /// OneOrMoreDimensions(0): The value is an array with one or more dimensions. - /// Scalar(−1): The value is not an array. - /// Any(−2): The value can be a scalar or an array with any number of dimensions. - /// ScalarOrOneDimension(−3): The value can be a scalar or a one dimensional array. - /// - int? ValueRank { get; set; } - /// - /// Comma separated list - /// - string ArrayDimensions { get; set; } - string Value { get; set; } - } - - public class VariableTypeModel : BaseTypeModel, IVariableDataTypeInfo - { - public virtual DataTypeModel DataType { get; set; } - /// - /// n > 1: the Value is an array with the specified number of dimensions. - /// OneDimension(1) : The value is an array with one dimension. - /// OneOrMoreDimensions(0): The value is an array with one or more dimensions. - /// Scalar(−1): The value is not an array. - /// Any(−2): The value can be a scalar or an array with any number of dimensions. - /// ScalarOrOneDimension(−3): The value can be a scalar or a one dimensional array. - /// - public int? ValueRank { get; set; } - /// - /// Comma separated list - /// - public string ArrayDimensions { get; set; } - public string Value { get; set; } - } - - public class DataTypeModel : BaseTypeModel - { - public virtual List StructureFields { get; set; } - public virtual List EnumFields { get; set; } - public bool? IsOptionSet { get; set; } - - public class StructureField - { - public string Name { get; set; } - public string SymbolicName { get; set; } - public virtual BaseTypeModel DataType { get; set; } - /// - /// n > 1: the Value is an array with the specified number of dimensions. - /// OneDimension(1) : The value is an array with one dimension. - /// OneOrMoreDimensions(0): The value is an array with one or more dimensions. - /// Scalar(−1): The value is not an array. - /// Any(−2): The value can be a scalar or an array with any number of dimensions. - /// ScalarOrOneDimension(−3): The value can be a scalar or a one dimensional array. - /// - public int? ValueRank { get; set; } - /// - /// Comma separated list - /// - public string ArrayDimensions { get; set; } - public uint? MaxStringLength { get; set; } - public virtual List Description { get; set; } - public bool IsOptional { get; set; } - public bool AllowSubTypes { get; set; } - /// - /// Used to preserve field order if stored in a relational database (via EF etc.) - /// - public int FieldOrder { get; set; } - - public StructureField() { } - public StructureField(StructureField field) - { - this.Name = field.Name; - this.SymbolicName = field.SymbolicName; - this.DataType = field.DataType; - this.ValueRank = field.ValueRank; - this.ArrayDimensions = field.ArrayDimensions; - this.MaxStringLength = field.MaxStringLength; - this.Description = field.Description; - this.IsOptional = field.IsOptional; - this.AllowSubTypes = field.AllowSubTypes; - this.FieldOrder = field.FieldOrder; - } - - public override string ToString() => $"{Name}: {DataType} {(IsOptional ? "Optional" : "")}"; - } - - public class StructureFieldWithOwner : StructureField - { - public StructureFieldWithOwner(StructureField field, DataTypeModel owner) : base(field) - { - Owner = owner; - } - public DataTypeModel Owner { get; set; } - } - - public class UaEnumField - { - public string Name { get; set; } - public string SymbolicName { get; set; } - public virtual List DisplayName { get; set; } - public virtual List Description { get; set; } - public long Value { get; set; } - - public override string ToString() => $"{Name} = {Value}"; - } - - internal override bool UpdateIndices(NodeSetModel model, HashSet updatedNodes) - { - var bUpdated = base.UpdateIndices(model, updatedNodes); - if (bUpdated && StructureFields?.Any() == true) - { - foreach (var field in StructureFields) - { - field.DataType?.UpdateIndices(model, updatedNodes); - } - } - return bUpdated; - } - - public List GetStructureFieldsInherited() - { - var structureFields = new List(); - - List baseTypesWithFields = new(); - var currentType = this; - while (currentType != null) - { - if (currentType.StructureFields?.Any() == true) - { - baseTypesWithFields.Add(currentType); - } - currentType = currentType.SuperType as DataTypeModel; - } - if (baseTypesWithFields.Count == 1) - { - structureFields = baseTypesWithFields[0].StructureFields.Select(sf => new StructureFieldWithOwner(sf, baseTypesWithFields[0])).ToList(); - } - else - { - foreach (var baseType in baseTypesWithFields) - { - foreach (var field in baseType.StructureFields) - { - var fieldWithOwner = new StructureFieldWithOwner(field, baseType); - var existingFieldIndex = structureFields.FindIndex(f => f.Name == field.Name); - if (existingFieldIndex >= 0) - { - structureFields[existingFieldIndex] = fieldWithOwner; - } - else - { - structureFields.Add(fieldWithOwner); - } - } - } - } - return structureFields; - } - } - -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel/NodeSetModelExtensions.cs b/CESMII.OpcUa.NodeSetModel/NodeSetModelExtensions.cs deleted file mode 100644 index 8db65707..00000000 --- a/CESMII.OpcUa.NodeSetModel/NodeSetModelExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace CESMII.OpcUa.NodeSetModel -{ - public static class NodeSetModelExtensions - { - public static IEnumerable EnumerateAllNodes(this NodeSetModel _this) - { - var allNodes = _this.DataTypes - .Concat(_this.VariableTypes) - .Concat(_this.Interfaces) - .Concat(_this.ObjectTypes) - .Concat(_this.Properties) - .Concat(_this.DataVariables) - .Concat(_this.Objects) - .Concat(_this.Methods) - .Concat(_this.ReferenceTypes) - .Concat(_this.UnknownNodes) - ; - return allNodes; - } - public static void UpdateAllNodes(this NodeSetModel _this) - { - _this.AllNodesByNodeId.Clear(); - foreach(var node in EnumerateAllNodes(_this)) - { - _this.AllNodesByNodeId.TryAdd(node.NodeId, node); - - } - } - /// - /// Ensures that all indices in the model are consistent, including - /// - SuperType/SubType collections - /// - Properties, DataVariables, Objects etc. collections - /// - /// NodeSetModel to update. - public static void UpdateIndices(this NodeSetModel _this) - { - _this.AllNodesByNodeId.Clear(); - var updatedNodes = new HashSet(); - foreach(var node in EnumerateAllNodes(_this)) - { - node.UpdateIndices(_this, updatedNodes); - } - } - } -#if NETSTANDARD2_0 - public static class DictionaryExtensions - { - public static bool TryAdd(this Dictionary dict, TKey key, TValue value) - { - if (dict.ContainsKey(key)) return false; - dict.Add(key, value); - return true; - } - } - - internal class HashCode - { - public static int Combine(T1 o1, T2 o2, T3 o3) - { - return (o1.GetHashCode() ^ o2.GetHashCode() ^ o3.GetHashCode()); - } - } - -#endif -} \ No newline at end of file diff --git a/CESMII.OpcUa.NodeSetModel/NodeSetModelVersioning.cs b/CESMII.OpcUa.NodeSetModel/NodeSetModelVersioning.cs deleted file mode 100644 index 598fdb4f..00000000 --- a/CESMII.OpcUa.NodeSetModel/NodeSetModelVersioning.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace CESMII.OpcUa.NodeSetModel -{ - public static class NodeSetVersionUtils - { - public static NodeSetModel GetMatchingOrHigherNodeSet(IEnumerable nodeSetsWithSameNamespaceUri, DateTime? publicationDate, string version) - { - if (nodeSetsWithSameNamespaceUri.FirstOrDefault()?.ModelUri == "http://opcfoundation.org/UA/") - { - // Special versioning rules for core nodesets: only match publication date within version family (1.03, 1.04, 1.05). - var prefixLength = "0.00".Length; - string versionPrefix; - NodeSetModel matchingNodeSet = null; - if (version?.Length >= prefixLength) - { - versionPrefix = version.Substring(0, prefixLength); - var nodeSetsInVersionFamily = nodeSetsWithSameNamespaceUri - .Where(n => string.Compare(n.Version.Substring(0, prefixLength), versionPrefix) == 0); - matchingNodeSet = GetMatchingOrHigherNodeSetByPublicationDate(nodeSetsInVersionFamily, publicationDate); - } - else - { - versionPrefix = null; - } - - if (matchingNodeSet == null) - { - // no match within version family or no version requested: return the highest available from higher version family - matchingNodeSet = nodeSetsWithSameNamespaceUri - .Where(n => versionPrefix == null || string.Compare(n.Version.Substring(0, prefixLength), versionPrefix) > 0) - .OrderByDescending(n => n.Version.Substring(0, prefixLength)) - .ThenByDescending(n => n.PublicationDate) - .FirstOrDefault(); - } - return matchingNodeSet; - } - else - { - return GetMatchingOrHigherNodeSetByPublicationDate(nodeSetsWithSameNamespaceUri, publicationDate); - } - } - public static bool? IsMatchingOrHigherNodeSet(string modelUri, DateTime? modelPublicationDate, string modelVersion, DateTime? publicationDateToMatch, string versionToMatch) - { - return CompareNodeSetVersion(modelUri, modelPublicationDate, modelVersion, publicationDateToMatch, versionToMatch) >= 0; - } - public static int? CompareNodeSetVersion(string modelUri, DateTime? modelPublicationDate, string modelVersion, DateTime? publicationDateToMatch, string versionToMatch) - { - if (modelUri == "http://opcfoundation.org/UA/") - { - // Special versioning rules for core nodesets: only match publication date within version family (1.03, 1.04, 1.05). - if (string.IsNullOrEmpty(versionToMatch)) - { - // No version specified: it's a match - return 1; - } - var prefixLength = "0.00".Length; - if (versionToMatch?.Length < prefixLength) - { - // Invalid version '{versionToMatch}' for OPC UA Core nodeset - return null; - } - if (modelVersion == null || modelVersion.Length < prefixLength) - { - // Invalid version '{modelVersion}' in OPC UA Core nodeset - return null; - } - var versionPrefixToMatch = versionToMatch.Substring(0, prefixLength); - var prefixComparison = string.CompareOrdinal(modelVersion.Substring(0, prefixLength), versionPrefixToMatch); - if (prefixComparison != 0) - { - return prefixComparison; - } - // Version family matches: now just do regular publication date comparison - } - int comparison; - if (publicationDateToMatch == null || modelPublicationDate == null) - { - // If either date is not specified it matches any date - comparison = 0; - } - else - { - comparison = DateTime.Compare(modelPublicationDate.Value, publicationDateToMatch.Value); - } - return comparison; - } - - private static NodeSetModel GetMatchingOrHigherNodeSetByPublicationDate(IEnumerable nodeSetsWithSameNamespaceUri, DateTime? publicationDate) - { - var orderedNodeSets = nodeSetsWithSameNamespaceUri.OrderBy(n => n.PublicationDate); - - if (publicationDate != null && publicationDate.Value != default) - { - var matchingNodeSet = orderedNodeSets - .FirstOrDefault(nsm => nsm.PublicationDate >= publicationDate); - return matchingNodeSet; - } - else - { - var matchingNodeSet = orderedNodeSets - .LastOrDefault(); - return matchingNodeSet; - } - } - - } -} \ No newline at end of file diff --git a/CloudLibSync/CloudLibSync.csproj b/CloudLibSync/CloudLibSync.csproj index 5c6e3d13..b629b7dd 100644 --- a/CloudLibSync/CloudLibSync.csproj +++ b/CloudLibSync/CloudLibSync.csproj @@ -2,15 +2,15 @@ Exe - net6.0 + net8.0 enable enable - - + + @@ -20,7 +20,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/CloudLibSync/Program.cs b/CloudLibSync/Program.cs index 5ad370d0..9f21ad7e 100644 --- a/CloudLibSync/Program.cs +++ b/CloudLibSync/Program.cs @@ -66,7 +66,7 @@ public bool IsEnabled(LogLevel logLevel) return true; } - public IDisposable BeginScope(TState state) + public IDisposable? BeginScope(TState state) where TState : notnull { return new MemoryStream(); } diff --git a/CloudLibSyncAzureFunction/CloudLibSyncAzureFunction.csproj b/CloudLibSyncAzureFunction/CloudLibSyncAzureFunction.csproj index 8e5bdaa3..f6e88327 100644 --- a/CloudLibSyncAzureFunction/CloudLibSyncAzureFunction.csproj +++ b/CloudLibSyncAzureFunction/CloudLibSyncAzureFunction.csproj @@ -1,12 +1,12 @@ - + - net6.0 + net8.0 v4 - + - + @@ -25,6 +25,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Opc.Ua.CloudLib.Client/Opc.Ua.Cloud.Library.Client.csproj b/Opc.Ua.CloudLib.Client/Opc.Ua.Cloud.Library.Client.csproj index 9bdc8bc1..22d791c4 100644 --- a/Opc.Ua.CloudLib.Client/Opc.Ua.Cloud.Library.Client.csproj +++ b/Opc.Ua.CloudLib.Client/Opc.Ua.Cloud.Library.Client.csproj @@ -3,7 +3,7 @@ Opc.Ua.Cloud.Library.Client OPCFoundation.NetStandard.Opc.Ua.Cloud.Library.Client - net6.0;netstandard2.0 + net8.0;netstandard2.0 Opc.Ua.Cloud.Library.Client OPC UA Cloud Library Client Class Library true @@ -29,9 +29,9 @@ - - - + + + @@ -41,13 +41,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - 6.0.31 + 6.0.33 diff --git a/Opc.Ua.CloudLib.Client/UACloudLibClient.cs b/Opc.Ua.CloudLib.Client/UACloudLibClient.cs index 0f6574fe..9f19984c 100644 --- a/Opc.Ua.CloudLib.Client/UACloudLibClient.cs +++ b/Opc.Ua.CloudLib.Client/UACloudLibClient.cs @@ -175,12 +175,12 @@ private async Task SendAndConvertAsync(GraphQLRequest request) { if (_forceRestTestHook) { - throw new GraphQlNotSupportedException("Failing graphql query to force REST fallback"); + throw new NotSupportedException("Failing graphql query to force REST fallback"); } GraphQLResponse response = await _client.SendQueryAsync(request).ConfigureAwait(false); if (response == null) { - throw new GraphQlException("Internal error: null response."); + throw new Exception("Internal error: null response."); } if (response.Errors?.Length > 0) { @@ -189,7 +189,7 @@ private async Task SendAndConvertAsync(GraphQLRequest request) { message = messageObj?.ToString(); } - throw new GraphQlException(message); + throw new Exception(message); } string dataJson = response.Data?.First?.First?.ToString(); @@ -534,7 +534,7 @@ public async Task> GetNodeSetsAsync(string identifier = n #endif { Console.WriteLine("Error: " + ex.Message + " Cloud Library does not support GraphQL."); - throw new GraphQlNotSupportedException("Cloud Library does not support GraphQL.", ex); + throw new NotSupportedException("Cloud Library does not support GraphQL.", ex); } } @@ -615,7 +615,7 @@ IQuery AddRequiredModelFields(IQuery query) } /// - /// + /// /// /// /// @@ -629,7 +629,7 @@ IQuery AddRequiredModelFields(IQuery query) /// /// /// - /// + /// public async Task> GetNodeSetsPendingApprovalAsync(string namespaceUri = null, DateTime? publicationDate = null, UAProperty additionalProperty = null, string after = null, int? first = null, int? last = null, string before = null, bool noMetadata = false, bool noTotalCount = false, bool noRequiredModels = false, bool noCreationTime = true) { @@ -833,7 +833,7 @@ query MyQuery ({variableParams}$after: String, $first: Int, $before: String, $la #endif { Console.WriteLine("Error: " + ex.Message + " Cloud Library does not support GraphQL."); - throw new GraphQlNotSupportedException("Cloud Library does not support GraphQL.", ex); + throw new NotSupportedException("Cloud Library does not support GraphQL.", ex); } } /// @@ -844,7 +844,7 @@ query MyQuery ({variableParams}$after: String, $first: Int, $before: String, $la /// Optional comment to explain the status, especially REJECTED /// Additional properties to be set or removed on the approved nodeset. Value = null or empty string removes the property. /// The approved namespace metadata if update succeeded. NULL or exception if failed. - /// + /// public async Task UpdateApprovalStatusAsync(string nodeSetId, string newStatus, string statusInfo, UAProperty additionalProperty) { var request = new GraphQLRequest(); @@ -899,7 +899,7 @@ mutation ApprovalMutation ($newStatus: ApprovalStatus!, $identifier: String, $ap #endif { Console.WriteLine("Error: " + ex.Message + " Cloud Library does not support GraphQL."); - throw new GraphQlNotSupportedException("Cloud Library does not support GraphQL.", ex); + throw new NotSupportedException("Cloud Library does not support GraphQL.", ex); } } @@ -1102,79 +1102,4 @@ private void UserDataChanged() _client.HttpClient.DefaultRequestHeaders.Authorization = Authentication; } } - - /// - /// UA Cloud Lib client exception with GraphQl query - /// - [Serializable] - public class GraphQlException : Exception - { - /// - /// - /// - public GraphQlException() - { - } - - /// - /// - /// - /// - public GraphQlException(string message) : base(message) - { - } - /// - /// - /// - /// - /// - public GraphQlException(string message, Exception innerException) : base(message, innerException) - { - } - /// - /// - /// - /// - /// - protected GraphQlException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) - { - } - } - - /// - /// Cloud Library does not support GraphQl - /// - [Serializable] - public class GraphQlNotSupportedException : Exception - { - /// - /// - /// - public GraphQlNotSupportedException() - { - } - /// - /// - /// - /// - public GraphQlNotSupportedException(string message) : base(message) - { - } - /// - /// - /// - /// - /// - public GraphQlNotSupportedException(string message, Exception innerException) : base(message, innerException) - { - } - /// - /// - /// - /// - /// - protected GraphQlNotSupportedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) - { - } - } } diff --git a/SampleConsoleClient/SampleConsoleClient.csproj b/SampleConsoleClient/SampleConsoleClient.csproj index aaa5ee6a..760b1767 100644 --- a/SampleConsoleClient/SampleConsoleClient.csproj +++ b/SampleConsoleClient/SampleConsoleClient.csproj @@ -2,14 +2,14 @@ Exe - net6.0 + net8.0 - - - - + + + + @@ -21,7 +21,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Tests/CloudLibClientTests/CloudLibClient.Tests.csproj b/Tests/CloudLibClientTests/CloudLibClient.Tests.csproj index cec98a55..3eda7506 100644 --- a/Tests/CloudLibClientTests/CloudLibClient.Tests.csproj +++ b/Tests/CloudLibClientTests/CloudLibClient.Tests.csproj @@ -9,14 +9,14 @@ - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -38,7 +38,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Tests/CloudLibClientTests/CloudLibIntegrationTest.cs b/Tests/CloudLibClientTests/CloudLibIntegrationTest.cs index 32a7cb7b..c3e1171d 100644 --- a/Tests/CloudLibClientTests/CloudLibIntegrationTest.cs +++ b/Tests/CloudLibClientTests/CloudLibIntegrationTest.cs @@ -32,7 +32,7 @@ public async Task Search(string[] keywords, int expectedCount) { var apiClient = _factory.CreateCloudLibClient(); - var nodeSets = await PagedVsNonPagedAsync(apiClient, keywords: keywords, after: null, first: 100).ConfigureAwait(false); + var nodeSets = await PagedVsNonPagedAsync(apiClient, keywords: keywords, after: null, first: 100).ConfigureAwait(true); output.WriteLine($"{nodeSets.Count}"); // Ignore namespace versions for now: the only duplicate version is the test namespace generated by the QueriesAndDownload.UpdateNodeSet test, which may run before or after this test Assert.Equal(expectedCount, nodeSets.DistinctBy(n => n.NamespaceUri.OriginalString).Count()); @@ -40,10 +40,10 @@ public async Task Search(string[] keywords, int expectedCount) private async Task> PagedVsNonPagedAsync(UACloudLibClient apiClient, string[] keywords, string after, int first) { - var unpagedResult = await apiClient.GetNodeSetsAsync(keywords: keywords, after: after, first: first).ConfigureAwait(false); + var unpagedResult = await apiClient.GetNodeSetsAsync(keywords: keywords, after: after, first: first).ConfigureAwait(true); var unpaged = unpagedResult.Edges.Select(e => e.Node).ToList(); - List paged = await GetAllPaged(apiClient, keywords: keywords, after: after, first: 5).ConfigureAwait(false); + List paged = await GetAllPaged(apiClient, keywords: keywords, after: after, first: 5).ConfigureAwait(true); Assert.True(paged.Count == unpaged.Count); Assert.Equal(unpaged, paged/*.Take(cloud.Count)*/, new NodesetComparer(output)); @@ -60,7 +60,7 @@ private static async Task> GetAllPaged(UACloudLibClient apiClient, string cursor = after; do { - var page = await apiClient.GetNodeSetsAsync(keywords: keywords, after: cursor, first: first).ConfigureAwait(false); + var page = await apiClient.GetNodeSetsAsync(keywords: keywords, after: cursor, first: first).ConfigureAwait(true); Assert.True(page.Edges.Count <= first, "CloudLibAsync returned more profiles than requested"); paged.AddRange(page.Edges.Select(e => e.Node)); if (!page.PageInfo.HasNextPage) diff --git a/Tests/CloudLibClientTests/Integration.cs b/Tests/CloudLibClientTests/Integration.cs index 1f3783e9..4c04120c 100644 --- a/Tests/CloudLibClientTests/Integration.cs +++ b/Tests/CloudLibClientTests/Integration.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Opc.Ua.Cloud.Library; @@ -20,7 +21,7 @@ namespace CloudLibClient.Tests "DeleteCloudLibDBAndStore": false, "IgnoreUploadConflict" : true } - Set DeleteCloudlibDBAndStore to true to wipe the db before every test run + Set DeleteCloudlibDBAndStore to true to wipe the db before every test run */ [Collection("_init0")] public class TestSetup : IClassFixture> @@ -35,7 +36,7 @@ public TestSetup(CustomWebApplicationFactory facto } [Fact] - public void Setup() + public async Task Setup() { if (_factory.TestConfig.DeleteCloudLibDBAndStore && InstantiationCount == 1) { @@ -56,7 +57,7 @@ public void Setup() var storage = scope.ServiceProvider.GetRequiredService(); if (storage is LocalFileStorage localStorage) { - _ = localStorage.DeleteAllFilesAsync().Result; + _ = await localStorage.DeleteAllFilesAsync().ConfigureAwait(true); } } } diff --git a/Tests/CloudLibClientTests/QueriesAndDownload.cs b/Tests/CloudLibClientTests/QueriesAndDownload.cs index e6f2f4b0..ed35b649 100644 --- a/Tests/CloudLibClientTests/QueriesAndDownload.cs +++ b/Tests/CloudLibClientTests/QueriesAndDownload.cs @@ -40,12 +40,12 @@ public async Task GetNodeSetDependencies(bool forceRest) client._allowRestFallback = true; } - var nodeSetInfo = await GetBasicNodeSetInfoForNamespaceAsync(client, strTestNamespaceUri).ConfigureAwait(false); + var nodeSetInfo = await GetBasicNodeSetInfoForNamespaceAsync(client, strTestNamespaceUri).ConfigureAwait(true); Assert.True(nodeSetInfo != null, "Nodeset not found"); var identifier = nodeSetInfo.Id.ToString(CultureInfo.InvariantCulture); - var nodeSetsById = await client.GetNodeSetDependencies(identifier: identifier).ConfigureAwait(false); + var nodeSetsById = await client.GetNodeSetDependencies(identifier: identifier).ConfigureAwait(true); Assert.True(nodeSetsById?.Count == 1); var nodeSet = nodeSetsById[0]; @@ -73,7 +73,7 @@ public async Task GetNodeSetDependencies(bool forceRest) DateTime.SpecifyKind(nodeSetInfo.PublicationDate.Value, DateTimeKind.Utc) : nodeSetInfo.PublicationDate; - List nodeSetsByNamespace = await client.GetNodeSetDependencies(modelUri: namespaceUri, publicationDate: publicationDate).ConfigureAwait(false); + List nodeSetsByNamespace = await client.GetNodeSetDependencies(modelUri: namespaceUri, publicationDate: publicationDate).ConfigureAwait(true); var dependenciesByNamespace = nodeSetsByNamespace .SelectMany(n => n.RequiredModels).Where(r => r != null) @@ -90,7 +90,7 @@ public async Task GetNodeSetDependencies(bool forceRest) Console.WriteLine($"FAIL: returned dependencies are different."); Console.WriteLine($"For identifier {identifier}: {string.Join(" ", dependenciesByIdentifier)}."); Console.WriteLine($"For namespace {namespaceUri} / {publicationDate}: {string.Join(" ", dependenciesByNamespace)}"); - Assert.True(false, "Returned dependencies are different. See log for details."); + Assert.Fail("Returned dependencies are different. See log for details."); } else { @@ -151,11 +151,11 @@ public async Task DownloadNodesetAsync() { var client = _factory.CreateCloudLibClient(); - var nodeSetsResult = await client.GetNodeSetsAsync(modelUri: strTestNamespaceUri).ConfigureAwait(false); + var nodeSetsResult = await client.GetNodeSetsAsync(modelUri: strTestNamespaceUri).ConfigureAwait(true); Assert.True(nodeSetsResult.TotalCount > 0, "Failed to download node set info"); var testNodeSet = nodeSetsResult.Nodes.FirstOrDefault(r => r.NamespaceUri.OriginalString == strTestNamespaceUri); - UANameSpace downloadedNamespace = await client.DownloadNodesetAsync(testNodeSet.Identifier).ConfigureAwait(false); + UANameSpace downloadedNamespace = await client.DownloadNodesetAsync(testNodeSet.Identifier).ConfigureAwait(true); Assert.NotNull(downloadedNamespace); Assert.Equal(downloadedNamespace.Nodeset.NamespaceUri.OriginalString, testNodeSet.NamespaceUri.OriginalString); @@ -218,7 +218,7 @@ public async Task GetBasicNodesetInformationAsync() { var client = _factory.CreateCloudLibClient(); - var basicNodesetInfo = await GetBasicNodeSetInfoForNamespaceAsync(client, strTestNamespaceUri).ConfigureAwait(false); + var basicNodesetInfo = await GetBasicNodeSetInfoForNamespaceAsync(client, strTestNamespaceUri).ConfigureAwait(true); Assert.True(basicNodesetInfo != null, $"Test Nodeset {strTestNamespaceUri} not found"); Assert.True(basicNodesetInfo.Id != 0); @@ -237,7 +237,7 @@ public async Task GetNamespaceIdsAsync() { var client = _factory.CreateCloudLibClient(); - var restResult = await client.GetNamespaceIdsAsync().ConfigureAwait(false); + var restResult = await client.GetNamespaceIdsAsync().ConfigureAwait(true); Assert.True(restResult?.Length > 0, "Failed to download namespace ids"); var testNodeSet = restResult.FirstOrDefault(r => r.NamespaceUri == strTestNamespaceUri); Assert.NotNull(testNodeSet.NamespaceUri); @@ -262,7 +262,7 @@ public async Task GetNodeSetsAsync(bool noMetadata, bool noRequiredModels, bool int? totalCount = null; do { - var result = await client.GetNodeSetsAsync(after: cursor, first: limit, noRequiredModels: noRequiredModels, noMetadata: noMetadata, noTotalCount: noTotalCount, noCreationTime: noCreationTime).ConfigureAwait(false); + var result = await client.GetNodeSetsAsync(after: cursor, first: limit, noRequiredModels: noRequiredModels, noMetadata: noMetadata, noTotalCount: noTotalCount, noCreationTime: noCreationTime).ConfigureAwait(true); Assert.True(cursor == null || result.Edges?.Count > 0, "Failed to get node set information."); testNodeSet = result.Edges.FirstOrDefault(n => n.Node.NamespaceUri.OriginalString == strTestNamespaceUri)?.Node; @@ -346,7 +346,7 @@ public async Task GetNodeSetsFilteredAsync(string[] keywords, int expectedCount) { var client = _factory.CreateCloudLibClient(); - var result = await client.GetNodeSetsAsync(keywords: keywords).ConfigureAwait(false); + var result = await client.GetNodeSetsAsync(keywords: keywords).ConfigureAwait(true); Assert.Equal(expectedCount, result.TotalCount); } @@ -360,7 +360,7 @@ public async Task GetConvertedMetadataAsync(bool forceRest) client._allowRestFallback = true; // GraphQL support was deprecated and is removed now: allow fallback to REST until the client uses new GraphQL mechanisms. #pragma warning disable CS0618 // Type or member is obsolete - List restResult = await client.GetConvertedMetadataAsync().ConfigureAwait(false); + List restResult = await client.GetConvertedMetadataAsync().ConfigureAwait(true); #pragma warning restore CS0618 // Type or member is obsolete Assert.True(restResult?.Count > 0, "Failed to get node set information."); @@ -408,17 +408,17 @@ public async Task UpdateNodeSet(string path, string fileName, bool uploadConflic { var client = _factory.CreateCloudLibClient(); - var expectedNodeSetCount = (await client.GetNodeSetsAsync().ConfigureAwait(false)).TotalCount; + var expectedNodeSetCount = (await client.GetNodeSetsAsync().ConfigureAwait(true)).TotalCount; string uploadedIdentifier = null; var uploadJson = File.ReadAllText(Path.Combine(path, fileName)); var addressSpace = JsonConvert.DeserializeObject(uploadJson); - var response = await client.UploadNodeSetAsync(addressSpace).ConfigureAwait(false); + var response = await client.UploadNodeSetAsync(addressSpace).ConfigureAwait(true); if (response.Status == HttpStatusCode.OK) { output.WriteLine($"Uploaded {addressSpace?.Nodeset.NamespaceUri}, {addressSpace?.Nodeset.Identifier}"); uploadedIdentifier = response.Message; - var approvalResult = await client.UpdateApprovalStatusAsync(uploadedIdentifier, "APPROVED", null, null).ConfigureAwait(false); + var approvalResult = await client.UpdateApprovalStatusAsync(uploadedIdentifier, "APPROVED", null, null).ConfigureAwait(true); Assert.NotNull(approvalResult); Assert.Equal("APPROVED", approvalResult.ApprovalStatus); } @@ -440,7 +440,7 @@ public async Task UpdateNodeSet(string path, string fileName, bool uploadConflic } } // Upload again should cause conflict - response = await client.UploadNodeSetAsync(addressSpace).ConfigureAwait(false); + response = await client.UploadNodeSetAsync(addressSpace).ConfigureAwait(true); Assert.Equal(HttpStatusCode.Conflict, response.Status); GraphQlResult nodeSetInfo; @@ -451,7 +451,7 @@ public async Task UpdateNodeSet(string path, string fileName, bool uploadConflic string requiredIdentifier = null; do { - nodeSetInfo = await client.GetNodeSetsAsync(modelUri: addressSpace.Nodeset.NamespaceUri.OriginalString, publicationDate: addressSpace.Nodeset.PublicationDate).ConfigureAwait(false); + nodeSetInfo = await client.GetNodeSetsAsync(modelUri: addressSpace.Nodeset.NamespaceUri.OriginalString, publicationDate: addressSpace.Nodeset.PublicationDate).ConfigureAwait(true); Assert.NotEmpty(nodeSetInfo.Nodes); var uploadedNode = nodeSetInfo.Nodes.Where(n => n.NamespaceUri.OriginalString == addressSpace.Nodeset.NamespaceUri.OriginalString && n.PublicationDate == addressSpace.Nodeset.PublicationDate).FirstOrDefault(); Assert.Contains(uploadedNode, nodeSetInfo.Nodes); @@ -469,7 +469,7 @@ public async Task UpdateNodeSet(string path, string fileName, bool uploadConflic var requiredUploadJson = File.ReadAllText(Path.Combine(path, dependentNodeSet)); var requiredAddressSpace = JsonConvert.DeserializeObject(requiredUploadJson); - response = await client.UploadNodeSetAsync(requiredAddressSpace).ConfigureAwait(false); + response = await client.UploadNodeSetAsync(requiredAddressSpace).ConfigureAwait(true); Assert.Equal(HttpStatusCode.OK, response.Status); requiredIdentifier = response.Message; @@ -491,21 +491,21 @@ public async Task UpdateNodeSet(string path, string fileName, bool uploadConflic } } } while (notIndexed); - await UploadAndIndex.WaitForIndexAsync(_factory.CreateAuthorizedClient(), expectedNodeSetCount).ConfigureAwait(false); + await UploadAndIndex.WaitForIndexAsync(_factory.CreateAuthorizedClient(), expectedNodeSetCount).ConfigureAwait(true); // Upload with override - response = await client.UploadNodeSetAsync(addressSpace, true).ConfigureAwait(false); + response = await client.UploadNodeSetAsync(addressSpace, true).ConfigureAwait(true); Assert.Equal(HttpStatusCode.OK, response.Status); { uploadedIdentifier = response.Message; - var approvalResult = await client.UpdateApprovalStatusAsync(uploadedIdentifier, "APPROVED", null, null).ConfigureAwait(false); + var approvalResult = await client.UpdateApprovalStatusAsync(uploadedIdentifier, "APPROVED", null, null).ConfigureAwait(true); Assert.NotNull(approvalResult); Assert.Equal("APPROVED", approvalResult.ApprovalStatus); } // Wait for indexing do { - nodeSetInfo = await client.GetNodeSetsAsync(modelUri: addressSpace.Nodeset.NamespaceUri.OriginalString, publicationDate: addressSpace.Nodeset.PublicationDate).ConfigureAwait(false); + nodeSetInfo = await client.GetNodeSetsAsync(modelUri: addressSpace.Nodeset.NamespaceUri.OriginalString, publicationDate: addressSpace.Nodeset.PublicationDate).ConfigureAwait(true); notIndexed = nodeSetInfo.TotalCount == 1 && nodeSetInfo.Edges[0].Node.ValidationStatus != "INDEXED"; if (notIndexed) { @@ -530,7 +530,7 @@ public async Task UpdateNodeSet(string path, string fileName, bool uploadConflic addressSpace.Nodeset.NodesetXml = null; await client.UploadNodeSetAsync(addressSpace, false); - await UploadAndIndex.WaitForIndexAsync(_factory.CreateAuthorizedClient(), expectedNodeSetCount).ConfigureAwait(false); + await UploadAndIndex.WaitForIndexAsync(_factory.CreateAuthorizedClient(), expectedNodeSetCount).ConfigureAwait(true); } } } diff --git a/Tests/CloudLibClientTests/UploadAndIndex.cs b/Tests/CloudLibClientTests/UploadAndIndex.cs index 20be1377..e8b69a1a 100644 --- a/Tests/CloudLibClientTests/UploadAndIndex.cs +++ b/Tests/CloudLibClientTests/UploadAndIndex.cs @@ -36,12 +36,12 @@ public async Task UploadNodeSets(string fileName) var uploadJson = File.ReadAllText(fileName); var addressSpace = JsonConvert.DeserializeObject(uploadJson); - var response = await client.UploadNodeSetAsync(addressSpace).ConfigureAwait(false); + var response = await client.UploadNodeSetAsync(addressSpace).ConfigureAwait(true); if (response.Status == HttpStatusCode.OK) { output.WriteLine($"Uploaded {addressSpace?.Nodeset.NamespaceUri}, {addressSpace?.Nodeset.Identifier}"); var uploadedIdentifier = response.Message; - var approvalResult = await client.UpdateApprovalStatusAsync(uploadedIdentifier, "APPROVED", null, null).ConfigureAwait(false); + var approvalResult = await client.UpdateApprovalStatusAsync(uploadedIdentifier, "APPROVED", null, null).ConfigureAwait(true); Assert.NotNull(approvalResult); Assert.Equal("APPROVED", approvalResult.ApprovalStatus); } @@ -60,7 +60,7 @@ public async Task WaitForIndex() var expectedNodeSetCount = TestNamespaceFiles.GetFiles().Count(); - await WaitForIndexAsync(client, expectedNodeSetCount).ConfigureAwait(false); + await WaitForIndexAsync(client, expectedNodeSetCount).ConfigureAwait(true); } internal static async Task WaitForIndexAsync(HttpClient client, int expectedNodeSetCount) @@ -68,11 +68,11 @@ internal static async Task WaitForIndexAsync(HttpClient client, int expectedNode bool bIndexing; do { - var counts = await GetNodeSetCountsAsync(client).ConfigureAwait(false); + var counts = await GetNodeSetCountsAsync(client).ConfigureAwait(true); bIndexing = counts.All < expectedNodeSetCount || counts.NotIndexed != 0; if (bIndexing) { - await Task.Delay(5000).ConfigureAwait(false); + await Task.Delay(5000).ConfigureAwait(true); } } while (bIndexing); @@ -91,10 +91,10 @@ internal static async Task WaitForIndexAsync(HttpClient client, int expectedNode }" } }); var address = new Uri(client.BaseAddress, "graphql"); - var response2 = await client.SendAsync(new HttpRequestMessage(HttpMethod.Post, address) { Content = new StringContent(queryBodyJson, null, "application/json"), }).ConfigureAwait(false); + var response2 = await client.SendAsync(new HttpRequestMessage(HttpMethod.Post, address) { Content = new StringContent(queryBodyJson, null, "application/json"), }).ConfigureAwait(true); Assert.True(response2.IsSuccessStatusCode, "Failed to read nodeset status"); - var responseString = await response2.Content.ReadAsStringAsync().ConfigureAwait(false); + var responseString = await response2.Content.ReadAsStringAsync().ConfigureAwait(true); Assert.False(string.IsNullOrEmpty(responseString), "null or empty response reading nodeset status."); var parsedJson = JsonConvert.DeserializeObject(responseString); diff --git a/UA-CloudLibrary.sln b/UA-CloudLibrary.sln index ce774b2e..bc073c7e 100644 --- a/UA-CloudLibrary.sln +++ b/UA-CloudLibrary.sln @@ -41,14 +41,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudLibSync", "CloudLibSyn EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudLibSyncAzureFunction", "CloudLibSyncAzureFunction\CloudLibSyncAzureFunction.csproj", "{6A7EF892-71D1-4076-AD10-7F67F276528B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CESMII.OpcUa.NodeSetImporter", "CESMII.OpcUa.NodeSetImporter\CESMII.OpcUa.NodeSetImporter.csproj", "{E5FE6CCC-75BE-4C63-8BA1-3ABAE9892296}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CESMII.OpcUa.NodeSetModel", "CESMII.OpcUa.NodeSetModel\CESMII.OpcUa.NodeSetModel.csproj", "{C7CEAFD9-4F31-46A4-92E1-E56BAEB01B57}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CESMII.OpcUa.NodeSetModel.EF", "CESMII.OpcUa.NodeSetModel.EF\CESMII.OpcUa.NodeSetModel.EF.csproj", "{7B5B7505-7965-4F27-9734-FA325A1A2434}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CESMII.OpcUa.NodeSetModel.Factory.Opc", "CESMII.OpcUa.NodeSetModel.Factory.Opc\CESMII.OpcUa.NodeSetModel.Factory.Opc.csproj", "{14143E99-E321-4E58-AD0A-1562C91CCA9C}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -98,30 +90,6 @@ Global {6A7EF892-71D1-4076-AD10-7F67F276528B}.Release|Any CPU.Build.0 = Release|Any CPU {6A7EF892-71D1-4076-AD10-7F67F276528B}.Staging|Any CPU.ActiveCfg = Release|Any CPU {6A7EF892-71D1-4076-AD10-7F67F276528B}.Staging|Any CPU.Build.0 = Release|Any CPU - {E5FE6CCC-75BE-4C63-8BA1-3ABAE9892296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E5FE6CCC-75BE-4C63-8BA1-3ABAE9892296}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E5FE6CCC-75BE-4C63-8BA1-3ABAE9892296}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E5FE6CCC-75BE-4C63-8BA1-3ABAE9892296}.Release|Any CPU.Build.0 = Release|Any CPU - {E5FE6CCC-75BE-4C63-8BA1-3ABAE9892296}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {E5FE6CCC-75BE-4C63-8BA1-3ABAE9892296}.Staging|Any CPU.Build.0 = Staging|Any CPU - {C7CEAFD9-4F31-46A4-92E1-E56BAEB01B57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C7CEAFD9-4F31-46A4-92E1-E56BAEB01B57}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C7CEAFD9-4F31-46A4-92E1-E56BAEB01B57}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C7CEAFD9-4F31-46A4-92E1-E56BAEB01B57}.Release|Any CPU.Build.0 = Release|Any CPU - {C7CEAFD9-4F31-46A4-92E1-E56BAEB01B57}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {C7CEAFD9-4F31-46A4-92E1-E56BAEB01B57}.Staging|Any CPU.Build.0 = Staging|Any CPU - {7B5B7505-7965-4F27-9734-FA325A1A2434}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7B5B7505-7965-4F27-9734-FA325A1A2434}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7B5B7505-7965-4F27-9734-FA325A1A2434}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7B5B7505-7965-4F27-9734-FA325A1A2434}.Release|Any CPU.Build.0 = Release|Any CPU - {7B5B7505-7965-4F27-9734-FA325A1A2434}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {7B5B7505-7965-4F27-9734-FA325A1A2434}.Staging|Any CPU.Build.0 = Staging|Any CPU - {14143E99-E321-4E58-AD0A-1562C91CCA9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {14143E99-E321-4E58-AD0A-1562C91CCA9C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {14143E99-E321-4E58-AD0A-1562C91CCA9C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {14143E99-E321-4E58-AD0A-1562C91CCA9C}.Release|Any CPU.Build.0 = Release|Any CPU - {14143E99-E321-4E58-AD0A-1562C91CCA9C}.Staging|Any CPU.ActiveCfg = Staging|Any CPU - {14143E99-E321-4E58-AD0A-1562C91CCA9C}.Staging|Any CPU.Build.0 = Staging|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UACloudLibraryServer/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs b/UACloudLibraryServer/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs index 6175ea5d..4cc0a5e3 100644 --- a/UACloudLibraryServer/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs +++ b/UACloudLibraryServer/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; namespace Opc.Ua.Cloud.Library.Areas.Identity.Pages.Account.Manage { @@ -59,7 +60,7 @@ public async Task OnPostAsync() personalData.Add($"Authenticator Key", await _userManager.GetAuthenticatorKeyAsync(user).ConfigureAwait(false)); - Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json"); + _ = Response.Headers.Append(new KeyValuePair("Content-Disposition", "attachment; filename=PersonalData.json")); return new FileContentResult(JsonSerializer.SerializeToUtf8Bytes(personalData), "application/json"); } } diff --git a/UACloudLibraryServer/UA-CloudLibrary.csproj b/UACloudLibraryServer/UA-CloudLibrary.csproj index 6830bc5b..9664b004 100644 --- a/UACloudLibraryServer/UA-CloudLibrary.csproj +++ b/UACloudLibraryServer/UA-CloudLibrary.csproj @@ -36,66 +36,64 @@ - - + + - + + + + + - + - - - - - - + + + + + + - - - - - - - + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - - - + + + - - - + + + - - - - - - - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/UACloudLibraryServer/wwwroot/lib/clipboard-copy-element/package-lock.json b/UACloudLibraryServer/wwwroot/lib/clipboard-copy-element/package-lock.json new file mode 100644 index 00000000..93193ae5 --- /dev/null +++ b/UACloudLibraryServer/wwwroot/lib/clipboard-copy-element/package-lock.json @@ -0,0 +1,9686 @@ +{ + "name": "@github/clipboard-copy-element", + "version": "1.3.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@github/clipboard-copy-element", + "version": "1.3.0", + "license": "MIT", + "devDependencies": { + "@custom-elements-manifest/analyzer": "^0.8.3", + "@github/prettier-config": "^0.0.6", + "@open-wc/testing": "^3.1.8", + "@web/dev-server-esbuild": "^0.4.1", + "@web/test-runner": "^0.16.1", + "@web/test-runner-playwright": "^0.10.0", + "chai": "^4.2.0", + "chromium": "^3.0.3", + "esbuild": "^0.17.19", + "eslint": "^8.42.0", + "eslint-plugin-custom-elements": "^0.0.8", + "eslint-plugin-github": "^4.8.0", + "karma": "^6.3.16", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^3.1.0", + "karma-mocha": "^2.0.1", + "karma-mocha-reporter": "^2.2.5", + "mocha": "^10.1.0", + "rollup": "^1.32.1", + "typescript": "^5.1.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@custom-elements-manifest/analyzer": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.8.4.tgz", + "integrity": "sha512-hibYFNoqPc/xSH9ySuotOllz3UtQnnbG912oC0RtRwHGilnOVT5zeL3Ip26swCjiuFAp8Y0uLN5DwnMpa/xXYQ==", + "dev": true, + "dependencies": { + "@custom-elements-manifest/find-dependencies": "^0.0.5", + "@github/catalyst": "^1.6.0", + "@web/config-loader": "0.1.3", + "chokidar": "3.5.2", + "command-line-args": "5.1.2", + "comment-parser": "1.2.4", + "custom-elements-manifest": "1.0.0", + "debounce": "1.2.1", + "globby": "11.0.4", + "typescript": "~4.3.2" + }, + "bin": { + "cem": "cem.js", + "custom-elements-manifest": "cem.js" + } + }, + "node_modules/@custom-elements-manifest/analyzer/node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@custom-elements-manifest/find-dependencies": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@custom-elements-manifest/find-dependencies/-/find-dependencies-0.0.5.tgz", + "integrity": "sha512-fKIMMZCDFSoL2ySUoz8knWgpV4jpb0lUXgLOvdZQMQFHxgxz1PqOJpUIypwvEVyKk3nEHRY4f10gNol02HjeCg==", + "dev": true, + "dependencies": { + "es-module-lexer": "^0.9.3" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@esm-bundle/chai": { + "version": "4.3.4-fix.0", + "resolved": "https://registry.npmjs.org/@esm-bundle/chai/-/chai-4.3.4-fix.0.tgz", + "integrity": "sha512-26SKdM4uvDWlY8/OOOxSB1AqQWeBosCX3wRYUZO7enTAj03CtVxIiCimYVG2WpULcyV51qapK4qTovwkUr5Mlw==", + "dev": true, + "dependencies": { + "@types/chai": "^4.2.12" + } + }, + "node_modules/@github/browserslist-config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@github/browserslist-config/-/browserslist-config-1.0.0.tgz", + "integrity": "sha512-gIhjdJp/c2beaIWWIlsXdqXVRUz3r2BxBCpfz/F3JXHvSAQ1paMYjLH+maEATtENg+k5eLV7gA+9yPp762ieuw==", + "dev": true + }, + "node_modules/@github/catalyst": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.6.0.tgz", + "integrity": "sha512-u8A+DameixqpeyHzvnJWTGj+wfiskQOYHzSiJscCWVfMkIT3rxnbHMtGh3lMthaRY21nbUOK71WcsCnCrXhBJQ==", + "dev": true + }, + "node_modules/@github/prettier-config": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@github/prettier-config/-/prettier-config-0.0.6.tgz", + "integrity": "sha512-Sdb089z+QbGnFF2NivbDeaJ62ooPlD31wE6Fkb/ESjAOXSjNJo+gjqzYYhlM7G3ERJmKFZRUJYMlsqB7Tym8lQ==", + "dev": true + }, + "node_modules/@hapi/bourne": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz", + "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==", + "dev": true + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", + "dev": true + }, + "node_modules/@lit/reactive-element": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", + "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", + "dev": true, + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, + "node_modules/@mdn/browser-compat-data": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.2.1.tgz", + "integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@open-wc/dedupe-mixin": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.4.0.tgz", + "integrity": "sha512-Sj7gKl1TLcDbF7B6KUhtvr+1UCxdhMbNY5KxdU5IfMFWqL8oy1ZeAcCANjoB1TL0AJTcPmcCFsCbHf8X2jGDUA==", + "dev": true + }, + "node_modules/@open-wc/scoped-elements": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-2.2.4.tgz", + "integrity": "sha512-12X4F4QGPWcvPbxAiJ4v8wQFCOu+laZHRGfTrkoj+3JzACCtuxHG49YbuqVzQ135QPKCuhP9wA0kpGGEfUegyg==", + "dev": true, + "dependencies": { + "@lit/reactive-element": "^1.0.0 || ^2.0.0", + "@open-wc/dedupe-mixin": "^1.4.0" + } + }, + "node_modules/@open-wc/semantic-dom-diff": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@open-wc/semantic-dom-diff/-/semantic-dom-diff-0.20.1.tgz", + "integrity": "sha512-mPF/RPT2TU7Dw41LEDdaeP6eyTOWBD4z0+AHP4/d0SbgcfJZVRymlIB6DQmtz0fd2CImIS9kszaMmwMt92HBPA==", + "dev": true, + "dependencies": { + "@types/chai": "^4.3.1", + "@web/test-runner-commands": "^0.9.0" + } + }, + "node_modules/@open-wc/testing": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@open-wc/testing/-/testing-3.2.2.tgz", + "integrity": "sha512-byN4dJTd6ZyI9mWmI4lVj30uiu+rYvQr93g64Pd7UFBdAUgb02DHLj6fkJ1gjxA6LC/MeFd7K7mOZ4+vKrMptw==", + "dev": true, + "dependencies": { + "@esm-bundle/chai": "^4.3.4-fix.0", + "@open-wc/semantic-dom-diff": "^0.20.0", + "@open-wc/testing-helpers": "^2.3.1", + "@types/chai-dom": "^1.11.0", + "@types/sinon-chai": "^3.2.3", + "chai-a11y-axe": "^1.5.0" + } + }, + "node_modules/@open-wc/testing-helpers": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@open-wc/testing-helpers/-/testing-helpers-2.3.2.tgz", + "integrity": "sha512-uZMGC/C1m5EiwQsff6KMmCW25TYMQlJt4ilAWIjnelWGFg9HPUiLnlFvAas3ESUP+4OXLO8Oft7p4mHvbYvAEQ==", + "dev": true, + "dependencies": { + "@open-wc/scoped-elements": "^2.2.4", + "lit": "^2.0.0 || ^3.0.0", + "lit-html": "^2.0.0 || ^3.0.0" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-0.5.0.tgz", + "integrity": "sha512-Uw6oB7VvmPRLE4iKsjuOh8zgDabhNX67dzo8U/BB0f9527qx+4eeUs+korU98OhG5C4ubg7ufBgVi63XYwS6TQ==", + "dev": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=14.1.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@puppeteer/browsers/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@puppeteer/browsers/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@puppeteer/browsers/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@puppeteer/browsers/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@puppeteer/browsers/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@puppeteer/browsers/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/@puppeteer/browsers/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@puppeteer/browsers/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@puppeteer/browsers/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@puppeteer/browsers/node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@puppeteer/browsers/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/babel__code-frame": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/babel__code-frame/-/babel__code-frame-7.0.6.tgz", + "integrity": "sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/chai": { + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz", + "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==", + "dev": true + }, + "node_modules/@types/chai-dom": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@types/chai-dom/-/chai-dom-1.11.3.tgz", + "integrity": "sha512-EUEZI7uID4ewzxnU7DJXtyvykhQuwe+etJ1wwOiJyQRTH/ifMWKX+ghiXkxCUvNJ6IQDodf0JXhuP6zZcy2qXQ==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/co-body": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@types/co-body/-/co-body-6.1.3.tgz", + "integrity": "sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*" + } + }, + "node_modules/@types/command-line-args": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", + "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", + "dev": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/content-disposition": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz", + "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==", + "dev": true + }, + "node_modules/@types/convert-source-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-2.0.3.tgz", + "integrity": "sha512-ag0BfJLZf6CQz8VIuRIEYQ5Ggwk/82uvTQf27RcpyDNbY0Vw49LIPqAxk5tqYfrCs9xDaIMvl4aj7ZopnYL8bA==", + "dev": true + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "node_modules/@types/cookies": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz", + "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debounce": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.4.tgz", + "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-assert": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz", + "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==", + "dev": true + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/keygrip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz", + "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/koa": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz", + "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==", + "dev": true, + "dependencies": { + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "node_modules/@types/koa-compose": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz", + "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==", + "dev": true, + "dependencies": { + "@types/koa": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sinon": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinon-chai": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.12.tgz", + "integrity": "sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@web/browser-logs": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.3.4.tgz", + "integrity": "sha512-0UkoUj1DdQjxaVBArHZRAGoiE5584/dSQ0V3hYWRqVDxaE3CwkfQ7kwb6i3Z1xJ8HZ9nuLMNycu3vLQwfhDnpg==", + "dev": true, + "dependencies": { + "errorstacks": "^2.2.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/config-loader": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz", + "integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==", + "dev": true, + "dependencies": { + "semver": "^7.3.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@web/dev-server": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.2.5.tgz", + "integrity": "sha512-IQWzjnK9H861X5BN+R9uQk2L7knogegHQcKyGsSfjyFC3fDdLit5WG2vUVpxFAYfhS4zjJWGajXGbTMhF8clkQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/command-line-args": "^5.0.0", + "@web/config-loader": "^0.2.1", + "@web/dev-server-core": "^0.5.1", + "@web/dev-server-rollup": "^0.5.1", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "debounce": "^1.2.0", + "deepmerge": "^4.2.2", + "ip": "^1.1.5", + "nanocolors": "^0.2.1", + "open": "^8.0.2", + "portfinder": "^1.0.32" + }, + "bin": { + "wds": "dist/bin.js", + "web-dev-server": "dist/bin.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/dev-server-core": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.6.3.tgz", + "integrity": "sha512-BWlgxIXQbg3RqUdz9Cfeh3XqFv0KcjQi4DLaZy9s63IlXgNZTzesTfDzliP/mIdWd5r8KZYh/P3n6LMi7CLPjQ==", + "dev": true, + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.0.2", + "chokidar": "^3.4.3", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.4.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/dev-server-core/node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/@web/dev-server-esbuild": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-0.4.4.tgz", + "integrity": "sha512-gxXvj1mw0/b8HP2ARaXgQEmWH/nyPWvRuzSyEvybMm9oThe//z6K0ksj2qyffT/X7yblhEReKqWK7djCaB0M0Q==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^4.0.0", + "@web/dev-server-core": "^0.6.2", + "esbuild": "^0.16 || ^0.17", + "parse5": "^6.0.1", + "ua-parser-js": "^1.0.33" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/dev-server-rollup": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.5.4.tgz", + "integrity": "sha512-lIN+lwj84Oh8Whe4vHijjMVe7NLJUzLxiiUsOleUtrBp1b7Us9QyUNCJK/iYitHJJDhCw6JcLJbCJ5H+vW969Q==", + "dev": true, + "dependencies": { + "@rollup/plugin-node-resolve": "^15.0.1", + "@web/dev-server-core": "^0.6.2", + "nanocolors": "^0.2.1", + "parse5": "^6.0.1", + "rollup": "^3.15.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@web/dev-server-rollup/node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@web/dev-server/node_modules/@web/config-loader": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.2.2.tgz", + "integrity": "sha512-HhoXMGivHbQ880MKQ1JChYCjWsMS4MUNOF35ktLV/0pZiX+J7oobybsPuyhS+gTnZsU7Duqnk3+HQYB7cNS4fA==", + "dev": true, + "dependencies": { + "semver": "^7.3.4" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/dev-server/node_modules/@web/dev-server-core": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.5.2.tgz", + "integrity": "sha512-7YjWmwzM+K5fPvBCXldUIMTK4EnEufi1aWQWinQE81oW1CqzEwmyUNCtnWV9fcPA4kJC4qrpcjWNGF4YDWxuSg==", + "dev": true, + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.0.0", + "chokidar": "^3.4.3", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.4.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/dev-server/node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/@web/parse5-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", + "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", + "dev": true, + "dependencies": { + "@types/parse5": "^6.0.1", + "parse5": "^6.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.16.1.tgz", + "integrity": "sha512-vXq9l31tddF/LfIqoycjyJBdmxAnYBaxfjAbuTvN603y8Rtnf6RzRtpJ18WWmVfTmNoVL4C40V4MZNcp4VIZkQ==", + "dev": true, + "dependencies": { + "@web/browser-logs": "^0.3.1", + "@web/config-loader": "^0.2.1", + "@web/dev-server": "^0.2.1", + "@web/test-runner-chrome": "^0.13.0", + "@web/test-runner-commands": "^0.7.0", + "@web/test-runner-core": "^0.11.1", + "@web/test-runner-mocha": "^0.8.1", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "convert-source-map": "^2.0.0", + "diff": "^5.0.0", + "globby": "^11.0.1", + "nanocolors": "^0.2.1", + "portfinder": "^1.0.32", + "source-map": "^0.7.3" + }, + "bin": { + "web-test-runner": "dist/bin.js", + "wtr": "dist/bin.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-chrome": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.13.4.tgz", + "integrity": "sha512-lbXsRvznlxJCnqGXQJ1Da8p+dcISgiHRNNvc2XuWqa2K+vPRZxkNcq+sP1vf2acGE1AHYUcaYxxlrFyNuJJd2Q==", + "dev": true, + "dependencies": { + "@web/test-runner-core": "^0.11.2", + "@web/test-runner-coverage-v8": "^0.7.0", + "async-mutex": "0.4.0", + "chrome-launcher": "^0.15.0", + "puppeteer-core": "^19.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-commands": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz", + "integrity": "sha512-zeLI6QdH0jzzJMDV5O42Pd8WLJtYqovgdt0JdytgHc0d1EpzXDsc7NTCJSImboc2NcayIsWAvvGGeRF69SMMYg==", + "dev": true, + "dependencies": { + "@web/test-runner-core": "^0.13.0", + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-commands/node_modules/@web/browser-logs": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", + "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", + "dev": true, + "dependencies": { + "errorstacks": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-commands/node_modules/@web/dev-server-core": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.2.tgz", + "integrity": "sha512-Q/0jpF13Ipk+qGGQ+Yx/FW1TQBYazpkfgYHHo96HBE7qv4V4KKHqHglZcSUxti/zd4bToxX1cFTz8dmbTlb8JA==", + "dev": true, + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^3.4.3", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.4.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-commands/node_modules/@web/test-runner-core": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.3.tgz", + "integrity": "sha512-ilDqF/v2sj0sD69FNSIDT7uw4M1yTVedLBt32/lXy3MMi6suCM7m/ZlhsBy8PXhf879WMvzBOl/vhJBpEMB9vA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.4.0", + "@web/dev-server-core": "^0.7.2", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "internal-ip": "^6.2.0", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-commands/node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/@web/test-runner-core": { + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.11.6.tgz", + "integrity": "sha512-hbLg15seMnpDD32NmEzy/T18EKiH4tnuqaspqq7dEKY9svvVhPiFj/Q0JN79SvE6oE4M0vAxzCTRlBl4/huiTw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.3.4", + "@web/dev-server-core": "^0.6.2", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "ip": "^1.1.5", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-coverage-v8": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.7.3.tgz", + "integrity": "sha512-hFlMFLEonDTS+TqKAE5RUJPq1HdsT0YqZD4z0x2y/E65UfYNB6ZJpV567KDCG+9ph1xynkKyqsiIhK1ufktVJA==", + "dev": true, + "dependencies": { + "@web/test-runner-core": "^0.12.0", + "istanbul-lib-coverage": "^3.0.0", + "lru-cache": "^8.0.4", + "picomatch": "^2.2.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-coverage-v8/node_modules/@web/test-runner-core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.12.0.tgz", + "integrity": "sha512-p318c1HzszyjqF0bl7oAsw6s8Xpd/xBIbMW7w5ktZwzm+r1KuNYh4RRuvkg1iMFkqu/6F8UeMR4+TJ0EYyJegw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.3.4", + "@web/dev-server-core": "^0.6.2", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "ip": "^1.1.5", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-mocha": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.8.2.tgz", + "integrity": "sha512-AS/Zc8dQo/8gGxizVLihxqOeJ5NM10jyv0L+ZIa9S7UDJuN1ge4xi2tbvCnSEcyX54gb6OG0bR+Ogy+Dzhvq7Q==", + "dev": true, + "dependencies": { + "@web/test-runner-core": "^0.12.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-mocha/node_modules/@web/test-runner-core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.12.0.tgz", + "integrity": "sha512-p318c1HzszyjqF0bl7oAsw6s8Xpd/xBIbMW7w5ktZwzm+r1KuNYh4RRuvkg1iMFkqu/6F8UeMR4+TJ0EYyJegw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.3.4", + "@web/dev-server-core": "^0.6.2", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "ip": "^1.1.5", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-playwright": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.10.3.tgz", + "integrity": "sha512-MWFrp6kD7ORslrdVG8DYNeHVBwhJAQkmyFgjAxGleIwlZHnM1zIJJDkvn73KUo3jNlMhdqiqGFCodKiDlbCfCg==", + "dev": true, + "dependencies": { + "@web/test-runner-core": "^0.12.0", + "@web/test-runner-coverage-v8": "^0.7.3", + "playwright": "^1.22.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner-playwright/node_modules/@web/test-runner-core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.12.0.tgz", + "integrity": "sha512-p318c1HzszyjqF0bl7oAsw6s8Xpd/xBIbMW7w5ktZwzm+r1KuNYh4RRuvkg1iMFkqu/6F8UeMR4+TJ0EYyJegw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.3.4", + "@web/dev-server-core": "^0.6.2", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "ip": "^1.1.5", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner/node_modules/@web/config-loader": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.2.2.tgz", + "integrity": "sha512-HhoXMGivHbQ880MKQ1JChYCjWsMS4MUNOF35ktLV/0pZiX+J7oobybsPuyhS+gTnZsU7Duqnk3+HQYB7cNS4fA==", + "dev": true, + "dependencies": { + "semver": "^7.3.4" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@web/test-runner/node_modules/@web/test-runner-commands": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.7.0.tgz", + "integrity": "sha512-3aXeGrkynOdJ5jgZu5ZslcWmWuPVY9/HNdWDUqPyNePG08PKmLV9Ij342ODDL6OVsxF5dvYn1312PhDqu5AQNw==", + "dev": true, + "dependencies": { + "@web/test-runner-core": "^0.11.0", + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", + "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "dependencies": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001662", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001662.tgz", + "integrity": "sha512-sgMUVwLmGseH8ZIrm1d51UbrhqMCH3jvS7gF/M6byuHOnKyLOBL7W8yz5V02OHwgLGA36o/AFhWzzh4uc5aqTA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-a11y-axe": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/chai-a11y-axe/-/chai-a11y-axe-1.5.0.tgz", + "integrity": "sha512-V/Vg/zJDr9aIkaHJ2KQu7lGTQQm5ZOH4u1k5iTMvIXuSVlSuUo0jcSpSqf9wUn9zl6oQXa4e4E0cqH18KOgKlQ==", + "dev": true, + "dependencies": { + "axe-core": "^4.3.3" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk-template/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/chalk-template/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk-template/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/chrome-launcher/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chromium": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/chromium/-/chromium-3.0.3.tgz", + "integrity": "sha512-TfbzP/3t38Us5xrbb9x87M/y5I/j3jx0zeJhhQ72gjp6dwJuhVP6hBZnBH4wEg7512VVXk9zCfTuPFOdw7bQqg==", + "dev": true, + "hasInstallScript": true, + "os": [ + "darwin", + "linux", + "win32" + ], + "dependencies": { + "cachedir": "^2.3.0", + "debug": "^4.1.0", + "extract-zip": "^1.7.0", + "got": "^11.5.1", + "progress": "^2.0.3", + "rimraf": "^2.7.1", + "tmp": "0.0.33", + "tunnel": "^0.0.6" + } + }, + "node_modules/chromium-bidi": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.7.tgz", + "integrity": "sha512-6+mJuFXwTMU6I3vYLs6IL8A1DyQTPjCfIL971X0aMPVGRbGnNfl6i6Cl0NMbxi2bRYLGESt9T2ZIMRM5PAEcIQ==", + "dev": true, + "dependencies": { + "mitt": "3.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/co-body": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.2.0.tgz", + "integrity": "sha512-Kbpv2Yd1NdL1V/V4cwLVxraHDV6K8ayohr2rmH0J87Er8+zJjcTa6dAn9QMPC9CRgU8+aNajKbSf1TzDB1yKPA==", + "dev": true, + "dependencies": { + "@hapi/bourne": "^3.0.0", + "inflation": "^2.0.0", + "qs": "^6.5.2", + "raw-body": "^2.3.3", + "type-is": "^1.6.16" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/command-line-args": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.2.tgz", + "integrity": "sha512-fytTsbndLbl+pPWtS0CxLV3BEWw9wJayB8NnU2cbQqVPsNdYezQeT+uIQv009m+GShnMNyuoBrRo8DTmuTfSCA==", + "dev": true, + "dependencies": { + "array-back": "^6.1.2", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", + "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", + "dev": true, + "dependencies": { + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^4.1.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.2.0.tgz", + "integrity": "sha512-W1+HdVRUl8fS3MZ9ogD51GOb46xMmhAZzR0WPw5jcgIZQJVvkddYzAl4YTU6g5w33Y1iRQLdIi2/1jhi2RNL0g==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/comment-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "dev": true, + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/custom-elements-manifest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz", + "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A==", + "dev": true + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1107588", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz", + "integrity": "sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==", + "dev": true + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.25", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.25.tgz", + "integrity": "sha512-kMb204zvK3PsSlgvvwzI3wBIcAw15tRkYk+NQdsjdDtcQWTp2RABbMQ9rUBy8KNEOM+/E6ep+XC3AykiWZld4g==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "dev": true, + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/ent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", + "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/errorstacks": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/errorstacks/-/errorstacks-2.4.1.tgz", + "integrity": "sha512-jE4i0SMYevwu/xxAuzhly/KTwtj0xDhbzB6m1xPImxTkw8wcCbgarOQPfCVMi5JKVyW7in29pNJCCJrry3Ynnw==", + "dev": true + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz", + "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-custom-elements": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-custom-elements/-/eslint-plugin-custom-elements-0.0.8.tgz", + "integrity": "sha512-726XMAabRLKKm6/yjvYfvY4MKBwX9C4x8yPjj/ap470KhSIBHm+xHbm3P7cKlsFz/4cxq6YrBeSwKmwlacF1jg==", + "dev": true, + "peerDependencies": { + "eslint": ">=4.19.0" + } + }, + "node_modules/eslint-plugin-escompat": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-escompat/-/eslint-plugin-escompat-3.11.1.tgz", + "integrity": "sha512-j/H70uveM+G9M0onQJOYM+h5trTjQfmBnhGzxAxwGrqARfgXwkfjs+SkvJ1j/a4ofyCIYpBQsGg7q+TowwPNmA==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.1" + }, + "peerDependencies": { + "eslint": ">=5.14.1" + } + }, + "node_modules/eslint-plugin-eslint-comments": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", + "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "ignore": "^5.0.5" + }, + "engines": { + "node": ">=6.5.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-filenames": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz", + "integrity": "sha512-tqxJTiEM5a0JmRCUYQmxw23vtTxrb2+a3Q2mMOPhFxvt7ZQQJmdiuMby9B/vUAuVMghyP7oET+nIf6EO6CBd/w==", + "dev": true, + "dependencies": { + "lodash.camelcase": "4.3.0", + "lodash.kebabcase": "4.1.1", + "lodash.snakecase": "4.1.1", + "lodash.upperfirst": "4.3.1" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/eslint-plugin-github": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-4.10.2.tgz", + "integrity": "sha512-F1F5aAFgi1Y5hYoTFzGQACBkw5W1hu2Fu5FSTrMlXqrojJnKl1S2pWO/rprlowRQpt+hzHhqSpsfnodJEVd5QA==", + "dev": true, + "dependencies": { + "@github/browserslist-config": "^1.0.0", + "@typescript-eslint/eslint-plugin": "^7.0.1", + "@typescript-eslint/parser": "^7.0.1", + "aria-query": "^5.3.0", + "eslint-config-prettier": ">=8.0.0", + "eslint-plugin-escompat": "^3.3.3", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-filenames": "^1.3.2", + "eslint-plugin-i18n-text": "^1.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-no-only-tests": "^3.0.0", + "eslint-plugin-prettier": "^5.0.0", + "eslint-rule-documentation": ">=1.0.0", + "jsx-ast-utils": "^3.3.2", + "prettier": "^3.0.0", + "svg-element-attributes": "^1.3.1" + }, + "bin": { + "eslint-ignore-errors": "bin/eslint-ignore-errors.js" + }, + "peerDependencies": { + "eslint": "^8.0.1" + } + }, + "node_modules/eslint-plugin-i18n-text": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz", + "integrity": "sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA==", + "dev": true, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", + "dev": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", + "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", + "dev": true, + "dependencies": { + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/eslint-plugin-no-only-tests": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz", + "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==", + "dev": true, + "engines": { + "node": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-rule-documentation": { + "version": "1.0.23", + "resolved": "https://registry.npmjs.org/eslint-rule-documentation/-/eslint-rule-documentation-1.0.23.tgz", + "integrity": "sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + } + }, + "node_modules/extract-zip/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/extract-zip/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/extract-zip/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-replace/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "dev": true, + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-assert/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflation": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz", + "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-ip": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", + "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", + "dev": true, + "dependencies": { + "default-gateway": "^6.0.0", + "ipaddr.js": "^1.9.1", + "is-ip": "^3.1.0", + "p-event": "^4.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/internal-ip?sponsor=1" + } + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", + "dev": true + }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "dev": true, + "dependencies": { + "ip-regex": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", + "dev": true, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chai": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", + "integrity": "sha512-mqKCkHwzPMhgTYca10S90aCEX9+HjVjjrBFAsw36Zj7BlQNbokXXCAe6Ji04VUMsxcY5RLP7YphpfO06XOubdg==", + "dev": true, + "peerDependencies": { + "chai": "*", + "karma": ">=0.10.9" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-chrome-launcher/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/karma-mocha": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", + "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.3" + } + }, + "node_modules/karma-mocha-reporter": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", + "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", + "dev": true, + "dependencies": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "peerDependencies": { + "karma": ">=0.13" + } + }, + "node_modules/karma-mocha-reporter/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/karma-mocha-reporter/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/karma/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/karma/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/karma/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/ua-parser-js": { + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-IZ6acm6RhQHNibSt7+c09hhvsKy9WUr4DVbeq9U8o71qxyYtJpQeDxQnMrVqnIFMLcQjHO0I9wgfO2vIahht4w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dev": true, + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/koa": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", + "dev": true, + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true + }, + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/koa-etag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-4.0.0.tgz", + "integrity": "sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg==", + "dev": true, + "dependencies": { + "etag": "^1.8.1" + } + }, + "node_modules/koa-send": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz", + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "resolve-path": "^1.4.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/koa-send/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-send/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-static": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/koa-static/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/koa/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/lit": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.0.tgz", + "integrity": "sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==", + "dev": true, + "dependencies": { + "@lit/reactive-element": "^2.0.4", + "lit-element": "^4.1.0", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-element": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.0.tgz", + "integrity": "sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==", + "dev": true, + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit/reactive-element": "^2.0.4", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-html": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.0.tgz", + "integrity": "sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA==", + "dev": true, + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "dev": true, + "engines": { + "node": ">=16.14" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marky": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", + "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mocha": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/mocha/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/mocha/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nanocolors": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz", + "integrity": "sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", + "dev": true + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/playwright": { + "version": "1.47.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.1.tgz", + "integrity": "sha512-SUEKi6947IqYbKxRiqnbUobVZY4bF1uu+ZnZNJX9DfU1tlf2UhWfvVjLf01pQx9URsOr18bFVUKXmanYWhbfkw==", + "dev": true, + "dependencies": { + "playwright-core": "1.47.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.47.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.1.tgz", + "integrity": "sha512-i1iyJdLftqtt51mEk6AhYFaAJCDx0xQ/O5NU8EKaWFgMjItPVma542Nh/Aq8aLCjIJSzjaiEQGW/nyqLkGF1OQ==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/portfinder/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/puppeteer-core": { + "version": "19.11.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.11.1.tgz", + "integrity": "sha512-qcuC2Uf0Fwdj9wNtaTZ2OvYRraXpAK+puwwVW8ofOhOgLPZyz1c68tsorfIZyCUOpyBisjr+xByu7BMbEYMepA==", + "dev": true, + "dependencies": { + "@puppeteer/browsers": "0.5.0", + "chromium-bidi": "0.4.7", + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.1107588", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.13.0" + }, + "engines": { + "node": ">=14.14.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/puppeteer-core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/puppeteer-core/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/puppeteer-core/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/puppeteer-core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/puppeteer-core/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==", + "dev": true, + "dependencies": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-path/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/resolve-path/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", + "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/node": "*", + "acorn": "^7.1.0" + }, + "bin": { + "rollup": "dist/bin/rollup" + } + }, + "node_modules/rollup/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/socket.io": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string.prototype.includes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", + "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-element-attributes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/svg-element-attributes/-/svg-element-attributes-1.3.1.tgz", + "integrity": "sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/synckit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/table-layout": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", + "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", + "dev": true, + "dependencies": { + "array-back": "^6.2.2", + "wordwrapjs": "^5.1.0" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/tr46/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true + }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "engines": { + "node": ">=0.6.x" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz", + "integrity": "sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrapjs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", + "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +}