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" + } + } + } +}